Merge "Disable draw overlay for most of Settings."
diff --git a/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java b/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
index d0b26a5..0f90c69 100644
--- a/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
+++ b/src/com/android/settings/applications/appinfo/DrawOverlayDetails.java
@@ -15,22 +15,13 @@
  */
 package com.android.settings.applications.appinfo;
 
-import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-
-import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.os.Bundle;
-import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
@@ -55,16 +46,11 @@
     private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
     private static final String LOG_TAG = "DrawOverlayDetails";
 
-    private static final int[] APP_OPS_OP_CODE = {
-            AppOpsManager.OP_SYSTEM_ALERT_WINDOW
-    };
-
     // Use a bridge to get the overlay details but don't initialize it to connect with all state.
     // TODO: Break out this functionality into its own class.
     private AppStateOverlayBridge mOverlayBridge;
     private AppOpsManager mAppOpsManager;
     private SwitchPreference mSwitchPref;
-    private Intent mSettingsIntent;
     private OverlayState mOverlayState;
 
     @Override
@@ -82,18 +68,15 @@
 
         // find preferences
         addPreferencesFromResource(R.xml.draw_overlay_permissions_details);
-        mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
+        mSwitchPref = findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
 
         // install event listeners
         mSwitchPref.setOnPreferenceChangeListener(this);
-
-        mSettingsIntent = new Intent(Intent.ACTION_MAIN)
-                .setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
     }
 
     // Override here so we don't have an empty screen
     @Override
-    public View onCreateView (LayoutInflater inflater,
+    public View onCreateView(LayoutInflater inflater,
             ViewGroup container,
             Bundle savedInstanceState) {
         // if we don't have a package info, show a page saying this is unsupported
@@ -104,21 +87,6 @@
     }
 
     @Override
-    public void onResume() {
-        super.onResume();
-        getActivity().getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        Window window = getActivity().getWindow();
-        WindowManager.LayoutParams attrs = window.getAttributes();
-        attrs.privateFlags &= ~SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-        window.setAttributes(attrs);
-    }
-
-    @Override
     public void onDestroy() {
         super.onDestroy();
         mOverlayBridge.release();
@@ -164,7 +132,9 @@
 
     @Override
     protected boolean refreshUi() {
-        if (mPackageInfo == null) return true;
+        if (mPackageInfo == null) {
+            return true;
+        }
 
         mOverlayState = mOverlayBridge.getOverlayInfo(mPackageName,
                 mPackageInfo.applicationInfo.uid);
@@ -174,9 +144,6 @@
         // you cannot ask a user to grant you a permission you did not have!
         mSwitchPref.setEnabled(mOverlayState.permissionDeclared && mOverlayState.controlEnabled);
 
-        ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
-                PackageManager.GET_META_DATA, mUserId);
-
         return true;
     }
 
diff --git a/src/com/android/settings/core/HideNonSystemOverlayMixin.java b/src/com/android/settings/core/HideNonSystemOverlayMixin.java
new file mode 100644
index 0000000..59cef3b
--- /dev/null
+++ b/src/com/android/settings/core/HideNonSystemOverlayMixin.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.core;
+
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.app.Activity;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+
+/**
+ * A mixin that adds window flag to prevent non-system overlays showing on top of Settings
+ * activities.
+ */
+public class HideNonSystemOverlayMixin implements LifecycleObserver {
+
+    private final Activity mActivity;
+
+    public HideNonSystemOverlayMixin(Activity activity) {
+        mActivity = activity;
+    }
+
+    @OnLifecycleEvent(ON_START)
+    public void onStart() {
+        if (mActivity == null) {
+            return;
+        }
+        mActivity.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        android.util.EventLog.writeEvent(0x534e4554, "120484087", -1, "");
+    }
+
+
+    @OnLifecycleEvent(ON_STOP)
+    public void onStop() {
+        if (mActivity == null) {
+            return;
+        }
+        final Window window = mActivity.getWindow();
+        final WindowManager.LayoutParams attrs = window.getAttributes();
+        attrs.privateFlags &= ~SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+        window.setAttributes(attrs);
+    }
+}
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index 294e754..cd13654 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
-import android.view.WindowManager.LayoutParams;
 import android.widget.Toolbar;
 
 import androidx.fragment.app.FragmentActivity;
@@ -59,8 +58,8 @@
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
         final long startTime = System.currentTimeMillis();
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
 
         final TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
         if (!theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 5fd26a6..3ccca00 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.notification;
 
-import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.settings.SettingsEnums;
@@ -26,8 +24,6 @@
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.view.Window;
-import android.view.WindowManager;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
@@ -88,8 +84,6 @@
     public void onResume() {
         super.onResume();
 
-        getActivity().getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
-
         if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
             Log.w(TAG, "Missing package or uid or packageinfo");
             finish();
@@ -124,15 +118,6 @@
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
-        final Window window = getActivity().getWindow();
-        final WindowManager.LayoutParams attrs = window.getAttributes();
-        attrs.privateFlags &= ~SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-        window.setAttributes(attrs);
-    }
-
-    @Override
     protected String getLogTag() {
         return TAG;
     }
diff --git a/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java b/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java
new file mode 100644
index 0000000..579cba0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.core;
+
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(RobolectricTestRunner.class)
+public class HideNonSystemOverlayMixinTest {
+
+    private ActivityController<TestActivity> mActivityController;
+
+    @Before
+    public void setUp() {
+        RuntimeEnvironment.application.setTheme(R.style.Theme_AppCompat);
+        mActivityController = Robolectric.buildActivity(TestActivity.class);
+    }
+
+    @Test
+    public void startActivity_shouldHideNonSystemOverlay() {
+        mActivityController.setup();
+        TestActivity activity = mActivityController.get();
+
+        // Activity start: HIDE_NON_SYSTEM_OVERLAY should be set.
+        final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
+        assertThat(attrs.privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
+                .isNotEqualTo(0);
+    }
+
+    @Test
+    public void stopActivity_shouldUnhideNonSystemOverlay() {
+        mActivityController.setup().stop();
+        TestActivity activity = mActivityController.get();
+
+        final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
+        assertThat(attrs.privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
+                .isEqualTo(0);
+    }
+
+    public static class TestActivity extends AppCompatActivity {
+        @Override
+        protected void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
+        }
+    }
+}