Commit fe86a2a5 authored by Raff Tsai's avatar Raff Tsai

Do not allow draw on top for App notification settings

Fixes: 119115683
Test: manual
Change-Id: Ib7b878a23b4a99171c58b5de992fb87feca8a28a
parent f514f1ee
......@@ -16,6 +16,8 @@
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;
......@@ -24,6 +26,8 @@ import android.os.AsyncTask;
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;
......@@ -33,7 +37,6 @@ import androidx.preference.SwitchPreference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.widget.MasterCheckBoxPreference;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
......@@ -85,6 +88,8 @@ public class AppNotificationSettings extends NotificationSettingsBase {
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();
......@@ -118,6 +123,15 @@ public class AppNotificationSettings extends NotificationSettingsBase {
updatePreferenceStates();
}
@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;
......
package com.android.settings.notification;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.view.Window;
import android.view.WindowManager;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@RunWith(RobolectricTestRunner.class)
public class AppNotificationSettingsTest {
private WindowManager.LayoutParams mLayoutParams;
private AppNotificationSettings mFragment;
private FragmentActivity mActivity;
@Mock
private Window mWindow;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLayoutParams = new WindowManager.LayoutParams();
mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
mFragment = spy(new AppNotificationSettings());
when(mFragment.getActivity()).thenReturn(mActivity);
when(mFragment.getFragmentManager()).thenReturn(mock(FragmentManager.class));
when(mActivity.getWindow()).thenReturn(mWindow);
when(mWindow.getAttributes()).thenReturn(mLayoutParams);
}
@Test
@Config(shadows = {ShadowNotificationSettingsBase.class})
public void onResume_shouldHideSystemOverlay() {
mFragment.onResume();
verify(mWindow).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
}
@Test
@Config(shadows = {ShadowNotificationSettingsBase.class})
public void onPause_shouldRemoveHideSystemOverlay() {
mFragment.onResume();
verify(mWindow).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
mFragment.onPause();
// There's no Window.clearPrivateFlags() method, so the Window.attributes are updated.
ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
WindowManager.LayoutParams.class);
verify(mWindow).setAttributes(paramCaptor.capture());
assertEquals(0,
paramCaptor.getValue().privateFlags
& SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
}
@Implements(NotificationSettingsBase.class)
public static class ShadowNotificationSettingsBase {
protected void __constructor__() {
// Do nothing
}
@Implementation
protected void onResume() {
// No-op.
}
@Implementation
protected void onPause() {
// No-op.
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment