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