EditTextVariations: create a IME focusable overlay for test

Bug: 228766370
Test: manual by using EditorTextVariations tool
     1) make and install EditTextVariations
     2) Enable "Settings > Display over other apps" for
        EditTextVariations
     3) Launch EditTextVariations from all apps
     4) Menu -> Show IME focuable overlay
     5) Go to home screen by gesture or pressing home key
     6) Launch any app (e.g. Chrome) and tap the editor
     7) Expect IME can show up

Change-Id: Ib4b72e0a277d8b2fb78837bed5d2e9cccd819a07
This commit is contained in:
Ming-Shin Lu 2022-04-15 01:42:35 +08:00
parent be5ec69242
commit f134ea3848
3 changed files with 64 additions and 1 deletions

View File

@ -19,6 +19,7 @@
android:versionName="0.67" android:versionName="0.67"
android:versionCode="67"> android:versionCode="67">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<supports-screens android:resizeable="true"/> <supports-screens android:resizeable="true"/>
<uses-sdk android:targetSdkVersion="27" <uses-sdk android:targetSdkVersion="27"
android:minSdkVersion="11"/> android:minSdkVersion="11"/>

View File

@ -35,6 +35,10 @@
<string name="menu_softinput_hidden" translatable="false">Keyboard Hidden</string> <string name="menu_softinput_hidden" translatable="false">Keyboard Hidden</string>
<!-- The menu title to send a notification to test direct reply. [CHAR LIMIT=20] --> <!-- The menu title to send a notification to test direct reply. [CHAR LIMIT=20] -->
<string name="menu_direct_reply">Direct Reply</string> <string name="menu_direct_reply">Direct Reply</string>
<!-- The menu title to show a application overlay with NOT_FOCUSABLE | ALT_FOCUSABLE_IM. [CHAR LIMIT=26] -->
<string name="menu_show_ime_focusable_overlay">Show IME focusable overlay</string>
<!-- The menu title to hide a application overlay with NOT_FOCUSABLE | ALT_FOCUSABLE_IM. [CHAR LIMIT=26] -->
<string name="menu_hide_ime_focusable_overlay">Hide IME focusable overlay</string>
<!-- The example of custom action key label. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] --> <!-- The example of custom action key label. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] -->
<string name="custom_action_label">Custom</string> <string name="custom_action_label">Custom</string>
</resources> </resources>

View File

@ -16,10 +16,19 @@
package com.android.inputmethod.tools.edittextvariations; package com.android.inputmethod.tools.edittextvariations;
import static android.graphics.Color.BLUE;
import static android.view.Gravity.LEFT;
import static android.view.Gravity.TOP;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -27,9 +36,11 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.InputType; import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -65,6 +76,7 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
private static final int MENU_SOFTINPUT_VISIBLE = 4; private static final int MENU_SOFTINPUT_VISIBLE = 4;
private static final int MENU_SOFTINPUT_HIDDEN = 5; private static final int MENU_SOFTINPUT_HIDDEN = 5;
private static final int MENU_DIRECT_REPLY = 6; private static final int MENU_DIRECT_REPLY = 6;
private static final int MENU_TOGGLE_IME_FOCUSABLE_OVERLAY = 7;
private static final String PREF_THEME = "theme"; private static final String PREF_THEME = "theme";
private static final String PREF_NAVIGATE = "navigate"; private static final String PREF_NAVIGATE = "navigate";
private static final String PREF_SOFTINPUT = "softinput"; private static final String PREF_SOFTINPUT = "softinput";
@ -85,6 +97,9 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
private ArrayAdapter<String> mAutoCompleteAdapter; private ArrayAdapter<String> mAutoCompleteAdapter;
private TextView mOverlayTextView;
private boolean mShowOverlay = true;
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
@Override @Override
@ -171,9 +186,12 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
if (NotificationUtils.DIRECT_REPLY_SUPPORTED) { if (NotificationUtils.DIRECT_REPLY_SUPPORTED) {
menu.add(Menu.NONE, MENU_DIRECT_REPLY, 5, R.string.menu_direct_reply); menu.add(Menu.NONE, MENU_DIRECT_REPLY, 5, R.string.menu_direct_reply);
} }
menu.add(Menu.NONE, MENU_TOGGLE_IME_FOCUSABLE_OVERLAY, 6,
mShowOverlay ? getString(R.string.menu_show_ime_focusable_overlay)
: getString(R.string.menu_hide_ime_focusable_overlay));
try { try {
final PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); final PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
menu.add(Menu.NONE, MENU_VERSION, 6, menu.add(Menu.NONE, MENU_VERSION, 7,
getString(R.string.menu_version, pinfo.versionName)) getString(R.string.menu_version, pinfo.versionName))
.setEnabled(false); .setEnabled(false);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
@ -213,6 +231,16 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
} else { } else {
NotificationUtils.sendDirectReplyNotification(this); NotificationUtils.sendDirectReplyNotification(this);
} }
} else if (itemId == MENU_TOGGLE_IME_FOCUSABLE_OVERLAY) {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(this,
"Not allowed to show overlay.\nCheck \"Settings > "
+ "Display over other apps\"", Toast.LENGTH_LONG).show();
} else {
toggleOverlayView(true /* needsIme */);
item.setTitle(mShowOverlay ? getString(R.string.menu_show_ime_focusable_overlay)
: getString(R.string.menu_hide_ime_focusable_overlay));
}
} }
return true; return true;
} }
@ -233,6 +261,14 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
} }
} }
@Override
protected void onDestroy() {
if (mOverlayTextView != null) {
getWindowManager().removeView(mOverlayTextView);
mOverlayTextView = null;
}
}
@Override @Override
public void onClick(final DialogInterface dialog, final int which) { public void onClick(final DialogInterface dialog, final int which) {
saveTheme(ThemeItem.THEME_LIST.get(which)); saveTheme(ThemeItem.THEME_LIST.get(which));
@ -515,4 +551,26 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
} }
return false; return false;
} }
private void toggleOverlayView(boolean needsIme) {
if (mOverlayTextView == null) {
Context overlayContext = createDisplayContext(getDisplay())
.createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
int focusableFlags = FLAG_NOT_FOCUSABLE | (needsIme ? FLAG_ALT_FOCUSABLE_IM : 0);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
TYPE_APPLICATION_OVERLAY, FLAG_WATCH_OUTSIDE_TOUCH | focusableFlags);
final Rect windowBounds = getWindowManager().getCurrentWindowMetrics().getBounds();
params.width = windowBounds.width() / 3;
params.height = windowBounds.height() / 3;
params.gravity = TOP | LEFT;
mOverlayTextView = new TextView(overlayContext);
mOverlayTextView.setText("I'm an IME focusable overlay");
mOverlayTextView.setBackgroundColor(BLUE);
getWindowManager().addView(mOverlayTextView, params);
}
mOverlayTextView.setVisibility(mShowOverlay ? View.VISIBLE : View.GONE);
// Toggle the overlay visibility after the call.
mShowOverlay = !mShowOverlay;
}
} }