1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.cts.mockime;
18 
19 import android.graphics.Point;
20 import android.graphics.Rect;
21 import android.os.Bundle;
22 import android.view.Display;
23 import android.view.View;
24 
25 import androidx.annotation.NonNull;
26 import androidx.annotation.Nullable;
27 
28 /**
29  * A collection of layout-related information when
30  * {@link View.OnLayoutChangeListener#onLayoutChange(View, int, int, int, int, int, int, int, int)}
31  * is called back for the input view (the view returned from {@link MockIme#onCreateInputView()}).
32  */
33 public final class ImeLayoutInfo {
34 
35     private static final String NEW_LAYOUT_KEY = "newLayout";
36     private static final String OLD_LAYOUT_KEY = "oldLayout";
37     private static final String VIEW_ORIGIN_ON_SCREEN_KEY = "viewOriginOnScreen";
38     private static final String DISPLAY_SIZE_KEY = "displaySize";
39 
40     @NonNull
41     private final Rect mNewLayout;
42     @NonNull
43     private final Rect mOldLayout;
44     @Nullable
45     private Point mViewOriginOnScreen;
46     @Nullable
47     private Point mDisplaySize;
48 
49     /**
50      * Returns the bounding box of the {@link View} passed to
51      * {@link android.inputmethodservice.InputMethodService#onCreateInputView()} in screen
52      * coordinates.
53      *
54      * <p>Currently this method assumes that no {@link View} in the hierarchy uses
55      * transformations such as {@link View#setRotation(float)}.</p>
56      *
57      * @return Region in screen coordinates.
58      */
59     @Nullable
getInputViewBoundsInScreen()60     public Rect getInputViewBoundsInScreen() {
61         return new Rect(
62                 mViewOriginOnScreen.x, mViewOriginOnScreen.y,
63                 mViewOriginOnScreen.x + mNewLayout.width(),
64                 mViewOriginOnScreen.y + mNewLayout.height());
65     }
66 
ImeLayoutInfo(@onNull Rect newLayout, @NonNull Rect oldLayout, @NonNull Point viewOriginOnScreen, @Nullable Point displaySize)67     ImeLayoutInfo(@NonNull Rect newLayout, @NonNull Rect oldLayout,
68             @NonNull Point viewOriginOnScreen, @Nullable Point displaySize) {
69         mNewLayout = new Rect(newLayout);
70         mOldLayout = new Rect(oldLayout);
71         mViewOriginOnScreen = new Point(viewOriginOnScreen);
72         mDisplaySize = new Point(displaySize);
73     }
74 
writeToBundle(@onNull Bundle bundle)75     void writeToBundle(@NonNull Bundle bundle) {
76         bundle.putParcelable(NEW_LAYOUT_KEY, mNewLayout);
77         bundle.putParcelable(OLD_LAYOUT_KEY, mOldLayout);
78         bundle.putParcelable(VIEW_ORIGIN_ON_SCREEN_KEY, mViewOriginOnScreen);
79         bundle.putParcelable(DISPLAY_SIZE_KEY, mDisplaySize);
80     }
81 
readFromBundle(@onNull Bundle bundle)82     static ImeLayoutInfo readFromBundle(@NonNull Bundle bundle) {
83         final Rect newLayout = bundle.getParcelable(NEW_LAYOUT_KEY);
84         final Rect oldLayout = bundle.getParcelable(OLD_LAYOUT_KEY);
85         final Point viewOrigin = bundle.getParcelable(VIEW_ORIGIN_ON_SCREEN_KEY);
86         final Point displaySize = bundle.getParcelable(DISPLAY_SIZE_KEY);
87 
88         return new ImeLayoutInfo(newLayout, oldLayout, viewOrigin, displaySize);
89     }
90 
fromLayoutListenerCallback(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)91     static ImeLayoutInfo fromLayoutListenerCallback(View v, int left, int top, int right,
92             int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
93         final Rect newLayout = new Rect(left, top, right, bottom);
94         final Rect oldLayout = new Rect(oldLeft, oldTop, oldRight, oldBottom);
95         final int[] viewOriginArray = new int[2];
96         v.getLocationOnScreen(viewOriginArray);
97         final Point viewOrigin = new Point(viewOriginArray[0], viewOriginArray[1]);
98         final Display display = v.getDisplay();
99         final Point displaySize;
100         if (display != null) {
101             displaySize = new Point();
102             display.getRealSize(displaySize);
103         } else {
104             displaySize = null;
105         }
106         return new ImeLayoutInfo(newLayout, oldLayout, viewOrigin, displaySize);
107     }
108 }
109