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.os.Bundle;
20 import android.os.PersistableBundle;
21 
22 import androidx.annotation.ColorInt;
23 import androidx.annotation.NonNull;
24 import androidx.annotation.Nullable;
25 
26 /**
27  * An immutable data store to control the behavior of {@link MockIme}.
28  */
29 public class ImeSettings {
30 
31     @NonNull
32     private final String mClientPackageName;
33 
34     @NonNull
35     private final String mEventCallbackActionName;
36 
37     private static final String EVENT_CALLBACK_INTENT_ACTION_KEY = "eventCallbackActionName";
38     private static final String DATA_KEY = "data";
39 
40     private static final String BACKGROUND_COLOR_KEY = "BackgroundColor";
41     private static final String NAVIGATION_BAR_COLOR_KEY = "NavigationBarColor";
42     private static final String INPUT_VIEW_HEIGHT_WITHOUT_SYSTEM_WINDOW_INSET =
43             "InputViewHeightWithoutSystemWindowInset";
44     private static final String WINDOW_FLAGS = "WindowFlags";
45     private static final String WINDOW_FLAGS_MASK = "WindowFlagsMask";
46     private static final String FULLSCREEN_MODE_ALLOWED = "FullscreenModeAllowed";
47     private static final String INPUT_VIEW_SYSTEM_UI_VISIBILITY = "InputViewSystemUiVisibility";
48     private static final String HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED =
49             "HardKeyboardConfigurationBehaviorAllowed";
50 
51     @NonNull
52     private final PersistableBundle mBundle;
53 
ImeSettings(@onNull String clientPackageName, @NonNull Bundle bundle)54     ImeSettings(@NonNull String clientPackageName, @NonNull Bundle bundle) {
55         mClientPackageName = clientPackageName;
56         mEventCallbackActionName = bundle.getString(EVENT_CALLBACK_INTENT_ACTION_KEY);
57         mBundle = bundle.getParcelable(DATA_KEY);
58     }
59 
60     @Nullable
getEventCallbackActionName()61     String getEventCallbackActionName() {
62         return mEventCallbackActionName;
63     }
64 
65     @NonNull
getClientPackageName()66     String getClientPackageName() {
67         return mClientPackageName;
68     }
69 
fullscreenModeAllowed(boolean defaultValue)70     public boolean fullscreenModeAllowed(boolean defaultValue) {
71         return mBundle.getBoolean(FULLSCREEN_MODE_ALLOWED, defaultValue);
72     }
73 
74     @ColorInt
getBackgroundColor(@olorInt int defaultColor)75     public int getBackgroundColor(@ColorInt int defaultColor) {
76         return mBundle.getInt(BACKGROUND_COLOR_KEY, defaultColor);
77     }
78 
hasNavigationBarColor()79     public boolean hasNavigationBarColor() {
80         return mBundle.keySet().contains(NAVIGATION_BAR_COLOR_KEY);
81     }
82 
83     @ColorInt
getNavigationBarColor()84     public int getNavigationBarColor() {
85         return mBundle.getInt(NAVIGATION_BAR_COLOR_KEY);
86     }
87 
getInputViewHeightWithoutSystemWindowInset(int defaultHeight)88     public int getInputViewHeightWithoutSystemWindowInset(int defaultHeight) {
89         return mBundle.getInt(INPUT_VIEW_HEIGHT_WITHOUT_SYSTEM_WINDOW_INSET, defaultHeight);
90     }
91 
getWindowFlags(int defaultFlags)92     public int getWindowFlags(int defaultFlags) {
93         return mBundle.getInt(WINDOW_FLAGS, defaultFlags);
94     }
95 
getWindowFlagsMask(int defaultFlags)96     public int getWindowFlagsMask(int defaultFlags) {
97         return mBundle.getInt(WINDOW_FLAGS_MASK, defaultFlags);
98     }
99 
getInputViewSystemUiVisibility(int defaultFlags)100     public int getInputViewSystemUiVisibility(int defaultFlags) {
101         return mBundle.getInt(INPUT_VIEW_SYSTEM_UI_VISIBILITY, defaultFlags);
102     }
103 
getHardKeyboardConfigurationBehaviorAllowed(boolean defaultValue)104     public boolean getHardKeyboardConfigurationBehaviorAllowed(boolean defaultValue) {
105         return mBundle.getBoolean(HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED, defaultValue);
106     }
107 
serializeToBundle(@onNull String eventCallbackActionName, @Nullable Builder builder)108     static Bundle serializeToBundle(@NonNull String eventCallbackActionName,
109             @Nullable Builder builder) {
110         final Bundle result = new Bundle();
111         result.putString(EVENT_CALLBACK_INTENT_ACTION_KEY, eventCallbackActionName);
112         result.putParcelable(DATA_KEY, builder != null ? builder.mBundle : PersistableBundle.EMPTY);
113         return result;
114     }
115 
116     /**
117      * The builder class for {@link ImeSettings}.
118      */
119     public static final class Builder {
120         private final PersistableBundle mBundle = new PersistableBundle();
121 
122         /**
123          * Controls whether fullscreen mode is allowed or not.
124          *
125          * <p>By default, fullscreen mode is not allowed in {@link MockIme}.</p>
126          *
127          * @param allowed {@code true} if fullscreen mode is allowed
128          * @see MockIme#onEvaluateFullscreenMode()
129          */
setFullscreenModeAllowed(boolean allowed)130         public Builder setFullscreenModeAllowed(boolean allowed) {
131             mBundle.putBoolean(FULLSCREEN_MODE_ALLOWED, allowed);
132             return this;
133         }
134 
135         /**
136          * Sets the background color of the {@link MockIme}.
137          * @param color background color to be used
138          */
setBackgroundColor(@olorInt int color)139         public Builder setBackgroundColor(@ColorInt int color) {
140             mBundle.putInt(BACKGROUND_COLOR_KEY, color);
141             return this;
142         }
143 
144         /**
145          * Sets the color to be passed to {@link android.view.Window#setNavigationBarColor(int)}.
146          *
147          * @param color color to be passed to {@link android.view.Window#setNavigationBarColor(int)}
148          * @see android.view.View
149          */
setNavigationBarColor(@olorInt int color)150         public Builder setNavigationBarColor(@ColorInt int color) {
151             mBundle.putInt(NAVIGATION_BAR_COLOR_KEY, color);
152             return this;
153         }
154 
155         /**
156          * Sets the input view height measured from the bottom system window inset.
157          * @param height height of the soft input view. This does not include the system window
158          *               inset such as navigation bar
159          */
setInputViewHeightWithoutSystemWindowInset(int height)160         public Builder setInputViewHeightWithoutSystemWindowInset(int height) {
161             mBundle.putInt(INPUT_VIEW_HEIGHT_WITHOUT_SYSTEM_WINDOW_INSET, height);
162             return this;
163         }
164 
165         /**
166          * Sets window flags to be specified to {@link android.view.Window#setFlags(int, int)} of
167          * the main {@link MockIme} window.
168          *
169          * <p>When {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} is set,
170          * {@link MockIme} tries to render the navigation bar by itself.</p>
171          *
172          * @param flags flags to be specified
173          * @param flagsMask mask bits that specify what bits need to be cleared before setting
174          *                  {@code flags}
175          * @see android.view.WindowManager
176          */
setWindowFlags(int flags, int flagsMask)177         public Builder setWindowFlags(int flags, int flagsMask) {
178             mBundle.putInt(WINDOW_FLAGS, flags);
179             mBundle.putInt(WINDOW_FLAGS_MASK, flagsMask);
180             return this;
181         }
182 
183         /**
184          * Sets flags to be specified to {@link android.view.View#setSystemUiVisibility(int)} of
185          * the main soft input view (the returned view from {@link MockIme#onCreateInputView()}).
186          *
187          * @param visibilityFlags flags to be specified
188          * @see android.view.View
189          */
setInputViewSystemUiVisibility(int visibilityFlags)190         public Builder setInputViewSystemUiVisibility(int visibilityFlags) {
191             mBundle.putInt(INPUT_VIEW_SYSTEM_UI_VISIBILITY, visibilityFlags);
192             return this;
193         }
194 
195         /**
196          * Controls whether {@link MockIme} is allowed to change the behavior based on
197          * {@link android.content.res.Configuration#keyboard} and
198          * {@link android.content.res.Configuration#hardKeyboardHidden}.
199          *
200          * <p>Methods in {@link android.inputmethodservice.InputMethodService} such as
201          * {@link android.inputmethodservice.InputMethodService#onEvaluateInputViewShown()} and
202          * {@link android.inputmethodservice.InputMethodService#onShowInputRequested(int, boolean)}
203          * change their behaviors when a hardware keyboard is attached.  This is confusing when
204          * writing tests so by default {@link MockIme} tries to cancel those behaviors.  This
205          * settings re-enables such a behavior.</p>
206          *
207          * @param allowed {@code true} when {@link MockIme} is allowed to change the behavior when
208          *                a hardware keyboard is attached
209          *
210          * @see android.inputmethodservice.InputMethodService#onEvaluateInputViewShown()
211          * @see android.inputmethodservice.InputMethodService#onShowInputRequested(int, boolean)
212          */
setHardKeyboardConfigurationBehaviorAllowed(boolean allowed)213         public Builder setHardKeyboardConfigurationBehaviorAllowed(boolean allowed) {
214             mBundle.putBoolean(HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED, allowed);
215             return this;
216         }
217     }
218 }
219