From 42d6144c0295e5025dc1f682058e0d09286bcdcb Mon Sep 17 00:00:00 2001 From: Jacob Hobbie Date: Fri, 23 Aug 2024 16:08:42 +0000 Subject: [PATCH 01/11] Allow Watch Unlock to exit back to Device Unlock settings. Seeking to imitate the behavior from fingerprint and face unlock. In GMS Core we will control when to send the RESULT_TIMEOUT resultCode, but we should generally exit all the way out to Device Unlock, where there is a passcode entry requirement, when we swipe away from Watch Unlock's settings. Flag: com.android.settings.flags.active_unlock_finish_parent Test: Manually Bug: 343576960 Change-Id: Ia9a1564295a44ab6925ea9fceebf92f437e03731 --- ...etrics_framework_flag_declarations.aconfig | 7 ++++++ .../CombinedBiometricSettings.java | 24 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/aconfig/settings_biometrics_framework_flag_declarations.aconfig b/aconfig/settings_biometrics_framework_flag_declarations.aconfig index e787da05e90..e81c68e6aa0 100644 --- a/aconfig/settings_biometrics_framework_flag_declarations.aconfig +++ b/aconfig/settings_biometrics_framework_flag_declarations.aconfig @@ -14,3 +14,10 @@ flag { description: "This flag enables or disables the Fingerprint v2 enrollment" bug: "295206723" } + +flag { + name: "active_unlock_finish_parent" + namespace: "biometrics_framework" + description: "This flag enables the Active Unlock settings activity to finish its parent activity" + bug: "343576960" +} diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java index 671a5b659fc..7b3a72446f7 100644 --- a/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java +++ b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java @@ -24,14 +24,19 @@ import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Nullable; import androidx.preference.Preference; import com.android.settings.R; +import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.activeunlock.ActiveUnlockContentListener.OnContentChangedListener; import com.android.settings.biometrics.activeunlock.ActiveUnlockDeviceNameListener; import com.android.settings.biometrics.activeunlock.ActiveUnlockRequireBiometricSetup; import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils; +import com.android.settings.flags.Flags; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.search.SearchIndexable; @@ -52,6 +57,10 @@ public class CombinedBiometricSettings extends BiometricsSettingsBase { private CombinedBiometricStatusUtils mCombinedBiometricStatusUtils; @Nullable private ActiveUnlockDeviceNameListener mActiveUnlockDeviceNameListener; + private final ActivityResultLauncher mActiveUnlockPreferenceLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + this::onActiveUnlockPreferenceResult); + @Override public void onAttach(Context context) { super.onAttach(context); @@ -158,12 +167,25 @@ public class CombinedBiometricSettings extends BiometricsSettingsBase { intent = mActiveUnlockStatusUtils.getIntent(); } if (intent != null) { - startActivityForResult(intent, ACTIVE_UNLOCK_REQUEST); + if (Flags.activeUnlockFinishParent()) { + mActiveUnlockPreferenceLauncher.launch(intent); + } else { + startActivityForResult(intent, ACTIVE_UNLOCK_REQUEST); + } } return true; } + private void onActiveUnlockPreferenceResult(@Nullable ActivityResult result) { + if (result != null && result.getResultCode() == BiometricEnrollBase.RESULT_TIMEOUT) { + mDoNotFinishActivity = false; + // When "Watch Unlock" is closed due to entering onStop(), + // "Face & Fingerprint Unlock" shall also close itself and back to "Security" page. + finish(); + } + } + @Override protected String getUseAnyBiometricSummary() { // either Active Unlock is not enabled or no device is enrolled. From 227548d9271f4fe3588ebfaeae435bf297e771b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Mon, 26 Aug 2024 15:42:58 +0200 Subject: [PATCH 02/11] Make ZenIconLoader injectable (in SystemUI) In settings, reduce calls to getInstance(), and pass it to preferences and their controllers instead. Bug: 360399800 Test: atest ZenModesListItemPreferenceTest ZenModesListPreferenceControllerTest Flag: android.app.modes_ui Change-Id: I318320575e3bd32b5d13a385fa644f8032484e1c --- .../AbstractZenModeHeaderController.java | 5 +++- .../ZenModeEditNameIconFragmentBase.java | 4 +++- .../notification/modes/ZenModeFragment.java | 4 +++- .../modes/ZenModeHeaderController.java | 9 ++++--- ...odeIconPickerIconPreferenceController.java | 6 +++-- .../modes/ZenModesListFragment.java | 3 ++- .../modes/ZenModesListItemPreference.java | 19 ++++++++++++--- .../ZenModesListPreferenceController.java | 10 +++++--- .../modes/ZenModesListItemPreferenceTest.java | 24 +++++++++---------- .../ZenModesListPreferenceControllerTest.java | 5 +++- 10 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java index af6423185e8..1d1b07d85a6 100644 --- a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java +++ b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java @@ -43,15 +43,18 @@ import java.util.function.Function; abstract class AbstractZenModeHeaderController extends AbstractZenModePreferenceController { private final DashboardFragment mFragment; + private final ZenIconLoader mIconLoader; private EntityHeaderController mHeaderController; @Nullable private ZenIcon.Key mCurrentIconKey; AbstractZenModeHeaderController( @NonNull Context context, + @NonNull ZenIconLoader iconLoader, @NonNull String key, @NonNull DashboardFragment fragment) { super(context, key); mFragment = fragment; + mIconLoader = iconLoader; } @Override @@ -90,7 +93,7 @@ abstract class AbstractZenModeHeaderController extends AbstractZenModePreference if (!Objects.equal(mCurrentIconKey, zenMode.getIconKey())) { mCurrentIconKey = zenMode.getIconKey(); FutureUtil.whenDone( - ZenIconLoader.getInstance().getIcon(mContext, zenMode), + mIconLoader.getIcon(mContext, zenMode), icon -> { checkNotNull(mHeaderController) .setIcon(iconStylist.apply(icon.drawable())) diff --git a/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java b/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java index 96cbf91b0d3..6dd90769645 100644 --- a/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java +++ b/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java @@ -30,6 +30,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; @@ -102,7 +103,8 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment protected final List createPreferenceControllers( Context context) { return ImmutableList.of( - new ZenModeIconPickerIconPreferenceController(context, "chosen_icon", this), + new ZenModeIconPickerIconPreferenceController(context, ZenIconLoader.getInstance(), + "chosen_icon", this), new ZenModeEditNamePreferenceController(context, "name", this::setModeName), new ZenModeIconPickerListPreferenceController(context, "icon_list", this::setModeIcon), diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java index 6889cac2e60..8eef7083995 100644 --- a/src/com/android/settings/notification/modes/ZenModeFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeFragment.java @@ -32,6 +32,7 @@ import androidx.core.view.MenuProvider; import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import java.util.ArrayList; @@ -54,7 +55,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { @Override protected List createPreferenceControllers(Context context) { List prefControllers = new ArrayList<>(); - prefControllers.add(new ZenModeHeaderController(context, "header", this)); + prefControllers.add( + new ZenModeHeaderController(context, ZenIconLoader.getInstance(), "header", this)); prefControllers.add(new ZenModeBlurbPreferenceController(context, "mode_blurb")); prefControllers.add( new ZenModeButtonPreferenceController(context, "activate", this, mBackend)); diff --git a/src/com/android/settings/notification/modes/ZenModeHeaderController.java b/src/com/android/settings/notification/modes/ZenModeHeaderController.java index ae6eacc52da..e901b9fb1a9 100644 --- a/src/com/android/settings/notification/modes/ZenModeHeaderController.java +++ b/src/com/android/settings/notification/modes/ZenModeHeaderController.java @@ -23,15 +23,14 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; class ZenModeHeaderController extends AbstractZenModeHeaderController { - ZenModeHeaderController( - @NonNull Context context, - @NonNull String key, - @NonNull DashboardFragment fragment) { - super(context, key, fragment); + ZenModeHeaderController(@NonNull Context context, @NonNull ZenIconLoader iconLoader, + @NonNull String key, @NonNull DashboardFragment fragment) { + super(context, iconLoader, key, fragment); } @Override diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java index 6c8d41f591a..dc0be100ae3 100644 --- a/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java @@ -24,14 +24,16 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; /** Controller used for displaying the currently-chosen icon at the top of the icon picker. */ class ZenModeIconPickerIconPreferenceController extends AbstractZenModeHeaderController { - ZenModeIconPickerIconPreferenceController(@NonNull Context context, @NonNull String key, + ZenModeIconPickerIconPreferenceController(@NonNull Context context, + @NonNull ZenIconLoader iconLoader, @NonNull String key, @NonNull DashboardFragment fragment) { - super(context, key, fragment); + super(context, iconLoader, key, fragment); } @Override diff --git a/src/com/android/settings/notification/modes/ZenModesListFragment.java b/src/com/android/settings/notification/modes/ZenModesListFragment.java index 588b3202bb6..37772b38eed 100644 --- a/src/com/android/settings/notification/modes/ZenModesListFragment.java +++ b/src/com/android/settings/notification/modes/ZenModesListFragment.java @@ -31,6 +31,7 @@ import com.android.settings.notification.modes.ZenModesListAddModePreferenceCont import com.android.settings.notification.modes.ZenModesListAddModePreferenceController.OnAddModeListener; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexable; @@ -56,7 +57,7 @@ public class ZenModesListFragment extends ZenModesFragmentBase { private static List buildPreferenceControllers(Context context, ZenModesBackend backend, OnAddModeListener onAddModeListener) { return ImmutableList.of( - new ZenModesListPreferenceController(context, backend), + new ZenModesListPreferenceController(context, backend, ZenIconLoader.getInstance()), new ZenModesListAddModePreferenceController(context, onAddModeListener) ); } diff --git a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java index 0c31d8f0097..0909c6f5f2e 100644 --- a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java +++ b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java @@ -31,6 +31,8 @@ import com.android.settingslib.notification.modes.ZenMode; import com.google.common.base.Strings; +import java.util.concurrent.Executor; + /** * Preference representing a single mode item on the modes aggregator page. Clicking on this * preference leads to an individual mode's configuration page. @@ -38,18 +40,29 @@ import com.google.common.base.Strings; class ZenModesListItemPreference extends RestrictedPreference { private final Context mContext; + private final ZenIconLoader mIconLoader; + private final Executor mUiExecutor; private ZenMode mZenMode; private TextView mTitleView; private TextView mSummaryView; - ZenModesListItemPreference(Context context, ZenMode zenMode) { + ZenModesListItemPreference(Context context, ZenIconLoader iconLoader, ZenMode zenMode) { + this(context, iconLoader, context.getMainExecutor(), zenMode); + } + + @VisibleForTesting + ZenModesListItemPreference(Context context, ZenIconLoader iconLoader, Executor uiExecutor, + ZenMode zenMode) { super(context); mContext = context; + mIconLoader = iconLoader; + mUiExecutor = uiExecutor; setZenMode(zenMode); setKey(zenMode.getId()); } + @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); @@ -93,12 +106,12 @@ class ZenModesListItemPreference extends RestrictedPreference { setIconSize(ICON_SIZE_SMALL); FutureUtil.whenDone( - ZenIconLoader.getInstance().getIcon(mContext, mZenMode), + mIconLoader.getIcon(mContext, mZenMode), icon -> setIcon( zenMode.isActive() ? IconUtil.applyAccentTint(mContext, icon.drawable()) : IconUtil.applyNormalTint(mContext, icon.drawable())), - mContext.getMainExecutor()); + mUiExecutor); updateTextColor(zenMode); } diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java index 12b727862c1..5e36469f39c 100644 --- a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java @@ -25,6 +25,7 @@ import androidx.preference.PreferenceCategory; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexableRaw; @@ -42,11 +43,14 @@ class ZenModesListPreferenceController extends BasePreferenceController implements BasePreferenceController.UiBlocker { protected static final String KEY = "zen_modes_list"; - protected ZenModesBackend mBackend; + private final ZenModesBackend mBackend; + private final ZenIconLoader mIconLoader; - ZenModesListPreferenceController(Context context, @NonNull ZenModesBackend backend) { + ZenModesListPreferenceController(Context context, @NonNull ZenModesBackend backend, @NonNull + ZenIconLoader iconLoader) { super(context, KEY); mBackend = backend; + mIconLoader = iconLoader; } @Override @@ -82,7 +86,7 @@ class ZenModesListPreferenceController extends BasePreferenceController modePreference.setZenMode(mode); } else { // new rule; create a new ZenRulePreference & add it to the preference category - modePreference = new ZenModesListItemPreference(mContext, mode); + modePreference = new ZenModesListItemPreference(mContext, mIconLoader, mode); category.addPreference(modePreference); } modePreference.setOrder(modes.indexOf(mode)); diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java index f5d5160c84b..3722e416061 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java @@ -36,7 +36,6 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @EnableFlags(Flags.FLAG_MODES_UI) @@ -45,18 +44,18 @@ public class ZenModesListItemPreferenceTest { public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Context mContext; + private final ZenIconLoader mIconLoader = new ZenIconLoader( + MoreExecutors.newDirectExecutorService()); @Before public void setup() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - ZenIconLoader.setInstance(new ZenIconLoader(MoreExecutors.newDirectExecutorService())); } @Test public void constructor_setsMode() { - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, - TestModeBuilder.EXAMPLE); + ZenModesListItemPreference preference = newPreference(TestModeBuilder.EXAMPLE); assertThat(preference.getKey()).isEqualTo(TestModeBuilder.EXAMPLE.getId()); assertThat(preference.getZenMode()).isEqualTo(TestModeBuilder.EXAMPLE); @@ -70,8 +69,7 @@ public class ZenModesListItemPreferenceTest { .setEnabled(true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); // To load icon. + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Enabled mode"); assertThat(preference.getSummary()).isEqualTo("When the thrush knocks"); @@ -87,8 +85,7 @@ public class ZenModesListItemPreferenceTest { .setActive(true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Active mode"); assertThat(preference.getSummary()).isEqualTo("ON • When Birnam forest comes to Dunsinane"); @@ -103,8 +100,7 @@ public class ZenModesListItemPreferenceTest { .setEnabled(false, /* byUser= */ false) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Mode disabled by app"); assertThat(preference.getSummary()).isEqualTo("Not set"); @@ -119,11 +115,15 @@ public class ZenModesListItemPreferenceTest { .setEnabled(false, /* byUser= */ true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Mode disabled by user"); assertThat(preference.getSummary()).isEqualTo("Disabled"); assertThat(preference.getIcon()).isNotNull(); } + + private ZenModesListItemPreference newPreference(ZenMode zenMode) { + return new ZenModesListItemPreference(mContext, mIconLoader, MoreExecutors.directExecutor(), + zenMode); + } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java index 4fa8b8ac6c4..69568ce1434 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java @@ -40,11 +40,13 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settingslib.notification.modes.TestModeBuilder; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexableRaw; import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.MoreExecutors; import org.junit.Before; import org.junit.Rule; @@ -95,7 +97,8 @@ public class ZenModesListPreferenceControllerTest { PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext); preferenceScreen.addPreference(mPreference); - mPrefController = new ZenModesListPreferenceController(mContext, mBackend); + mPrefController = new ZenModesListPreferenceController(mContext, mBackend, + new ZenIconLoader(MoreExecutors.newDirectExecutorService())); } @Test From fc8e8991c939d19ed386dcac51a517a4f347ded7 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 29 Aug 2024 15:55:44 +0800 Subject: [PATCH 03/11] Clean up InternetPreferenceController And also the flag. Bug: 339884322 Flag: com.android.settings.flags.internet_preference_controller_v2 Test: manual - Network & internet Change-Id: Icb3427f6624db0442c05f5e149dbe522d1497e83 --- ...tings_experience_flag_declarations.aconfig | 10 - res/xml/network_provider_internet.xml | 3 +- .../network/InternetPreferenceController.java | 316 ------------------ .../network/NetworkDashboardFragment.java | 9 - .../settings/wifi/WifiSummaryUpdater.java | 110 ------ .../settings/wifi/WifiSummaryUpdaterTest.java | 152 --------- .../InternetPreferenceControllerTest.java | 297 ---------------- 7 files changed, 2 insertions(+), 895 deletions(-) delete mode 100644 src/com/android/settings/network/InternetPreferenceController.java delete mode 100644 src/com/android/settings/wifi/WifiSummaryUpdater.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java delete mode 100644 tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java diff --git a/aconfig/settings_experience_flag_declarations.aconfig b/aconfig/settings_experience_flag_declarations.aconfig index e79b51560ed..d5caccfbb5c 100644 --- a/aconfig/settings_experience_flag_declarations.aconfig +++ b/aconfig/settings_experience_flag_declarations.aconfig @@ -17,13 +17,3 @@ flag { purpose: PURPOSE_BUGFIX } } - -flag { - name: "internet_preference_controller_v2" - namespace: "settings_experience" - description: "New InternetPreferenceControllerV2." - bug: "339884322" - metadata { - purpose: PURPOSE_BUGFIX - } -} diff --git a/res/xml/network_provider_internet.xml b/res/xml/network_provider_internet.xml index 2a08aae892d..e4ebe788b0c 100644 --- a/res/xml/network_provider_internet.xml +++ b/res/xml/network_provider_internet.xml @@ -29,7 +29,8 @@ android:order="-30" settings:allowDividerAbove="true" settings:keywords="@string/keywords_internet" - settings:useAdminDisabledSummary="true" /> + settings:useAdminDisabledSummary="true" + settings:controller="com.android.settings.network.InternetPreferenceControllerV2" /> mSubInfoEntityList = new ArrayList<>(); - private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - private DefaultSubscriptionReceiver mDataSubscriptionChangedReceiver; - private boolean mIsHotspotNetworkEnabled = SharedConnectivityRepository.isDeviceConfigEnabled(); - @VisibleForTesting - WifiPickerTrackerHelper mWifiPickerTrackerHelper; - - @VisibleForTesting - static Map sIconMap = new HashMap<>(); - static { - sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_unavailable); - sIconMap.put(INTERNET_NETWORKS_AVAILABLE, R.drawable.ic_no_internet_available); - sIconMap.put(INTERNET_WIFI, R.drawable.ic_wifi_signal_4); - sIconMap.put(INTERNET_CELLULAR, R.drawable.ic_network_cell); - sIconMap.put(INTERNET_ETHERNET, R.drawable.ic_settings_ethernet); - } - - private static Map sSummaryMap = new HashMap<>(); - static { - sSummaryMap.put(INTERNET_OFF, R.string.condition_airplane_title); - sSummaryMap.put(INTERNET_NETWORKS_AVAILABLE, R.string.networks_available); - sSummaryMap.put(INTERNET_WIFI, 0); - sSummaryMap.put(INTERNET_CELLULAR, 0); - sSummaryMap.put(INTERNET_ETHERNET, R.string.to_switch_networks_disconnect_ethernet); - } - - public InternetPreferenceController(Context context, Lifecycle lifecycle, - LifecycleOwner lifecycleOwner) { - super(context); - if (lifecycle == null) { - throw new IllegalArgumentException("Lifecycle must be set"); - } - mSummaryHelper = new WifiSummaryUpdater(mContext, this); - mInternetUpdater = new InternetUpdater(context, lifecycle, this); - mInternetType = mInternetUpdater.getInternetType(); - mLifecycleOwner = lifecycleOwner; - mMobileNetworkRepository = MobileNetworkRepository.getInstance(context); - mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this); - if (mIsHotspotNetworkEnabled) { - mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(lifecycle, context, this); - } - lifecycle.addObserver(this); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(KEY); - } - - private void drawIcon(int iconResId) { - Drawable drawable = mContext.getDrawable(iconResId); - if (drawable != null) { - drawable.setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal)); - mPreference.setIcon(drawable); - } - } - - @Override - public void updateState(Preference preference) { - if (mPreference == null) { - return; - } - - if (mInternetType == INTERNET_WIFI && updateHotspotNetwork()) { - return; - } - - final @IdRes int icon = sIconMap.get(mInternetType); - if (icon != 0) { - drawIcon(icon); - } - - if (mInternetType == INTERNET_WIFI) { - mPreference.setSummary(mSummaryHelper.getSummary()); - return; - } - - if (mInternetType == INTERNET_CELLULAR) { - updateCellularSummary(); - return; - } - - final @IdRes int summary = sSummaryMap.get(mInternetType); - if (summary != 0) { - mPreference.setSummary(summary); - } - } - - @VisibleForTesting - boolean updateHotspotNetwork() { - if (mWifiPickerTrackerHelper == null) { - return false; - } - WifiEntry entry = mWifiPickerTrackerHelper.getWifiPickerTracker().getConnectedWifiEntry(); - if (!(entry instanceof HotspotNetworkEntry)) { - return false; - } - drawIcon(getHotspotIconResource(((HotspotNetworkEntry) entry).getDeviceType())); - mPreference.setSummary(((HotspotNetworkEntry) entry).getAlternateSummary()); - return true; - } - - @Override - public boolean isAvailable() { - return mContext.getResources().getBoolean(R.bool.config_show_internet_settings); - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - /** @OnLifecycleEvent(ON_RESUME) */ - @OnLifecycleEvent(ON_RESUME) - public void onResume() { - mMobileNetworkRepository.addRegister(mLifecycleOwner, this, - SubscriptionManager.INVALID_SUBSCRIPTION_ID); - mMobileNetworkRepository.updateEntity(); - mSummaryHelper.register(true); - mDataSubscriptionChangedReceiver.registerReceiver(); - mDefaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); - } - - /** @OnLifecycleEvent(ON_PAUSE) */ - @OnLifecycleEvent(ON_PAUSE) - public void onPause() { - mMobileNetworkRepository.removeRegister(this); - mSummaryHelper.register(false); - mDataSubscriptionChangedReceiver.unRegisterReceiver(); - } - - /** - * Called when internet type is changed. - * - * @param internetType the internet type - */ - @Override - public void onInternetTypeChanged(@InternetUpdater.InternetType int internetType) { - final boolean needUpdate = (internetType != mInternetType); - mInternetType = internetType; - if (needUpdate) { - ThreadUtils.postOnMainThread(() -> { - updateState(mPreference); - }); - } - } - - /** - * Called when airplane mode state is changed. - */ - @Override - public void onAirplaneModeChanged(boolean isAirplaneModeOn) { - ThreadUtils.postOnMainThread(() -> { - updateState(mPreference); - }); - } - - @Override - public void onSummaryChanged(String summary) { - if (mInternetType == INTERNET_WIFI) { - updateState(mPreference); - } - } - - @VisibleForTesting - void updateCellularSummary() { - CharSequence summary = null; - SubscriptionInfoEntity activeSubInfo = null; - SubscriptionInfoEntity defaultSubInfo = null; - - for (SubscriptionInfoEntity subInfo : getSubscriptionInfoList()) { - if (subInfo.isActiveDataSubscriptionId) { - activeSubInfo = subInfo; - } - if (subInfo.getSubId() == getDefaultDataSubscriptionId()) { - defaultSubInfo = subInfo; - } - } - if (activeSubInfo == null || defaultSubInfo == null) { - return; - } - activeSubInfo = activeSubInfo.isSubscriptionVisible ? activeSubInfo : defaultSubInfo; - - if (activeSubInfo.equals(defaultSubInfo)) { - // DDS is active - summary = activeSubInfo.uniqueName; - } else { - summary = mContext.getString( - R.string.mobile_data_temp_using, activeSubInfo.uniqueName); - } - - mPreference.setSummary(summary); - } - - @VisibleForTesting - protected List getSubscriptionInfoList() { - return mSubInfoEntityList; - } - - @VisibleForTesting - protected int getDefaultDataSubscriptionId() { - return mDefaultDataSubId; - } - - @Override - public void onAvailableSubInfoChanged(List subInfoEntityList) { - mSubInfoEntityList = subInfoEntityList; - updateState(mPreference); - } - - @Override - public void onDefaultDataChanged(int defaultDataSubId) { - mDefaultDataSubId = defaultDataSubId; - updateState(mPreference); - } - - @Override - public void onWifiEntriesChanged() { - if (mInternetType == INTERNET_WIFI) { - updateState(mPreference); - } - } - - @Override - public void onWifiStateChanged() { - // Do nothing - } - - @Override - public void onNumSavedNetworksChanged() { - // Do nothing - } - - @Override - public void onNumSavedSubscriptionsChanged() { - // Do nothing - } -} diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java index 3bc535845c1..aff91308e94 100644 --- a/src/com/android/settings/network/NetworkDashboardFragment.java +++ b/src/com/android/settings/network/NetworkDashboardFragment.java @@ -25,7 +25,6 @@ import com.android.settings.R; import com.android.settings.SettingsDumpService; import com.android.settings.core.OnActivityResultListener; import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.flags.Flags; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -90,14 +89,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements controllers.add(new MobileNetworkSummaryController(context, lifecycle, lifecycleOwner)); controllers.add(vpnPreferenceController); - - if (Flags.internetPreferenceControllerV2()) { - controllers.add( - new InternetPreferenceControllerV2(context, InternetPreferenceController.KEY)); - } else { - controllers.add(new InternetPreferenceController(context, lifecycle, lifecycleOwner)); - } - controllers.add(privateDnsPreferenceController); // Start SettingsDumpService after the MobileNetworkRepository is created. diff --git a/src/com/android/settings/wifi/WifiSummaryUpdater.java b/src/com/android/settings/wifi/WifiSummaryUpdater.java deleted file mode 100644 index 645d2eaf57a..00000000000 --- a/src/com/android/settings/wifi/WifiSummaryUpdater.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkScoreManager; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.text.TextUtils; - -import androidx.annotation.VisibleForTesting; - -import com.android.settings.R; -import com.android.settings.widget.SummaryUpdater; -import com.android.settingslib.wifi.WifiStatusTracker; - -/** - * Helper class that listeners to wifi callback and notify client when there is update in - * wifi summary info. - */ -public class WifiSummaryUpdater extends SummaryUpdater { - - private final WifiStatusTracker mWifiTracker; - private final BroadcastReceiver mReceiver; - - private static final IntentFilter INTENT_FILTER; - static { - INTENT_FILTER = new IntentFilter(); - INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - INTENT_FILTER.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - INTENT_FILTER.addAction(WifiManager.RSSI_CHANGED_ACTION); - } - - public WifiSummaryUpdater(Context context, OnSummaryChangeListener listener) { - this(context, listener, null); - } - - @VisibleForTesting - public WifiSummaryUpdater(Context context, OnSummaryChangeListener listener, - WifiStatusTracker wifiTracker) { - super(context, listener); - mWifiTracker = wifiTracker != null ? wifiTracker : - new WifiStatusTracker(context, context.getSystemService(WifiManager.class), - context.getSystemService(NetworkScoreManager.class), - context.getSystemService(ConnectivityManager.class), - this::notifyChangeIfNeeded); - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - mWifiTracker.handleBroadcast(intent); - notifyChangeIfNeeded(); - } - }; - } - - @Override - public void register(boolean register) { - if (register) { - mWifiTracker.fetchInitialState(); - notifyChangeIfNeeded(); - mContext.registerReceiver(mReceiver, INTENT_FILTER, - Context.RECEIVER_EXPORTED_UNAUDITED); - } else { - mContext.unregisterReceiver(mReceiver); - } - mWifiTracker.setListening(register); - } - - @Override - public String getSummary() { - if (!mWifiTracker.enabled) { - return mContext.getString(R.string.switch_off_text); - } - if (!mWifiTracker.connected) { - return mContext.getString(R.string.disconnected); - } - String ssid = WifiInfo.sanitizeSsid(mWifiTracker.ssid); - if (TextUtils.isEmpty(mWifiTracker.statusLabel)) { - return ssid; - } - return mContext.getResources().getString( - com.android.settingslib.R.string.preference_summary_default_combination, - ssid, mWifiTracker.statusLabel); - } - - /** - * return true if Wi-Fi connected. - */ - public boolean isWifiConnected() { - return mWifiTracker.connected; - } -} diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java deleted file mode 100644 index 99040dba951..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.wifi.WifiManager; - -import com.android.settings.R; -import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener; -import com.android.settingslib.wifi.WifiStatusTracker; - -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 WifiSummaryUpdaterTest { - @Mock private WifiStatusTracker mWifiTracker; - @Mock private SummaryListener mListener; - - private Context mContext; - private WifiSummaryUpdater mSummaryUpdater; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application.getApplicationContext()); - doReturn(mock(Intent.class)).when(mContext).registerReceiver(any(), any(), anyInt()); - doNothing().when(mContext).unregisterReceiver(any(BroadcastReceiver.class)); - - mSummaryUpdater = new WifiSummaryUpdater(mContext, mListener, mWifiTracker); - } - - @Test - public void register_true_shouldRegisterListenerAndTracker() { - mSummaryUpdater.register(true); - - verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), - anyInt()); - verify(mWifiTracker).setListening(true); - } - - @Test - public void register_true_shouldFetchInitialStateAndSendSummaryChange() { - mSummaryUpdater.register(true); - - verify(mWifiTracker).fetchInitialState(); - verify(mListener).onSummaryChanged(anyString()); - } - - @Test - public void register_false_shouldUnregisterListenerAndTracker() { - mSummaryUpdater.register(true); - mSummaryUpdater.register(false); - - verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); - verify(mWifiTracker).setListening(false); - } - - @Test - public void onReceive_networkStateChanged_shouldSendSummaryChange() { - mSummaryUpdater.register(true); - mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); - - verify(mListener).onSummaryChanged(anyString()); - } - - @Test - public void onReceive_rssiChanged_shouldSendSummaryChange() { - mSummaryUpdater.register(true); - mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION)); - - verify(mListener).onSummaryChanged(anyString()); - } - - @Test - public void getSummary_wifiDisabled_shouldReturnDisabled() { - mWifiTracker.enabled = false; - - assertThat(mSummaryUpdater.getSummary()) - .isEqualTo(mContext.getString(R.string.switch_off_text)); - } - - @Test - public void getSummary_wifiDisconnected_shouldReturnDisconnected() { - mWifiTracker.enabled = true; - mWifiTracker.connected = false; - - assertThat(mSummaryUpdater.getSummary()) - .isEqualTo(mContext.getString(R.string.disconnected)); - } - - @Test - public void getSummary_wifiConnected_shouldReturnSsid() { - mWifiTracker.enabled = true; - mWifiTracker.connected = true; - mWifiTracker.ssid = "Test Ssid"; - - assertThat(mSummaryUpdater.getSummary()).isEqualTo("Test Ssid"); - } - - @Test - public void getSummary_wifiConnected_withSpeedLabel_shouldReturnSsid_withSpeedLabel() { - mWifiTracker.enabled = true; - mWifiTracker.connected = true; - mWifiTracker.ssid = "Test Ssid"; - mWifiTracker.statusLabel = "Very Fast"; - - assertThat(mSummaryUpdater.getSummary()).isEqualTo("Test Ssid / Very Fast"); - } - - private class SummaryListener implements OnSummaryChangeListener { - private String summary; - - @Override - public void onSummaryChanged(String summary) { - this.summary = summary; - } - } -} diff --git a/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java deleted file mode 100644 index 1c482efeef2..00000000000 --- a/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2020 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.network; - -import static com.android.settings.network.InternetUpdater.INTERNET_NETWORKS_AVAILABLE; -import static com.android.settings.network.InternetUpdater.INTERNET_WIFI; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkRequest; -import android.net.NetworkScoreManager; -import android.net.wifi.WifiManager; -import android.os.Handler; -import android.os.Looper; - -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.LifecycleRegistry; -import androidx.preference.Preference; -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; -import androidx.test.annotation.UiThreadTest; -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.android.settings.R; -import com.android.settings.testutils.ResourcesUtils; -import com.android.settings.wifi.WifiPickerTrackerHelper; -import com.android.settings.wifi.WifiSummaryUpdater; -import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity; -import com.android.wifitrackerlib.HotspotNetworkEntry; -import com.android.wifitrackerlib.StandardWifiEntry; -import com.android.wifitrackerlib.WifiPickerTracker; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -public class InternetPreferenceControllerTest { - - private static final String TEST_SUMMARY = "test summary"; - private static final String TEST_ALTERNATE_SUMMARY = "test alternate summary"; - private static final String NOT_CONNECTED = "Not connected"; - private static final String SUB_ID_1 = "1"; - private static final String SUB_ID_2 = "2"; - private static final String DISPLAY_NAME_1 = "Sub 1"; - private static final String DISPLAY_NAME_2 = "Sub 2"; - - @Rule - public final MockitoRule mMockitoRule = MockitoJUnit.rule(); - @Spy - private Context mContext = ApplicationProvider.getApplicationContext(); - @Mock - private SubscriptionInfoEntity mActiveSubInfo; - @Mock - private SubscriptionInfoEntity mDefaultDataSubInfo; - @Mock - private ConnectivityManager mConnectivityManager; - @Mock - private LifecycleOwner mLifecycleOwner; - @Mock - private WifiManager mWifiManager; - @Mock - private WifiSummaryUpdater mSummaryHelper; - @Mock - private WifiPickerTrackerHelper mWifiPickerTrackerHelper; - @Mock - private WifiPickerTracker mWifiPickerTracker; - @Mock - private HotspotNetworkEntry mHotspotNetworkEntry; - - private LifecycleRegistry mLifecycleRegistry; - - private MockInternetPreferenceController mController; - private PreferenceScreen mScreen; - private Preference mPreference; - private List mSubscriptionInfoEntityList = new ArrayList<>(); - - @Before - public void setUp() { - when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); - when(mContext.getSystemService(NetworkScoreManager.class)) - .thenReturn(mock(NetworkScoreManager.class)); - when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - when(mWifiPickerTrackerHelper.getWifiPickerTracker()).thenReturn(mWifiPickerTracker); - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null /* WifiEntry */); - when(mHotspotNetworkEntry.getAlternateSummary()).thenReturn(TEST_ALTERNATE_SUMMARY); - - if (Looper.myLooper() == null) { - Looper.prepare(); - } - mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner); - when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry); - mController = new MockInternetPreferenceController(mContext, mock(Lifecycle.class), - mLifecycleOwner); - mController.sIconMap.put(INTERNET_WIFI, 0); - mController.mWifiPickerTrackerHelper = mWifiPickerTrackerHelper; - - final PreferenceManager preferenceManager = new PreferenceManager(mContext); - mScreen = preferenceManager.createPreferenceScreen(mContext); - mPreference = new Preference(mContext); - mPreference.setKey(InternetPreferenceController.KEY); - mScreen.addPreference(mPreference); - } - - private class MockInternetPreferenceController extends - com.android.settings.network.InternetPreferenceController { - - private int mDefaultDataSubscriptionId; - public MockInternetPreferenceController(Context context, Lifecycle lifecycle, - LifecycleOwner lifecycleOwner) { - super(context, lifecycle, lifecycleOwner); - } - - private List mSubscriptionInfoEntity; - - @Override - protected List getSubscriptionInfoList() { - return mSubscriptionInfoEntity; - } - - public void setSubscriptionInfoList(List list) { - mSubscriptionInfoEntity = list; - } - - @Override - protected int getDefaultDataSubscriptionId() { - return mDefaultDataSubscriptionId; - } - - public void setDefaultDataSubscriptionId(int subscriptionId) { - mDefaultDataSubscriptionId = subscriptionId; - } - - } - - private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, int slotId, - String displayName, boolean isVisible, boolean isValid, boolean isActive, - boolean isActiveData) { - return new SubscriptionInfoEntity(subId, slotId, false, false, displayName, isVisible, - false, isValid, isActive, isActiveData); - } - - @Test - public void isAvailable_shouldMatchPrefFlag() { - assertThat(mController.isAvailable()).isEqualTo( - mContext.getResources().getBoolean(R.bool.config_show_internet_settings)); - } - - @Test - @UiThreadTest - public void onResume_shouldRegisterCallback() { - mController.onResume(); - - verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), - any(int.class)); - verify(mConnectivityManager).registerNetworkCallback( - any(NetworkRequest.class), - any(ConnectivityManager.NetworkCallback.class), - any(Handler.class)); - } - - @Test - @UiThreadTest - public void onPause_shouldUnregisterCallback() { - mController.onResume(); - mController.onPause(); - - verify(mContext, times(2)).unregisterReceiver(any(BroadcastReceiver.class)); - verify(mConnectivityManager, times(2)).unregisterNetworkCallback( - any(ConnectivityManager.NetworkCallback.class)); - } - - @Test - public void onSummaryChanged_internetWifi_updateSummary() { - when(mSummaryHelper.getSummary()).thenReturn(TEST_SUMMARY); - mController.mSummaryHelper = mSummaryHelper; - mController.onInternetTypeChanged(INTERNET_WIFI); - mController.displayPreference(mScreen); - - mController.onSummaryChanged(TEST_SUMMARY); - - assertThat(mPreference.getSummary()).isEqualTo(TEST_SUMMARY); - } - - @Test - public void onSummaryChanged_internetNetworksAvailable_notUpdateSummary() { - when(mSummaryHelper.getSummary()).thenReturn(TEST_SUMMARY); - mController.mSummaryHelper = mSummaryHelper; - mController.onInternetTypeChanged(INTERNET_NETWORKS_AVAILABLE); - mController.displayPreference(mScreen); - mPreference.setSummary(NOT_CONNECTED); - - mController.onSummaryChanged(TEST_SUMMARY); - - assertThat(mPreference.getSummary()).isNotEqualTo(TEST_SUMMARY); - } - - @Test - public void updateCellularSummary_getNullSubscriptionInfo_shouldNotCrash() { - mController.setSubscriptionInfoList(mSubscriptionInfoEntityList); - - mController.updateCellularSummary(); - } - - @Test - public void updateCellularSummary_getActiveSubscriptionInfo_cbrs() { - mController.setDefaultDataSubscriptionId(Integer.parseInt(SUB_ID_2)); - mActiveSubInfo = setupSubscriptionInfoEntity(SUB_ID_1, 1, DISPLAY_NAME_1, - false, true, true, true); - mDefaultDataSubInfo = setupSubscriptionInfoEntity(SUB_ID_2, 1, DISPLAY_NAME_2, - false, true, true, false); - mSubscriptionInfoEntityList.add(mActiveSubInfo); - mSubscriptionInfoEntityList.add(mDefaultDataSubInfo); - mController.setSubscriptionInfoList(mSubscriptionInfoEntityList); - mController.displayPreference(mScreen); - - mController.updateCellularSummary(); - assertThat(mPreference.getSummary()).isEqualTo(DISPLAY_NAME_2); - - mActiveSubInfo = setupSubscriptionInfoEntity(SUB_ID_1, 1, DISPLAY_NAME_1, - true, true, true, true); - mSubscriptionInfoEntityList.add(mActiveSubInfo); - mController.setSubscriptionInfoList(mSubscriptionInfoEntityList); - mController.onAvailableSubInfoChanged(mSubscriptionInfoEntityList); - final String expectedSummary = - ResourcesUtils.getResourcesString(mContext, "mobile_data_temp_using", - DISPLAY_NAME_1); - mController.updateCellularSummary(); - assertThat(mPreference.getSummary()).isEqualTo(expectedSummary); - } - - @Test - public void updateHotspotNetwork_isHotspotNetworkEntry_updateAlternateSummary() { - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(mHotspotNetworkEntry); - mController.onInternetTypeChanged(INTERNET_WIFI); - mController.displayPreference(mScreen); - mPreference.setSummary(TEST_SUMMARY); - - mController.updateHotspotNetwork(); - - assertThat(mPreference.getSummary().toString()).isEqualTo(TEST_ALTERNATE_SUMMARY); - } - - @Test - public void updateHotspotNetwork_notHotspotNetworkEntry_notChangeSummary() { - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(mock(StandardWifiEntry.class)); - mController.onInternetTypeChanged(INTERNET_WIFI); - mController.displayPreference(mScreen); - mPreference.setSummary(TEST_SUMMARY); - - mController.updateHotspotNetwork(); - - assertThat(mPreference.getSummary().toString()).isEqualTo(TEST_SUMMARY); - } - - @Test - public void updateHotspotNetwork_hotspotNetworkNotEnabled_returnFalse() { - mController.mWifiPickerTrackerHelper = null; - - assertThat(mController.updateHotspotNetwork()).isFalse(); - } -} From 93c566ef5bbe1624b89624e915161e177b97229e Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Tue, 27 Aug 2024 18:51:05 +0100 Subject: [PATCH 04/11] Clean up fully rolled out HeadlessSingleUserFixes Flag was rolled out in Android V. Bug: 335663055 Test: TH Flag: EXEMPT flag cleanup Change-Id: I7de1f400d03662b690f4a77a379994985797a3fe --- .../password/ConfirmDeviceCredentialBaseFragment.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java index cfee9805740..0d57b577298 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java @@ -27,7 +27,6 @@ import android.app.KeyguardManager; import android.app.RemoteLockscreenValidationSession; import android.app.admin.DevicePolicyManager; import android.app.admin.ManagedSubscriptionsPolicy; -import android.app.admin.flags.Flags; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; @@ -375,13 +374,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr private int getUserTypeForWipe() { final UserInfo userToBeWiped = mUserManager.getUserInfo( mDevicePolicyManager.getProfileWithMinimumFailedPasswordsForWipe(mEffectiveUserId)); - UserHandle primaryUser = UserHandle.SYSTEM; - if (Flags.headlessSingleUserFixes()) { - UserHandle mainUser = mUserManager.getMainUser(); - if (mainUser != null ) { - primaryUser = mainUser; - } - } + UserHandle mainUser = mUserManager.getMainUser(); + UserHandle primaryUser = mainUser != null ? mainUser : UserHandle.SYSTEM; if (userToBeWiped == null || userToBeWiped.getUserHandle().equals(primaryUser)) { return USER_TYPE_PRIMARY; } else if (userToBeWiped.isManagedProfile()) { From 78ee160c20eeb41bb7eccfde9af772a9b1a958d6 Mon Sep 17 00:00:00 2001 From: Chris Antol Date: Thu, 29 Aug 2024 19:50:55 +0000 Subject: [PATCH 05/11] Only check INTERACT_ACROSS_USERS_FULL when user handle is not current Bug: 326057017 Change-Id: I83ab4461f28e7f40c676099213c840a1a7dc932a Test: atest; open app info pages from both primary and secondary profile -> verify they open as expected Flag: EXEMPT bug fix --- .../settings/applications/AppInfoBase.java | 16 ++++++++-------- .../applications/AppInfoWithHeaderTest.java | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java index c056add7ef3..1d774826c2d 100644 --- a/src/com/android/settings/applications/AppInfoBase.java +++ b/src/com/android/settings/applications/AppInfoBase.java @@ -136,14 +136,14 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment mPackageName = intent.getData().getSchemeSpecificPart(); } } - if (!hasInteractAcrossUsersPermission()) { - Log.w(TAG, "Intent not valid."); - finish(); - return ""; - } if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) { - mUserId = ((UserHandle) intent.getParcelableExtra( - Intent.EXTRA_USER_HANDLE)).getIdentifier(); + mUserId = ((UserHandle) intent.getParcelableExtra(Intent.EXTRA_USER_HANDLE)) + .getIdentifier(); + if (mUserId != UserHandle.myUserId() && !hasInteractAcrossUsersFullPermission()) { + Log.w(TAG, "Intent not valid."); + finish(); + return ""; + } } else { mUserId = UserHandle.myUserId(); } @@ -171,7 +171,7 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment } @VisibleForTesting - protected boolean hasInteractAcrossUsersPermission() { + protected boolean hasInteractAcrossUsersFullPermission() { Activity activity = getActivity(); if (!(activity instanceof SettingsActivity)) { return false; diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java index cb121ea3c05..0ed56c0fec6 100644 --- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java @@ -250,7 +250,7 @@ public class AppInfoWithHeaderTest { } @Override - protected boolean hasInteractAcrossUsersPermission() { + protected boolean hasInteractAcrossUsersFullPermission() { return true; } @@ -267,7 +267,7 @@ public class AppInfoWithHeaderTest { private static final class TestFragmentWithoutPermission extends TestFragment { @Override - protected boolean hasInteractAcrossUsersPermission() { + protected boolean hasInteractAcrossUsersFullPermission() { return false; } } From 5a9c00e63e6adab403430a5372614c1545575313 Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Wed, 28 Aug 2024 12:11:45 +0800 Subject: [PATCH 06/11] Add log for fetch data from BatteryStatsManager. Bug: 362177550 Bug: 357978626 Test: manual Flag: EXEMPT bug fix Change-Id: Iec6e7ccb871cc34d5ab3d2c8d8414edef0118024 --- .../fuelgauge/batteryusage/DataProcessor.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java index da8481d3a13..ebe7996d335 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java @@ -172,13 +172,21 @@ public final class DataProcessor { /** Gets the {@link BatteryUsageStats} from system service. */ @Nullable public static BatteryUsageStats getBatteryUsageStats(final Context context) { + final long startTime = System.currentTimeMillis(); final BatteryUsageStatsQuery batteryUsageStatsQuery = new BatteryUsageStatsQuery.Builder() .includeBatteryHistory() .includeProcessStateData() .build(); - return context.getSystemService(BatteryStatsManager.class) - .getBatteryUsageStats(batteryUsageStatsQuery); + final BatteryUsageStats batteryUsageStats = + context.getSystemService(BatteryStatsManager.class) + .getBatteryUsageStats(batteryUsageStatsQuery); + Log.d( + TAG, + String.format( + "getBatteryUsageStats() from BatteryStatsManager in %d/ms", + System.currentTimeMillis() - startTime)); + return batteryUsageStats; } /** Gets the {@link UsageEvents} from system service for all unlocked users. */ @@ -1693,8 +1701,14 @@ public final class DataProcessor { final UserManager userManager = context.getSystemService(UserManager.class); final SparseArray batteryEntryList = new SparseArray<>(); final ArrayList results = new ArrayList<>(); + final long startTime = System.currentTimeMillis(); final List uidBatteryConsumers = batteryUsageStats.getUidBatteryConsumers(); + Log.d( + TAG, + String.format( + "get %d uidBatteryConsumers from BatteryUsageStats in %d/ms", + uidBatteryConsumers.size(), (System.currentTimeMillis() - startTime))); // Sort to have all apps with "real" UIDs first, followed by apps that are supposed // to be combined with the real ones. @@ -1763,9 +1777,11 @@ public final class DataProcessor { deviceConsumer.getConsumedPowerForCustomComponent(componentId))); } + final int numComponentEntries = batteryEntryList.size(); final List userBatteryConsumers = batteryUsageStats.getUserBatteryConsumers(); - for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) { + final int numUserEntries = userBatteryConsumers.size(); + for (int i = 0; i < numUserEntries; i++) { final UserBatteryConsumer consumer = userBatteryConsumers.get(i); results.add( new BatteryEntry( @@ -1785,6 +1801,13 @@ public final class DataProcessor { results.add(batteryEntryList.valueAt(i)); } + Log.d( + TAG, + String.format( + "getCoalescedUsageList(): uidEntries = %d, " + + "userEntries = %d, componentEntries = %d", + numUidSippers, numUserEntries, numComponentEntries)); + // The sort order must have changed, so re-sort based on total power use. results.sort(BatteryEntry.COMPARATOR); return results; From f4f78a738246c8eb43edb83b3a3c9e26d17c9adb Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Fri, 30 Aug 2024 14:08:56 +0800 Subject: [PATCH 07/11] Extend sleep timeout to fix flake tests. Fix: 363146362 Test: atest PeriodicJobReceiverTest Flag: EXEMPT bug fix Change-Id: If62ed640d25a3ebb3ab1ac0929e8075a2008f4cf --- .../fuelgauge/batteryusage/PeriodicJobReceiverTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiverTest.java index ea3c04c87c0..82121660c19 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiverTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/PeriodicJobReceiverTest.java @@ -108,7 +108,7 @@ public final class PeriodicJobReceiverTest { mReceiver.onReceive(mContext, JOB_UPDATE_INTENT); - TimeUnit.MILLISECONDS.sleep(100); + TimeUnit.MILLISECONDS.sleep(1000); assertThat(mDao.getAllAfter(0)).hasSize(1); } @@ -119,7 +119,7 @@ public final class PeriodicJobReceiverTest { mReceiver.onReceive(mContext, JOB_UPDATE_INTENT); - TimeUnit.MILLISECONDS.sleep(100); + TimeUnit.MILLISECONDS.sleep(1000); assertThat(mDao.getAllAfter(0)).hasSize(3); } From 407f69fec58f7ebcd0f0a2fc93c032e65ec9f5a0 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Fri, 30 Aug 2024 16:24:49 +0800 Subject: [PATCH 08/11] Fix WifiPrivacy for special SSID AP - root cause: specail SSID AP(contain '%', end with '\' or '/' and end with '???'), andriodx Navigation cannot find destination - changes: use Base64 UrlEncode replace String Bug: 360304229 Flag: EXEMPT bugfix Test: Manual testing atest -c WifiPrivacyPageProviderTest Change-Id: Ifb89451477f2ba143f504b94c8d4d9167aee2c2e --- .../settings/wifi/details2/WifiPrivacyPageProvider.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/wifi/details2/WifiPrivacyPageProvider.kt b/src/com/android/settings/wifi/details2/WifiPrivacyPageProvider.kt index 7744a73cc17..8888f0dacf5 100644 --- a/src/com/android/settings/wifi/details2/WifiPrivacyPageProvider.kt +++ b/src/com/android/settings/wifi/details2/WifiPrivacyPageProvider.kt @@ -55,6 +55,7 @@ import com.android.settingslib.spa.widget.ui.CategoryTitle import com.android.wifitrackerlib.WifiEntry import java.time.Clock import java.time.ZoneOffset +import java.util.Base64 const val WIFI_ENTRY_KEY = "wifiEntryKey" @@ -68,7 +69,8 @@ object WifiPrivacyPageProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { - val wifiEntryKey = arguments!!.getString(WIFI_ENTRY_KEY) + val wifiEntryKey = + String(Base64.getUrlDecoder().decode(arguments!!.getString(WIFI_ENTRY_KEY))) if (wifiEntryKey != null) { val context = LocalContext.current val lifecycle = LocalLifecycleOwner.current.lifecycle @@ -81,7 +83,7 @@ object WifiPrivacyPageProvider : SettingsPageProvider { fun getRoute( wifiEntryKey: String, - ): String = "${name}/$wifiEntryKey" + ): String = "${name}/${Base64.getUrlEncoder().encodeToString(wifiEntryKey.toByteArray())}" } @Composable From 916d02c95829dedc59cf1b3a5c7b1648cbd60ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Fri, 30 Aug 2024 15:25:43 +0200 Subject: [PATCH 09/11] Add DND icon as option in the icon picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Goodbye croissant mode. 🥐🥲 Bug: 361597532 Test: manual Flag: android.app.modes_ui Change-Id: Ic8c3dc0d45eab660da84ea844d3315b425954564 --- res/values/arrays.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 8cbf5dc6ad3..8e5519fa7c6 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1536,6 +1536,7 @@ @*android:drawable/ic_zen_mode_icon_group_of_people @*android:drawable/ic_zen_mode_icon_lightbulb @*android:drawable/ic_zen_mode_type_schedule_calendar + @*android:drawable/ic_zen_mode_type_special_dnd @*android:drawable/ic_zen_mode_icon_running @*android:drawable/ic_zen_mode_icon_golf @@ -1561,7 +1562,6 @@ @*android:drawable/ic_zen_mode_icon_train @*android:drawable/ic_zen_mode_type_driving - @*android:drawable/ic_zen_mode_icon_croissant @*android:drawable/ic_zen_mode_icon_fork_and_knife @*android:drawable/ic_zen_mode_icon_shopping_cart @*android:drawable/ic_zen_mode_icon_child @@ -1587,6 +1587,7 @@ Group of people Lightbulb Calendar + Do Not Disturb Person running Golf @@ -1612,7 +1613,6 @@ Train Car - Croissant Fork and knife Shopping cart Child From 970d364d072e1b433436de8fba7b0cdac449e03e Mon Sep 17 00:00:00 2001 From: Geoffrey Boullanger Date: Fri, 30 Aug 2024 14:46:53 +0000 Subject: [PATCH 10/11] Add updateState to AutoTimeZonePreferenceController The summary (i.e. description under the toggle title in Android settings) from AutoTimeZonePreferenceController is only used in wifi-only devices, like Tangor. We have found that since V, the summary was no longer displayed in the Date and time settings page. This fix brings the summary back. Bug: b/363176828 Test: tested on a Tangor tablet Flag: EXEMPT bugfix Change-Id: I1f118b8e1d5e0d8d1b0f5b515d79522b72fb4fa4 --- .../datetime/AutoTimeZonePreferenceController.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java index 3a1f995aaf2..8eccf319784 100644 --- a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java +++ b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java @@ -27,6 +27,8 @@ import android.app.time.TimeZoneCapabilitiesAndConfig; import android.app.time.TimeZoneConfiguration; import android.content.Context; +import androidx.preference.Preference; + import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; @@ -115,6 +117,12 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController return R.string.menu_key_system; } + @Override + public void updateState(Preference preference) { + super.updateState(preference); + refreshSummary(preference); + } + @Override public CharSequence getSummary() { // If auto time zone cannot enable telephony fallback and is capable of location, then auto From eff79d3365445e22db88864a5da21c41b9b5ce52 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Fri, 30 Aug 2024 19:04:55 +0000 Subject: [PATCH 11/11] Revert "Clean up fully rolled out HeadlessSingleUserFixes" Revert submission 28993807-hdop-cleaup Reason for revert: Droidmonitor created revert due to b/363275535. Will be verifying through ABTD before submission. Reverted changes: /q/submissionid:28993807-hdop-cleaup Change-Id: I89127e1c6e445adb21dbf96c6bbbec8935bf6296 --- .../password/ConfirmDeviceCredentialBaseFragment.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java index 0d57b577298..cfee9805740 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java @@ -27,6 +27,7 @@ import android.app.KeyguardManager; import android.app.RemoteLockscreenValidationSession; import android.app.admin.DevicePolicyManager; import android.app.admin.ManagedSubscriptionsPolicy; +import android.app.admin.flags.Flags; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; @@ -374,8 +375,13 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr private int getUserTypeForWipe() { final UserInfo userToBeWiped = mUserManager.getUserInfo( mDevicePolicyManager.getProfileWithMinimumFailedPasswordsForWipe(mEffectiveUserId)); - UserHandle mainUser = mUserManager.getMainUser(); - UserHandle primaryUser = mainUser != null ? mainUser : UserHandle.SYSTEM; + UserHandle primaryUser = UserHandle.SYSTEM; + if (Flags.headlessSingleUserFixes()) { + UserHandle mainUser = mUserManager.getMainUser(); + if (mainUser != null ) { + primaryUser = mainUser; + } + } if (userToBeWiped == null || userToBeWiped.getUserHandle().equals(primaryUser)) { return USER_TYPE_PRIMARY; } else if (userToBeWiped.isManagedProfile()) {