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.view.Gravity; 33 import android.view.inputmethod.InputMethodManager; 34 import android.widget.EditText; 35 import android.widget.LinearLayout; 36 import android.widget.TextView; 37 38 import androidx.annotation.Nullable; 39 40 /** 41 * A test {@link Activity} that automatically shows the input method. 42 */ 43 public final class MainActivity extends Activity { 44 45 private static final String EXTRA_KEY_PRIVATE_IME_OPTIONS = 46 "android.view.inputmethod.ctstestapp.EXTRA_KEY_PRIVATE_IME_OPTIONS"; 47 private static final String EXTRA_KEY_SHOW_DIALOG = 48 "android.view.inputmethod.ctstestapp.EXTRA_KEY_SHOW_DIALOG"; 49 50 private static final String EXTRA_DISMISS_DIALOG = "extra_dismiss_dialog"; 51 private static final String EXTRA_SHOW_SOFT_INPUT = "extra_show_soft_input"; 52 private static final String EXTRA_HANDWRITING_DELEGATOR = "extra_handwriting_delegator"; 53 54 private static final String ACTION_TRIGGER = "broadcast_action_trigger"; 55 private AlertDialog mDialog; 56 private EditText mEditor; 57 private final Handler mHandler = new Handler(Looper.myLooper()); 58 59 private BroadcastReceiver mBroadcastReceiver; 60 61 @Nullable getStringIntentExtra(String key)62 private String getStringIntentExtra(String key) { 63 if (getPackageManager().isInstantApp()) { 64 final Uri uri = getIntent().getData(); 65 if (uri == null || !uri.isHierarchical()) { 66 return null; 67 } 68 return uri.getQueryParameter(key); 69 } 70 return getIntent().getStringExtra(key); 71 } 72 getBooleanIntentExtra(String key)73 private boolean getBooleanIntentExtra(String key) { 74 if (getPackageManager().isInstantApp()) { 75 final Uri uri = getIntent().getData(); 76 if (uri == null || !uri.isHierarchical()) { 77 return false; 78 } 79 return uri.getBooleanQueryParameter(key, false); 80 } 81 return getIntent().getBooleanExtra(key, false) 82 || "true".equals(getIntent().getStringExtra(key)); 83 } 84 85 @Override onCreate(Bundle savedInstanceState)86 protected void onCreate(Bundle savedInstanceState) { 87 super.onCreate(savedInstanceState); 88 89 final LinearLayout layout = new LinearLayout(this); 90 layout.setOrientation(LinearLayout.VERTICAL); 91 final boolean needShowDialog = getBooleanIntentExtra(EXTRA_KEY_SHOW_DIALOG); 92 93 if (needShowDialog) { 94 layout.setOrientation(LinearLayout.VERTICAL); 95 layout.setGravity(Gravity.BOTTOM); 96 getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_RESIZE); 97 98 final TextView textView = new TextView(this); 99 textView.setText("This is DialogActivity"); 100 layout.addView(textView); 101 102 mDialog = new AlertDialog.Builder(this) 103 .setView(new LinearLayout(this)) 104 .create(); 105 mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); 106 mDialog.getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_PAN); 107 mDialog.show(); 108 } else { 109 mEditor = new EditText(this); 110 mEditor.setHint("editText"); 111 final String privateImeOptions = getStringIntentExtra(EXTRA_KEY_PRIVATE_IME_OPTIONS); 112 if (privateImeOptions != null) { 113 mEditor.setPrivateImeOptions(privateImeOptions); 114 } 115 boolean isHandwritingDelegator = getBooleanIntentExtra(EXTRA_HANDWRITING_DELEGATOR); 116 if (isHandwritingDelegator) { 117 mEditor.setIsHandwritingDelegate(true); 118 mEditor.setAllowedHandwritingDelegatorPackage("android.view.inputmethod.cts"); 119 } 120 mEditor.requestFocus(); 121 layout.addView(mEditor); 122 } 123 124 setContentView(layout); 125 } 126 127 @Override onStart()128 protected void onStart() { 129 super.onStart(); 130 mBroadcastReceiver = new BroadcastReceiver() { 131 @Override 132 public void onReceive(Context context, Intent intent) { 133 final Bundle extras = intent.getExtras(); 134 if (extras == null) { 135 return; 136 } 137 138 if (extras.containsKey(EXTRA_SHOW_SOFT_INPUT)) { 139 getSystemService(InputMethodManager.class).showSoftInput(mEditor, 0); 140 } 141 142 if (extras.getBoolean(EXTRA_DISMISS_DIALOG, false)) { 143 if (mDialog != null) { 144 mDialog.dismiss(); 145 mDialog = null; 146 } 147 mHandler.postDelayed(() -> finish(), 100); 148 } 149 } 150 }; 151 registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_TRIGGER), 152 Context.RECEIVER_EXPORTED); 153 } 154 155 @Override onStop()156 protected void onStop() { 157 super.onStop(); 158 if (mBroadcastReceiver != null) { 159 unregisterReceiver(mBroadcastReceiver); 160 mBroadcastReceiver = null; 161 } 162 } 163 } 164