subInfos = subManager.getActiveSubscriptionInfoList();
if (subInfos == null) {
return null;
}
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index dcba273c6a2..22b4311e1fa 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -22,6 +22,7 @@ import android.app.Activity;
import android.app.Application;
import android.app.settings.SettingsEnums;
import android.app.usage.IUsageStatsManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -62,6 +63,7 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
private static final int REQUEST_CODE = 200;
private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
private static final String KEY_ADVANCED_CATEGORY = "configure_notifications_advanced";
+ private static final String KEY_NAS = "notification_assistant";
private RingtonePreference mRequestPreference;
@@ -116,6 +118,8 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
}
});
+ controllers.add(new NotificationAssistantPreferenceController(context,
+ new NotificationBackend(), host, KEY_NAS));
if (FeatureFlagUtils.isEnabled(context, FeatureFlags.SILKY_HOME)) {
controllers.add(new EmergencyBroadcastPreferenceController(context,
@@ -199,4 +203,14 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
return keys;
}
};
+
+ // Dialogs only have access to the parent fragment, not the controller, so pass the information
+ // along to keep business logic out of this file
+ protected void enableNAS(ComponentName cn) {
+ final PreferenceScreen screen = getPreferenceScreen();
+ NotificationAssistantPreferenceController napc =
+ use(NotificationAssistantPreferenceController.class);
+ napc.setNotificationAssistantGranted(cn);
+ napc.updateState(screen.findPreference(napc.getPreferenceKey()));
+ }
}
diff --git a/src/com/android/settings/notification/NotificationAssistantDialogFragment.java b/src/com/android/settings/notification/NotificationAssistantDialogFragment.java
new file mode 100644
index 00000000000..48b1cd988ea
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationAssistantDialogFragment.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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.notification;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class NotificationAssistantDialogFragment extends InstrumentedDialogFragment
+ implements DialogInterface.OnClickListener {
+ static final String KEY_COMPONENT = "c";
+
+ public static NotificationAssistantDialogFragment newInstance(Fragment target,
+ ComponentName cn) {
+ final NotificationAssistantDialogFragment dialogFragment =
+ new NotificationAssistantDialogFragment();
+ final Bundle args = new Bundle();
+ args.putString(KEY_COMPONENT, cn.flattenToString());
+ dialogFragment.setArguments(args);
+ dialogFragment.setTargetFragment(target, 0);
+
+ return dialogFragment;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final String summary = getResources()
+ .getString(R.string.notification_assistant_security_warning_summary);
+ return new AlertDialog.Builder(getContext())
+ .setMessage(summary)
+ .setCancelable(true)
+ .setPositiveButton(R.string.okay, this)
+ .create();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DEFAULT_NOTIFICATION_ASSISTANT;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final Bundle args = getArguments();
+ final ComponentName cn = ComponentName.unflattenFromString(args
+ .getString(KEY_COMPONENT));
+ ConfigureNotificationSettings parent = (ConfigureNotificationSettings) getTargetFragment();
+ parent.enableNAS(cn);
+ }
+}
diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
index 66f27fef953..637e4b0d435 100644
--- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
@@ -18,44 +18,72 @@ package com.android.settings.notification;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.UserHandle;
+import android.provider.Settings;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.applications.DefaultAppInfo;
-import com.android.settingslib.widget.CandidateInfo;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.core.TogglePreferenceController;
import com.google.common.annotations.VisibleForTesting;
-public class NotificationAssistantPreferenceController extends BasePreferenceController {
+public class NotificationAssistantPreferenceController extends TogglePreferenceController {
+ private static final String TAG = "NASPreferenceController";
+ private static final int AVAILABLE = 1;
+ private Fragment mFragment;
+ private int mUserId = UserHandle.myUserId();
@VisibleForTesting
protected NotificationBackend mNotificationBackend;
- private PackageManager mPackageManager;
- public NotificationAssistantPreferenceController(Context context, String preferenceKey) {
+ public NotificationAssistantPreferenceController(Context context, NotificationBackend backend,
+ Fragment fragment, String preferenceKey) {
super(context, preferenceKey);
- mNotificationBackend = new NotificationBackend();
- mPackageManager = mContext.getPackageManager();
+ mNotificationBackend = backend;
+ mFragment = fragment;
}
@Override
public int getAvailabilityStatus() {
- return BasePreferenceController.AVAILABLE;
+ return AVAILABLE;
}
@Override
- public CharSequence getSummary() {
- CandidateInfo appSelected = new NotificationAssistantPicker.CandidateNone(mContext);
- ComponentName assistant = mNotificationBackend.getAllowedNotificationAssistant();
- if (assistant != null) {
- appSelected = createCandidateInfo(assistant);
- }
- return appSelected.loadLabel();
+ public boolean isChecked() {
+ ComponentName acn = mNotificationBackend.getAllowedNotificationAssistant();
+ ComponentName dcn = mNotificationBackend.getDefaultNotificationAssistant();
+ return (acn != null && acn.equals(dcn));
}
- @VisibleForTesting
- protected CandidateInfo createCandidateInfo(ComponentName cn) {
- return new DefaultAppInfo(mContext, mPackageManager, UserHandle.myUserId(), cn);
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ ComponentName cn = isChecked
+ ? mNotificationBackend.getDefaultNotificationAssistant() : null;
+ if (isChecked) {
+ if (mFragment == null) {
+ throw new IllegalStateException("No fragment to start activity");
+ }
+ showDialog(cn);
+ return false;
+ } else {
+ setNotificationAssistantGranted(null);
+ return true;
+ }
}
-}
+
+ protected void setNotificationAssistantGranted(ComponentName cn) {
+ if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, mUserId) == 0) {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 1, mUserId);
+ mNotificationBackend.resetDefaultNotificationAssistant(cn != null);
+ }
+ mNotificationBackend.setNotificationAssistantGranted(cn);
+ }
+
+ protected void showDialog(ComponentName cn) {
+ NotificationAssistantDialogFragment dialogFragment =
+ NotificationAssistantDialogFragment.newInstance(mFragment, cn);
+ dialogFragment.show(mFragment.getFragmentManager(), TAG);
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 4347ca55104..b08d02cef26 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -19,7 +19,6 @@ import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER;
import android.app.INotificationManager;
@@ -50,7 +49,6 @@ import android.service.notification.NotificationListenerFilter;
import android.text.format.DateUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
-import android.util.Slog;
import androidx.annotation.VisibleForTesting;
@@ -563,6 +561,23 @@ public class NotificationBackend {
}
}
+ public ComponentName getDefaultNotificationAssistant() {
+ try {
+ return sINM.getDefaultNotificationAssistant();
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling NoMan", e);
+ return null;
+ }
+ }
+
+ public void resetDefaultNotificationAssistant(boolean loadFromConfig) {
+ try {
+ sINM.resetDefaultNotificationAssistant(loadFromConfig);
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling NoMan", e);
+ }
+ }
+
public boolean setNotificationAssistantGranted(ComponentName cn) {
try {
sINM.setNotificationAssistantAccessGranted(cn, true);
diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
index 4958f1bfe6d..7fb4a48b195 100644
--- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java
+++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java
@@ -83,6 +83,22 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
private PackageManager mPm;
private CountDownLatch mCountdownLatch;
private Future mCountdownFuture;
+ private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ final TypedArray ta = NotificationHistoryActivity.this.obtainStyledAttributes(
+ new int[]{android.R.attr.dialogCornerRadius});
+ final float dialogCornerRadius = ta.getDimension(0, 0);
+ ta.recycle();
+ TypedValue v = new TypedValue();
+ NotificationHistoryActivity.this.getTheme().resolveAttribute(
+ com.android.internal.R.attr.listDivider, v, true);
+ int bottomPadding = NotificationHistoryActivity.this.getDrawable(v.resourceId)
+ .getIntrinsicHeight();
+ outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight() - bottomPadding),
+ dialogCornerRadius);
+ }
+ };
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
enum NotificationHistoryEvent implements UiEventLogger.UiEventEnum {
@@ -133,22 +149,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
notifications.isEmpty() ? View.GONE : View.VISIBLE);
mCountdownLatch.countDown();
mTodayView.setClipToOutline(true);
- mTodayView.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- final TypedArray ta = NotificationHistoryActivity.this.obtainStyledAttributes(
- new int[]{android.R.attr.dialogCornerRadius});
- final float dialogCornerRadius = ta.getDimension(0, 0);
- ta.recycle();
- TypedValue v = new TypedValue();
- NotificationHistoryActivity.this.getTheme().resolveAttribute(
- com.android.internal.R.attr.listDivider, v, true);
- int bottomPadding = NotificationHistoryActivity.this.getDrawable(v.resourceId)
- .getIntrinsicHeight();
- outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight() - bottomPadding),
- dialogCornerRadius);
- }
- });
+ mTodayView.setOutlineProvider(mOutlineProvider);
// for each package, new header and recycler view
for (int i = 0, notificationsSize = notifications.size(); i < notificationsSize; i++) {
NotificationHistoryPackage nhp = notifications.get(i);
@@ -216,6 +217,8 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity {
mTodayView = findViewById(R.id.apps);
mSnoozeView = findViewById(R.id.snoozed_list);
mDismissView = findViewById(R.id.recently_dismissed_list);
+ mDismissView.setClipToOutline(true);
+ mDismissView.setOutlineProvider(mOutlineProvider);
mHistoryOff = findViewById(R.id.history_off);
mHistoryOn = findViewById(R.id.history_on);
mHistoryEmpty = findViewById(R.id.history_on_empty);
diff --git a/src/com/android/settings/security/ScreenPinningPreferenceController.java b/src/com/android/settings/security/ScreenPinningPreferenceController.java
index 37a3f9caaaf..442380d4925 100644
--- a/src/com/android/settings/security/ScreenPinningPreferenceController.java
+++ b/src/com/android/settings/security/ScreenPinningPreferenceController.java
@@ -40,7 +40,7 @@ public class ScreenPinningPreferenceController extends BasePreferenceController
public CharSequence getSummary() {
return Settings.System.getInt(mContext.getContentResolver(),
Settings.System.LOCK_TO_APP_ENABLED, 0) != 0
- ? mContext.getText(R.string.switch_on_text)
- : mContext.getText(R.string.switch_off_text);
+ ? mContext.getText(R.string.screen_pinning_switch_on_text)
+ : mContext.getText(R.string.screen_pinning_switch_off_text);
}
}
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index cdc65372aed..181b78f535c 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -304,7 +304,9 @@ public class VpnSettings extends RestrictedSettingsFragment implements
LegacyVpnPreference p = mSettings.findOrCreatePreference(stubProfile, false);
p.setState(vpn.state);
p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(vpn.key));
- p.setInsecureVpn(VpnProfile.isLegacyType(stubProfile.type));
+ // (b/184921649) do not call setInsecureVpn() for connectedLegacyVpns, since the
+ // LegacyVpnInfo does not contain VPN type information, and the profile already
+ // exists within vpnProfiles.
updates.add(p);
}
diff --git a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
index 104761f7c88..6bc510d6b16 100644
--- a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
+++ b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
@@ -23,6 +23,7 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -40,7 +41,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.WifiConfigUiBase2;
import com.android.settings.wifi.WifiDialog2;
@@ -62,7 +63,7 @@ import java.util.List;
* The key of {@link WifiEntry} should be saved to the intent Extras when launching this class
* in order to properly render this page.
*/
-public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
+public class WifiNetworkDetailsFragment2 extends RestrictedDashboardFragment implements
WifiDialog2.WifiDialog2Listener {
private static final String TAG = "WifiNetworkDetailsFrg2";
@@ -75,6 +76,8 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
// Interval between initiating SavedNetworkTracker scans
private static final long SCAN_INTERVAL_MILLIS = 10_000;
+ @VisibleForTesting
+ boolean mIsUiRestricted;
@VisibleForTesting
NetworkDetailsTracker mNetworkDetailsTracker;
private HandlerThread mWorkerThread;
@@ -83,6 +86,34 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
@VisibleForTesting
List mControllers;
+ public WifiNetworkDetailsFragment2() {
+ super(UserManager.DISALLOW_CONFIG_WIFI);
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setIfOnlyAvailableForAdmins(true);
+ mIsUiRestricted = isUiRestricted();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mIsUiRestricted) {
+ restrictUi();
+ }
+ }
+
+ @VisibleForTesting
+ void restrictUi() {
+ clearWifiEntryCallback();
+ if (!isUiRestrictedByOnlyAdmin()) {
+ getEmptyTextView().setText(R.string.wifi_empty_list_user_restricted);
+ }
+ getPreferenceScreen().removeAll();
+ }
+
@Override
public void onDestroy() {
mWorkerThread.quit();
@@ -126,7 +157,7 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (isEditable()) {
+ if (!mIsUiRestricted && isEditable()) {
MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify);
item.setIcon(com.android.internal.R.drawable.ic_mode_edit);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
@@ -255,6 +286,17 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
getArguments().getString(KEY_CHOSEN_WIFIENTRY_KEY));
}
+ private void clearWifiEntryCallback() {
+ if (mNetworkDetailsTracker == null) {
+ return;
+ }
+ final WifiEntry wifiEntry = mNetworkDetailsTracker.getWifiEntry();
+ if (wifiEntry == null) {
+ return;
+ }
+ wifiEntry.setListener(null);
+ }
+
private boolean isEditable() {
if (mNetworkDetailsTracker == null) {
return false;
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index e34255035e5..088356b904e 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -294,13 +294,4 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
screen.setInitialExpandedChildrenCount(getInitialExpandedChildCount());
}
}
-
- @Override
- public int getInitialExpandedChildCount() {
- if (mSecurityPreferenceController != null && mSecurityPreferenceController.getSecurityType()
- == SoftApConfiguration.SECURITY_TYPE_OPEN) {
- return (EXPANDED_CHILD_COUNT_DEFAULT - 1);
- }
- return EXPANDED_CHILD_COUNT_DEFAULT;
- }
}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantDialogFragmentTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantDialogFragmentTest.java
new file mode 100644
index 00000000000..eef3f043bf8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantDialogFragmentTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 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.notification;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+
+import androidx.fragment.app.FragmentActivity;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationAssistantDialogFragmentTest {
+
+ private Context mContext;
+ @Mock
+ private ConfigureNotificationSettings mFragment;
+ private NotificationAssistantDialogFragment mDialogFragment;
+ @Mock
+ private FragmentActivity mActivity;
+
+ ComponentName mComponentName = new ComponentName("a", "b");
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mDialogFragment =
+ spy(NotificationAssistantDialogFragment.newInstance(mFragment, mComponentName));
+ doReturn(mActivity).when(mDialogFragment).getActivity();
+ doReturn(mContext).when(mDialogFragment).getContext();
+
+ }
+
+
+ @Test
+ public void testClickOK_callEnableNAS() {
+ mDialogFragment.onClick(null, DialogInterface.BUTTON_POSITIVE);
+
+ verify(mFragment, times(1)).enableNAS(eq(mComponentName));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
index b2f65e06d7b..4f2145cb07b 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
@@ -16,17 +16,25 @@
package com.android.settings.notification;
-import static junit.framework.TestCase.assertEquals;
-
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Debug;
+import android.provider.Settings;
-import com.android.settingslib.widget.CandidateInfo;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
@@ -35,7 +43,6 @@ import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class NotificationAssistantPreferenceControllerTest {
@@ -44,57 +51,86 @@ public class NotificationAssistantPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
+ private ConfigureNotificationSettings mFragment;
+ @Mock
+ private FragmentManager mFragmentManager;
+ @Mock
+ private FragmentTransaction mFragmentTransaction;
+ @Mock
private NotificationBackend mBackend;
private NotificationAssistantPreferenceController mPreferenceController;
+ ComponentName mNASComponent = new ComponentName("a", "b");
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mPreferenceController = new TestPreferenceController(mContext, mBackend);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ doReturn(mContext).when(mFragment).getContext();
+ when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
+ when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
+ when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent);
+ mPreferenceController = new NotificationAssistantPreferenceController(mContext,
+ mBackend, mFragment, KEY);
}
@Test
- public void testGetSummary_noAssistant() {
+ public void testIsChecked() throws Exception {
+ when(mBackend.getAllowedNotificationAssistant()).thenReturn(mNASComponent);
+ assertTrue(mPreferenceController.isChecked());
+
when(mBackend.getAllowedNotificationAssistant()).thenReturn(null);
- CharSequence noneLabel = new NotificationAssistantPicker.CandidateNone(mContext)
- .loadLabel();
- assertEquals(noneLabel, mPreferenceController.getSummary());
+ assertFalse(mPreferenceController.isChecked());
}
@Test
- public void testGetSummary_TestAssistant() {
- String testName = "test_pkg/test_cls";
- when(mBackend.getAllowedNotificationAssistant()).thenReturn(
- ComponentName.unflattenFromString(testName));
- assertEquals(testName, mPreferenceController.getSummary());
+ public void testSetChecked() throws Exception {
+ // Verify a dialog is shown when the switch is to be enabled.
+ assertFalse(mPreferenceController.setChecked(true));
+ verify(mFragmentTransaction).add(
+ any(NotificationAssistantDialogFragment.class), anyString());
+ verify(mBackend, times(0)).setNotificationAssistantGranted(any());
+
+ // Verify no dialog is shown and NAS set to null when disabled
+ assertTrue(mPreferenceController.setChecked(false));
+ verify(mBackend, times(1)).setNotificationAssistantGranted(null);
}
- private final class TestPreferenceController extends NotificationAssistantPreferenceController {
+ @Test
+ public void testMigrationFromSetting_userEnable() throws Exception {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0);
- private TestPreferenceController(Context context, NotificationBackend backend) {
- super(context, KEY);
- mNotificationBackend = backend;
- }
+ //Test user enable for the first time
+ mPreferenceController.setNotificationAssistantGranted(mNASComponent);
+ assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0));
+ verify(mBackend, times(1))
+ .resetDefaultNotificationAssistant(eq(true));
- @Override
- public String getPreferenceKey() {
- return KEY;
- }
+ //Test user enable again, migration should not happen
+ mPreferenceController.setNotificationAssistantGranted(mNASComponent);
+ //Number of invocations should not increase
+ verify(mBackend, times(1))
+ .resetDefaultNotificationAssistant(eq(true));
+ }
- @Override
- protected CandidateInfo createCandidateInfo(ComponentName cn) {
- return new CandidateInfo(true) {
- @Override
- public CharSequence loadLabel() { return cn.flattenToString(); }
+ @Test
+ public void testMigrationFromSetting_userDisable() throws Exception {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0);
- @Override
- public Drawable loadIcon() { return null; }
+ //Test user disable for the first time
+ mPreferenceController.setChecked(false);
+ assertEquals(1, Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0));
+ verify(mBackend, times(1))
+ .resetDefaultNotificationAssistant(eq(false));
- @Override
- public String getKey() { return null; }
- };
- }
+ //Test user disable again, migration should not happen
+ mPreferenceController.setChecked(false);
+ //Number of invocations should not increase
+ verify(mBackend, times(1))
+ .resetDefaultNotificationAssistant(eq(false));
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
index 66b5bcb9bcc..fdd6295ab65 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
@@ -32,6 +32,7 @@ import android.app.settings.SettingsEnums;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.widget.TextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -110,6 +111,41 @@ public class WifiNetworkDetailsFragment2Test {
verify(mMenu, never()).add(anyInt(), anyInt(), anyInt(), eq(R.string.wifi_modify));
}
+ @Test
+ public void onCreateOptionsMenu_uiRestricted_shouldNotAddEditMenu() {
+ mFragment.mIsUiRestricted = true;
+
+ mFragment.onCreateOptionsMenu(mMenu, mock(MenuInflater.class));
+
+ verify(mMenu, never()).add(anyInt(), anyInt(), anyInt(), eq(R.string.wifi_modify));
+ }
+
+ @Test
+ public void restrictUi_shouldShowRestrictedText() {
+ final FakeFragment fragment = spy(new FakeFragment());
+ final PreferenceScreen screen = mock(PreferenceScreen.class);
+ final TextView restrictedText = mock(TextView.class);
+ doReturn(screen).when(fragment).getPreferenceScreen();
+ doReturn(false).when(fragment).isUiRestrictedByOnlyAdmin();
+ doReturn(restrictedText).when(fragment).getEmptyTextView();
+
+ fragment.restrictUi();
+
+ verify(restrictedText).setText(anyInt());
+ }
+
+ @Test
+ public void restrictUi_shouldRemoveAllPreferences() {
+ final FakeFragment fragment = spy(new FakeFragment());
+ final PreferenceScreen screen = mock(PreferenceScreen.class);
+ doReturn(screen).when(fragment).getPreferenceScreen();
+ doReturn(true).when(fragment).isUiRestrictedByOnlyAdmin();
+
+ fragment.restrictUi();
+
+ verify(screen).removeAll();
+ }
+
@Test
public void refreshPreferences_controllerShouldUpdateStateAndDisplayPreference() {
final FakeFragment fragment = spy(new FakeFragment());
@@ -136,6 +172,11 @@ public class WifiNetworkDetailsFragment2Test {
public void addPreferenceController(AbstractPreferenceController controller) {
super.addPreferenceController(controller);
}
+
+ @Override
+ public boolean isUiRestrictedByOnlyAdmin() {
+ return super.isUiRestrictedByOnlyAdmin();
+ }
}
public class TestController extends BasePreferenceController {
diff --git a/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java b/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
index 028b224123a..fec7ad3d777 100644
--- a/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
@@ -132,8 +132,6 @@ public class MobileNetworkUtilsTest {
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
Arrays.asList(mSubscriptionInfo1, mSubscriptionInfo2));
- when(mSubscriptionManager.getAccessibleSubscriptionInfoList()).thenReturn(
- Arrays.asList(mSubscriptionInfo1, mSubscriptionInfo2));
when(mTelephonyManager.getNetworkOperatorName()).thenReturn(
PLMN_FROM_TELEPHONY_MANAGER_API);
diff --git a/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java
index 0d20140fba6..f7e311131ce 100644
--- a/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java
@@ -88,8 +88,6 @@ public class OpenNetworkSelectPagePreferenceControllerTest {
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
Arrays.asList(mSubscriptionInfo));
- when(mSubscriptionManager.getAccessibleSubscriptionInfoList()).thenReturn(
- Arrays.asList(mSubscriptionInfo));
when(mTelephonyManager.getNetworkOperatorName()).thenReturn(OPERATOR_NAME);