1616
1717package com .android .inputmethod .tools .edittextvariations ;
1818
19+ import static android .graphics .Color .BLUE ;
20+ import static android .view .Gravity .LEFT ;
21+ import static android .view .Gravity .TOP ;
22+ import static android .view .WindowManager .LayoutParams .FLAG_ALT_FOCUSABLE_IM ;
23+ import static android .view .WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE ;
24+ import static android .view .WindowManager .LayoutParams .FLAG_WATCH_OUTSIDE_TOUCH ;
25+ import static android .view .WindowManager .LayoutParams .TYPE_APPLICATION_OVERLAY ;
26+
1927import android .Manifest ;
2028import android .annotation .SuppressLint ;
2129import android .app .Activity ;
2230import android .app .AlertDialog ;
31+ import android .content .Context ;
2332import android .content .DialogInterface ;
2433import android .content .Intent ;
2534import android .content .SharedPreferences ;
2635import android .content .pm .ApplicationInfo ;
2736import android .content .pm .PackageInfo ;
2837import android .content .pm .PackageManager ;
2938import android .content .pm .PackageManager .NameNotFoundException ;
39+ import android .graphics .Rect ;
3040import android .os .Build ;
3141import android .os .Bundle ;
3242import android .preference .PreferenceManager ;
43+ import android .provider .Settings ;
3344import android .text .InputType ;
3445import android .text .TextUtils ;
3546import android .util .Log ;
@@ -65,6 +76,7 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
6576 private static final int MENU_SOFTINPUT_VISIBLE = 4 ;
6677 private static final int MENU_SOFTINPUT_HIDDEN = 5 ;
6778 private static final int MENU_DIRECT_REPLY = 6 ;
79+ private static final int MENU_TOGGLE_IME_FOCUSABLE_OVERLAY = 7 ;
6880 private static final String PREF_THEME = "theme" ;
6981 private static final String PREF_NAVIGATE = "navigate" ;
7082 private static final String PREF_SOFTINPUT = "softinput" ;
@@ -85,6 +97,9 @@ public final class EditTextVariations extends Activity implements TextView.OnEdi
8597
8698 private ArrayAdapter <String > mAutoCompleteAdapter ;
8799
100+ private TextView mOverlayTextView ;
101+ private boolean mShowOverlay = true ;
102+
88103 /** Called when the activity is first created. */
89104 @ SuppressLint ("SetJavaScriptEnabled" )
90105 @ Override
@@ -171,9 +186,12 @@ public boolean onCreateOptionsMenu(final Menu menu) {
171186 if (NotificationUtils .DIRECT_REPLY_SUPPORTED ) {
172187 menu .add (Menu .NONE , MENU_DIRECT_REPLY , 5 , R .string .menu_direct_reply );
173188 }
189+ menu .add (Menu .NONE , MENU_TOGGLE_IME_FOCUSABLE_OVERLAY , 6 ,
190+ mShowOverlay ? getString (R .string .menu_show_ime_focusable_overlay )
191+ : getString (R .string .menu_hide_ime_focusable_overlay ));
174192 try {
175193 final PackageInfo pinfo = getPackageManager ().getPackageInfo (getPackageName (), 0 );
176- menu .add (Menu .NONE , MENU_VERSION , 6 ,
194+ menu .add (Menu .NONE , MENU_VERSION , 7 ,
177195 getString (R .string .menu_version , pinfo .versionName ))
178196 .setEnabled (false );
179197 } catch (NameNotFoundException e ) {
@@ -213,6 +231,16 @@ && checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) !=
213231 } else {
214232 NotificationUtils .sendDirectReplyNotification (this );
215233 }
234+ } else if (itemId == MENU_TOGGLE_IME_FOCUSABLE_OVERLAY ) {
235+ if (!Settings .canDrawOverlays (this )) {
236+ Toast .makeText (this ,
237+ "Not allowed to show overlay.\n Check \" Settings > "
238+ + "Display over other apps\" " , Toast .LENGTH_LONG ).show ();
239+ } else {
240+ toggleOverlayView (true /* needsIme */ );
241+ item .setTitle (mShowOverlay ? getString (R .string .menu_show_ime_focusable_overlay )
242+ : getString (R .string .menu_hide_ime_focusable_overlay ));
243+ }
216244 }
217245 return true ;
218246 }
@@ -233,6 +261,14 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions,
233261 }
234262 }
235263
264+ @ Override
265+ protected void onDestroy () {
266+ if (mOverlayTextView != null ) {
267+ getWindowManager ().removeView (mOverlayTextView );
268+ mOverlayTextView = null ;
269+ }
270+ }
271+
236272 @ Override
237273 public void onClick (final DialogInterface dialog , final int which ) {
238274 saveTheme (ThemeItem .THEME_LIST .get (which ));
@@ -515,4 +551,26 @@ private static boolean isNeedNotificationPermission() {
515551 }
516552 return false ;
517553 }
554+
555+ private void toggleOverlayView (boolean needsIme ) {
556+ if (mOverlayTextView == null ) {
557+ Context overlayContext = createDisplayContext (getDisplay ())
558+ .createWindowContext (TYPE_APPLICATION_OVERLAY , null /* options */ );
559+ int focusableFlags = FLAG_NOT_FOCUSABLE | (needsIme ? FLAG_ALT_FOCUSABLE_IM : 0 );
560+ final WindowManager .LayoutParams params = new WindowManager .LayoutParams (
561+ TYPE_APPLICATION_OVERLAY , FLAG_WATCH_OUTSIDE_TOUCH | focusableFlags );
562+ final Rect windowBounds = getWindowManager ().getCurrentWindowMetrics ().getBounds ();
563+ params .width = windowBounds .width () / 3 ;
564+ params .height = windowBounds .height () / 3 ;
565+ params .gravity = TOP | LEFT ;
566+
567+ mOverlayTextView = new TextView (overlayContext );
568+ mOverlayTextView .setText ("I'm an IME focusable overlay" );
569+ mOverlayTextView .setBackgroundColor (BLUE );
570+ getWindowManager ().addView (mOverlayTextView , params );
571+ }
572+ mOverlayTextView .setVisibility (mShowOverlay ? View .VISIBLE : View .GONE );
573+ // Toggle the overlay visibility after the call.
574+ mShowOverlay = !mShowOverlay ;
575+ }
518576}
0 commit comments