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
diff --git a/tools/EditTextVariations/AndroidManifest.xml b/tools/EditTextVariations/AndroidManifest.xml
index ecfe764..0cf6d4f 100644
--- a/tools/EditTextVariations/AndroidManifest.xml
+++ b/tools/EditTextVariations/AndroidManifest.xml
@@ -19,6 +19,7 @@
      android:versionName="0.67"
      android:versionCode="67">
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <supports-screens android:resizeable="true"/>
     <uses-sdk android:targetSdkVersion="27"
          android:minSdkVersion="11"/>
diff --git a/tools/EditTextVariations/res/values/strings.xml b/tools/EditTextVariations/res/values/strings.xml
index cb896e8..1b42dc7 100644
--- a/tools/EditTextVariations/res/values/strings.xml
+++ b/tools/EditTextVariations/res/values/strings.xml
@@ -35,6 +35,10 @@
     <string name="menu_softinput_hidden" translatable="false">Keyboard Hidden</string>
     <!-- The menu title to send a notification to test direct reply. [CHAR LIMIT=20] -->
     <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] -->
     <string name="custom_action_label">Custom</string>
 </resources>
diff --git a/tools/EditTextVariations/src/com/android/inputmethod/tools/edittextvariations/EditTextVariations.java b/tools/EditTextVariations/src/com/android/inputmethod/tools/edittextvariations/EditTextVariations.java
index 31a0025..53d08b6 100644
--- a/tools/EditTextVariations/src/com/android/inputmethod/tools/edittextvariations/EditTextVariations.java
+++ b/tools/EditTextVariations/src/com/android/inputmethod/tools/edittextvariations/EditTextVariations.java
@@ -16,10 +16,19 @@
 
 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.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -27,9 +36,11 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.provider.Settings;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.Log;
@@ -65,6 +76,7 @@
     private static final int MENU_SOFTINPUT_VISIBLE = 4;
     private static final int MENU_SOFTINPUT_HIDDEN = 5;
     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_NAVIGATE = "navigate";
     private static final String PREF_SOFTINPUT = "softinput";
@@ -85,6 +97,9 @@
 
     private ArrayAdapter<String> mAutoCompleteAdapter;
 
+    private TextView mOverlayTextView;
+    private boolean mShowOverlay = true;
+
     /** Called when the activity is first created. */
     @SuppressLint("SetJavaScriptEnabled")
     @Override
@@ -171,9 +186,12 @@
         if (NotificationUtils.DIRECT_REPLY_SUPPORTED) {
             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 {
             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))
                     .setEnabled(false);
         } catch (NameNotFoundException e) {
@@ -213,6 +231,16 @@
             } else {
                 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;
     }
@@ -234,6 +262,14 @@
     }
 
     @Override
+    protected void onDestroy() {
+        if (mOverlayTextView != null) {
+            getWindowManager().removeView(mOverlayTextView);
+            mOverlayTextView = null;
+        }
+    }
+
+    @Override
     public void onClick(final DialogInterface dialog, final int which) {
         saveTheme(ThemeItem.THEME_LIST.get(which));
         restartActivity();
@@ -515,4 +551,26 @@
         }
         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;
+    }
 }