1 /* 2 * Copyright (C) 2020 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 package android.view.inputmethod.ctstestapp; 17 18 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 19 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; 20 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 21 22 import android.app.Activity; 23 import android.app.AlertDialog; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.net.Uri; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.Looper; 32 import android.os.RemoteCallback; 33 import android.view.Gravity; 34 import android.view.inputmethod.EditorInfo; 35 import android.view.inputmethod.InputConnection; 36 import android.view.inputmethod.InputMethodManager; 37 import android.view.inputmethod.cts.util.MockTestActivityUtil; 38 import android.widget.EditText; 39 import android.widget.LinearLayout; 40 import android.widget.TextView; 41 42 import androidx.annotation.Nullable; 43 44 /** 45 * A test {@link Activity} that automatically shows the input method. 46 */ 47 public final class MainActivity extends Activity { 48 49 private AlertDialog mDialog; 50 private EditText mEditor; 51 private final Handler mHandler = new Handler(Looper.myLooper()); 52 53 private BroadcastReceiver mBroadcastReceiver; 54 55 @Nullable getStringIntentExtra(String key)56 private String getStringIntentExtra(String key) { 57 if (getPackageManager().isInstantApp()) { 58 final Uri uri = getIntent().getData(); 59 if (uri == null || !uri.isHierarchical()) { 60 return null; 61 } 62 return uri.getQueryParameter(key); 63 } 64 return getIntent().getStringExtra(key); 65 } 66 getIntegerIntentExtra(String key)67 private Integer getIntegerIntentExtra(String key) { 68 String value = getIntent().getStringExtra(key); 69 if (value != null) { 70 return Integer.parseInt(value); 71 } 72 return null; 73 } 74 getBooleanIntentExtra(String key)75 private boolean getBooleanIntentExtra(String key) { 76 if (getPackageManager().isInstantApp()) { 77 final Uri uri = getIntent().getData(); 78 if (uri == null || !uri.isHierarchical()) { 79 return false; 80 } 81 return uri.getBooleanQueryParameter(key, false); 82 } 83 return getIntent().getBooleanExtra(key, false) || "true".equals( 84 getIntent().getStringExtra(key)); 85 } 86 87 @Override onCreate(Bundle savedInstanceState)88 protected void onCreate(Bundle savedInstanceState) { 89 super.onCreate(savedInstanceState); 90 final LinearLayout layout = new LinearLayout(this); 91 layout.setOrientation(LinearLayout.VERTICAL); 92 final boolean needShowDialog = 93 getBooleanIntentExtra(MockTestActivityUtil.EXTRA_KEY_SHOW_DIALOG); 94 95 if (needShowDialog) { 96 layout.setOrientation(LinearLayout.VERTICAL); 97 layout.setGravity(Gravity.BOTTOM); 98 getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_RESIZE); 99 100 final TextView textView = new TextView(this); 101 textView.setText("This is DialogActivity"); 102 layout.addView(textView); 103 104 mDialog = new AlertDialog.Builder(this).setView(new LinearLayout(this)).create(); 105 mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); 106 mDialog.getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_PAN); 107 mDialog.show(); 108 } else { 109 RemoteCallback remoteCallback = getIntent().getParcelableExtra( 110 MockTestActivityUtil.EXTRA_ON_CREATE_INPUT_CONNECTION_CALLBACK, 111 RemoteCallback.class); 112 String sessionId = getIntent().getStringExtra( 113 MockTestActivityUtil.EXTRA_ON_CREATE_USER_HANDLE_SESSION_ID); 114 if (remoteCallback == null || sessionId == null) { 115 mEditor = new EditText(this); 116 } else { 117 mEditor = new EditText(this) { 118 @Override 119 public InputConnection onCreateInputConnection(EditorInfo editorInfo) { 120 final InputConnection original = super.onCreateInputConnection(editorInfo); 121 if (editorInfo.extras == null) { 122 editorInfo.extras = new Bundle(); 123 } 124 editorInfo.extras.putString( 125 ReplyReceivingInputConnection 126 .EDITOR_INFO_KEY_REPLY_USER_HANDLE_SESSION_ID, 127 sessionId); 128 return new ReplyReceivingInputConnection(original, sessionId, 129 remoteCallback); 130 } 131 }; 132 } 133 mEditor.setHint("editText"); 134 final String privateImeOptions = 135 getStringIntentExtra(MockTestActivityUtil.EXTRA_KEY_PRIVATE_IME_OPTIONS); 136 if (privateImeOptions != null) { 137 mEditor.setPrivateImeOptions(privateImeOptions); 138 } 139 if (getBooleanIntentExtra(MockTestActivityUtil.EXTRA_HANDWRITING_DELEGATE)) { 140 mEditor.setIsHandwritingDelegate(true); 141 mEditor.setAllowedHandwritingDelegatorPackage("android.view.inputmethod.cts"); 142 } 143 if (getBooleanIntentExtra( 144 MockTestActivityUtil.EXTRA_HOME_HANDWRITING_DELEGATOR_ALLOWED)) { 145 mEditor.setHandwritingDelegateFlags( 146 InputMethodManager.HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED); 147 } 148 Integer softInputMode = getIntegerIntentExtra( 149 MockTestActivityUtil.EXTRA_SOFT_INPUT_MODE); 150 if (softInputMode != null) { 151 getWindow().setSoftInputMode(softInputMode); 152 } 153 mEditor.requestFocus(); 154 layout.addView(mEditor); 155 } 156 157 layout.setFitsSystemWindows(true); 158 setContentView(layout); 159 } 160 161 @Override onStart()162 protected void onStart() { 163 super.onStart(); 164 mBroadcastReceiver = new BroadcastReceiver() { 165 @Override 166 public void onReceive(Context context, Intent intent) { 167 final Bundle extras = intent.getExtras(); 168 if (extras == null) { 169 return; 170 } 171 172 if (extras.containsKey(MockTestActivityUtil.EXTRA_SHOW_SOFT_INPUT)) { 173 getSystemService(InputMethodManager.class).showSoftInput(mEditor, 0); 174 } 175 176 if (extras.getBoolean(MockTestActivityUtil.EXTRA_DISMISS_DIALOG, false)) { 177 if (mDialog != null) { 178 mDialog.dismiss(); 179 mDialog = null; 180 } 181 mHandler.postDelayed(() -> finish(), 100); 182 } 183 } 184 }; 185 registerReceiver(mBroadcastReceiver, new IntentFilter(MockTestActivityUtil.ACTION_TRIGGER), 186 Context.RECEIVER_EXPORTED); 187 } 188 189 @Override onStop()190 protected void onStop() { 191 super.onStop(); 192 if (mBroadcastReceiver != null) { 193 unregisterReceiver(mBroadcastReceiver); 194 mBroadcastReceiver = null; 195 } 196 } 197 } 198