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 
53     private static final String ACTION_TRIGGER = "broadcast_action_trigger";
54     private AlertDialog mDialog;
55     private EditText mEditor;
56     private final Handler mHandler = new Handler(Looper.myLooper());
57 
58     private BroadcastReceiver mBroadcastReceiver;
59 
60     @Nullable
getStringIntentExtra(String key)61     private String getStringIntentExtra(String key) {
62         if (getPackageManager().isInstantApp()) {
63             final Uri uri = getIntent().getData();
64             if (uri == null || !uri.isHierarchical()) {
65                 return null;
66             }
67             return uri.getQueryParameter(key);
68         }
69         return getIntent().getStringExtra(key);
70     }
71 
getBooleanIntentExtra(String key)72     private boolean getBooleanIntentExtra(String key) {
73         if (getPackageManager().isInstantApp()) {
74             final Uri uri = getIntent().getData();
75             if (uri == null || !uri.isHierarchical()) {
76                 return false;
77             }
78             return uri.getBooleanQueryParameter(key, false);
79         }
80         return getIntent().getBooleanExtra(key, false);
81     }
82 
83     @Override
onCreate(Bundle savedInstanceState)84     protected void onCreate(Bundle savedInstanceState) {
85         super.onCreate(savedInstanceState);
86 
87         final LinearLayout layout = new LinearLayout(this);
88         layout.setOrientation(LinearLayout.VERTICAL);
89         final boolean needShowDialog = getBooleanIntentExtra(EXTRA_KEY_SHOW_DIALOG);
90 
91         if (needShowDialog) {
92             layout.setOrientation(LinearLayout.VERTICAL);
93             layout.setGravity(Gravity.BOTTOM);
94             getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_RESIZE);
95 
96             final TextView textView = new TextView(this);
97             textView.setText("This is DialogActivity");
98             layout.addView(textView);
99 
100             mDialog = new AlertDialog.Builder(this)
101                     .setView(new LinearLayout(this))
102                     .create();
103             mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
104             mDialog.getWindow().setSoftInputMode(SOFT_INPUT_ADJUST_PAN);
105             mDialog.show();
106         } else {
107             mEditor = new EditText(this);
108             mEditor.setHint("editText");
109             final String privateImeOptions = getStringIntentExtra(EXTRA_KEY_PRIVATE_IME_OPTIONS);
110             if (privateImeOptions != null) {
111                 mEditor.setPrivateImeOptions(privateImeOptions);
112             }
113             mEditor.requestFocus();
114             layout.addView(mEditor);
115         }
116 
117         setContentView(layout);
118     }
119 
120     @Override
onStart()121     protected void onStart() {
122         super.onStart();
123         mBroadcastReceiver = new BroadcastReceiver() {
124             @Override
125             public void onReceive(Context context, Intent intent) {
126                 final Bundle extras = intent.getExtras();
127                 if (extras == null) {
128                     return;
129                 }
130 
131                 if (extras.containsKey(EXTRA_SHOW_SOFT_INPUT)) {
132                     getSystemService(InputMethodManager.class).showSoftInput(mEditor, 0);
133                 }
134 
135                 if (extras.getBoolean(EXTRA_DISMISS_DIALOG, false)) {
136                     if (mDialog != null) {
137                         mDialog.dismiss();
138                         mDialog = null;
139                     }
140                     mHandler.postDelayed(() -> finish(), 100);
141                 }
142             }
143         };
144         registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_TRIGGER));
145     }
146 
147     @Override
onStop()148     protected void onStop() {
149         super.onStop();
150         if (mBroadcastReceiver != null) {
151             unregisterReceiver(mBroadcastReceiver);
152             mBroadcastReceiver = null;
153         }
154     }
155 }
156