From caf122bcb68550c41890864f413669a46bccac69 Mon Sep 17 00:00:00 2001 From: cnchen Date: Wed, 3 Apr 2019 16:18:34 +0800 Subject: [PATCH 01/22] Fix fingerprint screens from "Anything else" screen not applying Stencil theme Bug: 129788677 Test: RunSettingsRoboTests, manual test intent extra data has been passed Change-Id: Icfae54061e5d87a8ba9c95263d840c456aac5bcb --- src/com/android/settings/password/ChooseLockSettingsHelper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index 00e0bcdb658..db125986c95 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -31,6 +31,7 @@ import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import com.android.internal.widget.LockPatternUtils; +import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -452,6 +453,7 @@ public final class ChooseLockSettingsHelper { } private void copyInternalExtras(Intent inIntent, Intent outIntent) { + SetupWizardUtils.copySetupExtras(inIntent, outIntent); String theme = inIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME); if (theme != null) { outIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme); From 63b4c1ab85516685427560913211be41d0e998c9 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 8 Apr 2019 19:56:45 +0800 Subject: [PATCH 02/22] Remove the PreferenceGroup without title in WifiNetworkDetailsFragment To remove the PreferenceGroup title space. Bug: 129683066 Test: manual Change-Id: I00bced8038a01c0ef7e8f4dfa0b82e36a275004e --- res/xml/wifi_network_details_fragment.xml | 72 +++++++++---------- .../AddDevicePreferenceController.java | 3 +- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 8fb19cbc684..3218e0de25e 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -36,49 +36,45 @@ android:key="buttons" android:selectable="false" /> - - - + + - + - + - + - - + - - - - + + Date: Mon, 8 Apr 2019 15:46:57 -0400 Subject: [PATCH 03/22] Move NAS selection to 'special app access' Test: manual Fixes: 130169253 Change-Id: I0e69b11c557bc153cee0073bb2e982e3ee36e721 --- res/xml/configure_notification_settings.xml | 7 ------- res/xml/special_access.xml | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index 97a41822995..cf25a15557d 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -19,13 +19,6 @@ android:title="@string/configure_notification_settings" android:key="configure_notification_settings"> - - + + Date: Mon, 8 Apr 2019 13:55:58 -0700 Subject: [PATCH 04/22] Add null check in UserPreference The comparator can get null objects according to bug report. Fixes: 130144755 Test: manual Change-Id: Ic8a332d390f411d2eb69c944fb7fd166d9961535 --- .../settings/users/UserPreference.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/users/UserPreference.java b/src/com/android/settings/users/UserPreference.java index d87d78ecbaf..3603d44ea09 100644 --- a/src/com/android/settings/users/UserPreference.java +++ b/src/com/android/settings/users/UserPreference.java @@ -40,18 +40,22 @@ public class UserPreference extends RestrictedPreference { public static final int USERID_UNKNOWN = -10; public static final int USERID_GUEST_DEFAULTS = -11; public static final Comparator SERIAL_NUMBER_COMPARATOR = - new Comparator() { - @Override - public int compare(UserPreference p1, UserPreference p2) { - int sn1 = p1.getSerialNumber(); - int sn2 = p2.getSerialNumber(); - if (sn1 < sn2) { - return -1; - } else if (sn1 > sn2) { - return 1; - } - return 0; + (p1, p2) -> { + + if (p1 == null) { + return -1; } + else if (p2 == null) { + return 1; + } + int sn1 = p1.getSerialNumber(); + int sn2 = p2.getSerialNumber(); + if (sn1 < sn2) { + return -1; + } else if (sn1 > sn2) { + return 1; + } + return 0; }; private OnClickListener mDeleteClickListener; From 276edc8d86b2a5164619c1d3224abd9d056acdf7 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Mon, 8 Apr 2019 12:29:27 -0700 Subject: [PATCH 05/22] Do not retrive app detail if the fragment is exiting. The exit flag can be set by a variety of things, such as when package is removed, or package is invalid (hidden mainline module). Loading such packages changes the internal state of ApplicationsState class (an app singleton), which leads to inconsistencies later. Fixes: 130166465 Test: robotest Change-Id: Ib09240cb694fa16692914a7aa9ce354869615c2d --- .../applications/appinfo/AppInfoDashboardFragment.java | 7 ++++--- .../applications/appinfo/AppInfoDashboardFragmentTest.java | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 766fa50acc5..8274634a01f 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -112,7 +112,8 @@ public class AppInfoDashboardFragment extends DashboardFragment private UserManager mUserManager; private PackageManager mPm; - private boolean mFinishing; + @VisibleForTesting + boolean mFinishing; private boolean mListeningToPackageRemove; @@ -544,7 +545,7 @@ public class AppInfoDashboardFragment extends DashboardFragment @VisibleForTesting void retrieveAppEntry() { final Activity activity = getActivity(); - if (activity == null) { + if (activity == null || mFinishing) { return; } if (mState == null) { @@ -650,7 +651,7 @@ public class AppInfoDashboardFragment extends DashboardFragment || TextUtils.equals(mAppEntry.info.packageName, packageName)) { onPackageRemoved(); } else if (mAppEntry.info.isResourceOverlay() - && TextUtils.equals(mPackageInfo.overlayTarget, packageName)) { + && TextUtils.equals(mPackageInfo.overlayTarget, packageName)) { refreshUi(); } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java index 56e59f7bd0e..e46cd06afe6 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -281,6 +281,13 @@ public final class AppInfoDashboardFragmentTest { assertThat(mFragment.createPreferenceControllers(mShadowContext)).isNull(); } + @Test + public void getPreferenceControllers_exiting_shouldReturnNull() { + mFragment.mFinishing = true; + + assertThat(mFragment.createPreferenceControllers(mShadowContext)).isNull(); + } + @Test public void getNumberOfUserWithPackageInstalled_twoUsersInstalled_shouldReturnTwo() throws PackageManager.NameNotFoundException { From 2fa0b7ed85a441e7db353d0afe15ae9a52ec68a6 Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Mon, 8 Apr 2019 14:22:40 -0700 Subject: [PATCH 06/22] Treat mcx apn type as not wild-cardable. Test: manual Bug: 130167974 Change-Id: Ic3e643646491e5a187505fd54ca767ad91e285f5 --- src/com/android/settings/network/ApnEditor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/network/ApnEditor.java b/src/com/android/settings/network/ApnEditor.java index 4de402602ae..542a86952d9 100644 --- a/src/com/android/settings/network/ApnEditor.java +++ b/src/com/android/settings/network/ApnEditor.java @@ -1164,7 +1164,8 @@ public class ApnEditor extends SettingsPreferenceFragment // add APN type if it is not read-only and is not wild-cardable if (!readOnlyApnTypes.contains(apnType) && !apnType.equals(PhoneConstants.APN_TYPE_IA) - && !apnType.equals(PhoneConstants.APN_TYPE_EMERGENCY)) { + && !apnType.equals(PhoneConstants.APN_TYPE_EMERGENCY) + && !apnType.equals(PhoneConstants.APN_TYPE_MCX)) { if (first) { first = false; } else { From d3864daebdf69bbdc1a102ce9e214277c292a4a2 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Mon, 8 Apr 2019 15:23:01 -0700 Subject: [PATCH 07/22] Treat mode_default as denied for install_unknown_apps Test: atest SettingsRoboTests Bug: 123700348 Change-Id: Ieeb6456854cc3d0faa0e9c407accd94f56a25813 --- .../applications/AppStateInstallAppsBridge.java | 13 +++---------- .../applications/AppStateInstallAppsBridgeTest.java | 4 +++- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/applications/AppStateInstallAppsBridge.java b/src/com/android/settings/applications/AppStateInstallAppsBridge.java index f852bcab9a0..8a3e5a220d5 100644 --- a/src/com/android/settings/applications/AppStateInstallAppsBridge.java +++ b/src/com/android/settings/applications/AppStateInstallAppsBridge.java @@ -93,8 +93,6 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { final InstallAppsState appState = new InstallAppsState(); appState.permissionRequested = hasRequestedAppOpPermission( Manifest.permission.REQUEST_INSTALL_PACKAGES, packageName); - appState.permissionGranted = hasPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES, - uid); appState.appOpMode = getAppOpMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid, packageName); return appState; @@ -105,7 +103,6 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { */ public static class InstallAppsState { boolean permissionRequested; - boolean permissionGranted; int appOpMode; public InstallAppsState() { @@ -113,11 +110,7 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { } public boolean canInstallApps() { - if (appOpMode == AppOpsManager.MODE_DEFAULT) { - return permissionGranted; - } else { - return appOpMode == AppOpsManager.MODE_ALLOWED; - } + return appOpMode == AppOpsManager.MODE_ALLOWED; } public boolean isPotentialAppSource() { @@ -126,8 +119,8 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { @Override public String toString() { - StringBuilder sb = new StringBuilder("[permissionGranted: " + permissionGranted); - sb.append(", permissionRequested: " + permissionRequested); + StringBuilder sb = new StringBuilder(); + sb.append("[permissionRequested: " + permissionRequested); sb.append(", appOpMode: " + appOpMode); sb.append("]"); return sb.toString(); diff --git a/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java index 304dfe9735b..277f63e5745 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java @@ -33,8 +33,10 @@ public class AppStateInstallAppsBridgeTest { new AppStateInstallAppsBridge.InstallAppsState(); assertThat(appState.canInstallApps()).isFalse(); - appState.permissionGranted = true; appState.permissionRequested = true; + assertThat(appState.canInstallApps()).isFalse(); + + appState.appOpMode = AppOpsManager.MODE_ALLOWED; assertThat(appState.canInstallApps()).isTrue(); appState.appOpMode = AppOpsManager.MODE_ERRORED; From 4646fe8e63bc5d21c37960e8b6c4cb1bf8b1ae50 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Mon, 8 Apr 2019 13:42:14 -0700 Subject: [PATCH 08/22] Use active instead of available subscriptions in 2 places In a couple of places we were showing DSDS UI using the list of *available* subscriptions instead of the list of *active* ones. This difference is relevant for instance if you have multiple eSIM profiles - in typical hardware only one of those can be active at one time. This CL fixes that problem in two places: 1) The header at the top of the Network & internet page 2) The ListPreference's on the mobile network detail page for selecting the default subscription for Calls / SMS. Fixes: 129673046 Test: make RunSettingsRoboTests Change-Id: I891c856bdd4516286fcee1067684d9161ceaca80 --- .../settings/network/SubscriptionUtil.java | 25 +++++++++++--- .../SubscriptionsPreferenceController.java | 4 +-- .../DefaultSubscriptionController.java | 4 +-- .../network/SubscriptionUtilTest.java | 29 ++++++++++++++++ ...SubscriptionsPreferenceControllerTest.java | 34 +++++++++---------- .../DefaultSubscriptionControllerTest.java | 30 ++++++++-------- 6 files changed, 86 insertions(+), 40 deletions(-) diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java index 224fc41e0b9..5f1becaf54d 100644 --- a/src/com/android/settings/network/SubscriptionUtil.java +++ b/src/com/android/settings/network/SubscriptionUtil.java @@ -27,16 +27,33 @@ import java.util.Iterator; import java.util.List; public class SubscriptionUtil { - private static List sResultsForTesting; + private static List sAvailableResultsForTesting; + private static List sActiveResultsForTesting; @VisibleForTesting public static void setAvailableSubscriptionsForTesting(List results) { - sResultsForTesting = results; + sAvailableResultsForTesting = results; + } + + @VisibleForTesting + public static void setActiveSubscriptionsForTesting(List results) { + sActiveResultsForTesting = results; + } + + public static List getActiveSubscriptions(SubscriptionManager manager) { + if (sActiveResultsForTesting != null) { + return sActiveResultsForTesting; + } + List subscriptions = manager.getActiveSubscriptionInfoList(true); + if (subscriptions == null) { + return new ArrayList<>(); + } + return subscriptions; } public static List getAvailableSubscriptions(SubscriptionManager manager) { - if (sResultsForTesting != null) { - return sResultsForTesting; + if (sAvailableResultsForTesting != null) { + return sAvailableResultsForTesting; } List subscriptions = manager.getSelectableSubscriptionInfoList(); if (subscriptions == null) { diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java index 1ff67f8b307..88ff5cf247f 100644 --- a/src/com/android/settings/network/SubscriptionsPreferenceController.java +++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java @@ -129,7 +129,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl mSubscriptionPreferences = new ArrayMap<>(); int order = mStartOrder; - for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mManager)) { + for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mManager)) { final int subId = info.getSubscriptionId(); Preference pref = existingPrefs.remove(subId); if (pref == null) { @@ -216,7 +216,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl if (mSubscriptionsListener.isAirplaneModeOn()) { return false; } - return SubscriptionUtil.getAvailableSubscriptions(mManager).size() >= 2; + return SubscriptionUtil.getActiveSubscriptions(mManager).size() >= 2; } @Override diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java index e982a6ba2db..02a2d58c009 100644 --- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java +++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java @@ -75,7 +75,7 @@ public abstract class DefaultSubscriptionController extends BasePreferenceContro @Override public int getAvailabilityStatus() { - final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager); + final List subs = SubscriptionUtil.getActiveSubscriptions(mManager); if (subs.size() > 1) { return AVAILABLE; } else { @@ -121,7 +121,7 @@ public abstract class DefaultSubscriptionController extends BasePreferenceContro } mPreference.setVisible(true); - final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager); + final List subs = SubscriptionUtil.getActiveSubscriptions(mManager); // We'll have one entry for each available subscription, plus one for a "ask me every // time" entry at the end. diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java index dbc122a3256..c074466b789 100644 --- a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java +++ b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java @@ -18,6 +18,7 @@ package com.android.settings.network; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -108,4 +109,32 @@ public class SubscriptionUtilTest { assertThat(subs.get(0).getSubscriptionId()).isEqualTo(1); assertThat(subs.get(1).getSubscriptionId()).isEqualTo(4); } + + @Test + public void getActiveSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() { + when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null); + final List subs = SubscriptionUtil.getActiveSubscriptions(mManager); + assertThat(subs).isNotNull(); + assertThat(subs).isEmpty(); + } + + @Test + public void getActiveSubscriptions_oneSubscription_oneResult() { + final SubscriptionInfo info = mock(SubscriptionInfo.class); + when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info)); + final List subs = SubscriptionUtil.getActiveSubscriptions(mManager); + assertThat(subs).isNotNull(); + assertThat(subs).hasSize(1); + } + + @Test + public void getActiveSubscriptions_twoSubscriptions_twoResults() { + final SubscriptionInfo info1 = mock(SubscriptionInfo.class); + final SubscriptionInfo info2 = mock(SubscriptionInfo.class); + when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn( + Arrays.asList(info1, info2)); + final List subs = SubscriptionUtil.getActiveSubscriptions(mManager); + assertThat(subs).isNotNull(); + assertThat(subs).hasSize(2); + } } diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java index 97966b3420a..26f26ff5505 100644 --- a/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java @@ -103,19 +103,19 @@ public class SubscriptionsPreferenceControllerTest { @After public void tearDown() { - SubscriptionUtil.setAvailableSubscriptionsForTesting(null); + SubscriptionUtil.setActiveSubscriptionsForTesting(null); } @Test public void isAvailable_oneSubscription_availableFalse() { - SubscriptionUtil.setAvailableSubscriptionsForTesting( + SubscriptionUtil.setActiveSubscriptionsForTesting( Arrays.asList(mock(SubscriptionInfo.class))); assertThat(mController.isAvailable()).isFalse(); } @Test public void isAvailable_twoSubscriptions_availableTrue() { - SubscriptionUtil.setAvailableSubscriptionsForTesting( + SubscriptionUtil.setActiveSubscriptionsForTesting( Arrays.asList(mock(SubscriptionInfo.class), mock(SubscriptionInfo.class))); assertThat(mController.isAvailable()).isTrue(); } @@ -126,13 +126,13 @@ public class SubscriptionsPreferenceControllerTest { for (int i = 0; i < 5; i++) { subs.add(mock(SubscriptionInfo.class)); } - SubscriptionUtil.setAvailableSubscriptionsForTesting(subs); + SubscriptionUtil.setActiveSubscriptionsForTesting(subs); assertThat(mController.isAvailable()).isTrue(); } @Test public void isAvailable_airplaneModeOn_availableFalse() { - SubscriptionUtil.setAvailableSubscriptionsForTesting( + SubscriptionUtil.setActiveSubscriptionsForTesting( Arrays.asList(mock(SubscriptionInfo.class), mock(SubscriptionInfo.class))); assertThat(mController.isAvailable()).isTrue(); Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1); @@ -141,7 +141,7 @@ public class SubscriptionsPreferenceControllerTest { @Test public void onAirplaneModeChanged_airplaneModeTurnedOn_eventFired() { - SubscriptionUtil.setAvailableSubscriptionsForTesting( + SubscriptionUtil.setActiveSubscriptionsForTesting( Arrays.asList(mock(SubscriptionInfo.class), mock(SubscriptionInfo.class))); mController.onResume(); mController.displayPreference(mScreen); @@ -157,7 +157,7 @@ public class SubscriptionsPreferenceControllerTest { @Test public void onAirplaneModeChanged_airplaneModeTurnedOff_eventFired() { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1); - SubscriptionUtil.setAvailableSubscriptionsForTesting( + SubscriptionUtil.setActiveSubscriptionsForTesting( Arrays.asList(mock(SubscriptionInfo.class), mock(SubscriptionInfo.class))); mController.onResume(); mController.displayPreference(mScreen); @@ -174,13 +174,13 @@ public class SubscriptionsPreferenceControllerTest { public void onSubscriptionsChanged_countBecameTwo_eventFired() { final SubscriptionInfo sub1 = mock(SubscriptionInfo.class); final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1)); mController.onResume(); mController.displayPreference(mScreen); assertThat(mController.isAvailable()).isFalse(); final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount; - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isTrue(); assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1); @@ -192,14 +192,14 @@ public class SubscriptionsPreferenceControllerTest { final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); when(sub1.getSubscriptionId()).thenReturn(1); when(sub2.getSubscriptionId()).thenReturn(2); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); mController.onResume(); mController.displayPreference(mScreen); assertThat(mController.isAvailable()).isTrue(); verify(mPreferenceCategory, times(2)).addPreference(any(Preference.class)); final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount; - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isFalse(); assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1); @@ -221,7 +221,7 @@ public class SubscriptionsPreferenceControllerTest { when(sub3.getSubscriptionId()).thenReturn(3); // Start out with only sub1 and sub2. - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); mController.onResume(); mController.displayPreference(mScreen); final ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class); @@ -233,7 +233,7 @@ public class SubscriptionsPreferenceControllerTest { // Now replace sub2 with sub3, and make sure the old preference was removed and the new // preference was added. final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount; - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub3)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub3)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isTrue(); assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1); @@ -259,7 +259,7 @@ public class SubscriptionsPreferenceControllerTest { doReturn(i + 1).when(sub).getSubscriptionId(); subscriptions.add(sub); } - SubscriptionUtil.setAvailableSubscriptionsForTesting(subscriptions); + SubscriptionUtil.setActiveSubscriptionsForTesting(subscriptions); mController.displayPreference(mScreen); final ArgumentCaptor prefCaptor = ArgumentCaptor.forClass(Preference.class); verify(mPreferenceCategory, times(subscriptionCount)).addPreference(prefCaptor.capture()); @@ -303,7 +303,7 @@ public class SubscriptionsPreferenceControllerTest { final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); when(sub1.getSubscriptionId()).thenReturn(11); when(sub2.getSubscriptionId()).thenReturn(22); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); ShadowSubscriptionManager.setDefaultDataSubscriptionId(11); ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11); @@ -324,7 +324,7 @@ public class SubscriptionsPreferenceControllerTest { final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); when(sub1.getSubscriptionId()).thenReturn(11); when(sub2.getSubscriptionId()).thenReturn(22); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11); ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11); @@ -346,7 +346,7 @@ public class SubscriptionsPreferenceControllerTest { final SubscriptionInfo sub2 = mock(SubscriptionInfo.class); when(sub1.getSubscriptionId()).thenReturn(11); when(sub2.getSubscriptionId()).thenReturn(22); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); ShadowSubscriptionManager.setDefaultDataSubscriptionId(11); ShadowSubscriptionManager.setDefaultSmsSubscriptionId(22); diff --git a/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java index e503d70599d..7dd636a4ab8 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java @@ -73,19 +73,19 @@ public class DefaultSubscriptionControllerTest { @After public void tearDown() { - SubscriptionUtil.setAvailableSubscriptionsForTesting(null); + SubscriptionUtil.setActiveSubscriptionsForTesting(null); } @Test public void getAvailabilityStatus_onlyOneSubscription_notAvailable() { - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList( + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList( createMockSub(1, "sub1"))); assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); } @Test public void getAvailabilityStatus_twoSubscriptions_isAvailable() { - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList( + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList( createMockSub(1, "sub1"), createMockSub(2, "sub2"))); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); @@ -95,7 +95,7 @@ public class DefaultSubscriptionControllerTest { public void displayPreference_twoSubscriptionsSub1Default_correctListPreferenceValues() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -123,7 +123,7 @@ public class DefaultSubscriptionControllerTest { public void displayPreference_twoSubscriptionsSub2Default_correctListPreferenceValues() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub2.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -156,7 +156,7 @@ public class DefaultSubscriptionControllerTest { // Mark sub2 as opportunistic; then it should not appear in the list of entries/entryValues. when(sub2.isOpportunistic()).thenReturn(true); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -179,7 +179,7 @@ public class DefaultSubscriptionControllerTest { public void onPreferenceChange_prefChangedToSub2_callbackCalledCorrectly() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -192,7 +192,7 @@ public class DefaultSubscriptionControllerTest { public void onPreferenceChange_prefChangedToAlwaysAsk_callbackCalledCorrectly() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -207,7 +207,7 @@ public class DefaultSubscriptionControllerTest { public void onSubscriptionsChanged_twoSubscriptionsDefaultChanges_selectedEntryGetsUpdated() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); @@ -224,14 +224,14 @@ public class DefaultSubscriptionControllerTest { public void onSubscriptionsChanged_goFromTwoSubscriptionsToOne_prefDisappears() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); assertThat(mController.isAvailable()).isTrue(); assertThat(mListPreference.isVisible()).isTrue(); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isFalse(); @@ -242,14 +242,14 @@ public class DefaultSubscriptionControllerTest { public void onSubscriptionsChanged_goFromOneSubscriptionToTwo_prefAppears() { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); assertThat(mController.isAvailable()).isFalse(); assertThat(mListPreference.isVisible()).isFalse(); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isTrue(); @@ -261,13 +261,13 @@ public class DefaultSubscriptionControllerTest { final SubscriptionInfo sub1 = createMockSub(111, "sub1"); final SubscriptionInfo sub2 = createMockSub(222, "sub2"); final SubscriptionInfo sub3 = createMockSub(333, "sub3"); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2)); doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId(); mController.displayPreference(mScreen); assertThat(mListPreference.getEntries().length).isEqualTo(3); - SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3)); + SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3)); mController.onSubscriptionsChanged(); assertThat(mController.isAvailable()).isTrue(); From 4350317580b481fd0f98179ae4d7590924d9b4d0 Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Mon, 8 Apr 2019 16:16:20 -0700 Subject: [PATCH 09/22] Move bitmap recycle to onDestroy() If we recycle it in OnStop() and this page isn't destoried, it will crash when we revisit it. Fixes: 130185099 Test: RunSettingsRoboTests Change-Id: I4d3c1c12debcccb1ee7d676a1c5accece0b42e09 --- .../AdvancedBluetoothDetailsHeaderController.java | 9 ++++++++- ...AdvancedBluetoothDetailsHeaderControllerTest.java | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java index 1d2d793496a..9a651d207f2 100644 --- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java @@ -41,6 +41,7 @@ import com.android.settings.core.BasePreferenceController; import com.android.settings.fuelgauge.BatteryMeterView; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnDestroy; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.utils.ThreadUtils; @@ -54,7 +55,7 @@ import java.util.Map; * This class adds a header with device name and status (connected/disconnected, etc.). */ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceController implements - LifecycleObserver, OnStart, OnStop, CachedBluetoothDevice.Callback { + LifecycleObserver, OnStart, OnStop, OnDestroy, CachedBluetoothDevice.Callback { private static final String TAG = "AdvancedBtHeaderCtrl"; @VisibleForTesting @@ -118,7 +119,13 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont } mCachedDevice.unregisterCallback(this::onDeviceAttributesChanged); mBluetoothAdapter.unregisterMetadataListener(mCachedDevice.getDevice()); + } + @Override + public void onDestroy() { + if (!isAvailable()) { + return; + } // Destroy icon bitmap associated with this header for (Bitmap bitmap : mIconCache.values()) { if (bitmap != null) { diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java index b9616697099..3532bf89a54 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java @@ -209,6 +209,18 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{ verify(mBluetoothAdapter, never()).unregisterMetadataListener(mBluetoothDevice); } + @Test + public void onDestroy_isAvailable_recycleBitmap() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + .thenReturn("true"); + mController.mIconCache.put(ICON_URI, mBitmap); + + mController.onDestroy(); + + assertThat(mController.mIconCache).isEmpty(); + verify(mBitmap).recycle(); + } + private void assertBatteryLevel(LinearLayout linearLayout, int batteryLevel) { final TextView textView = linearLayout.findViewById(R.id.bt_battery_summary); assertThat(textView.getText().toString()).isEqualTo( From e82540f174ee01082980dbc847a1fd4bd490a434 Mon Sep 17 00:00:00 2001 From: pastychang Date: Tue, 2 Apr 2019 19:03:16 +0800 Subject: [PATCH 10/22] Add strings used for setupwizard lockscreen skip dialog Test: atest Bug: 124028212 Change-Id: I9f65022f6bbc70606a40b5b20e9484731376d203 --- res/values/strings.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4e1b32eeed4..aaf3bdcfa26 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1007,6 +1007,10 @@ Skip anyway Go back + + Skip + + Cancel Touch the sensor @@ -1037,6 +1041,24 @@ Skip fingerprint setup? You\u2019ve chosen to use your fingerprint as one way to unlock your phone. If you skip now, you\u2019ll need to set this up later. Setup takes only a minute or so. + + Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + + Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + + Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + + Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + + Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + + Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + + Skip PIN Setup? + + Skip Password Setup? + + Skip Pattern Setup? Set up screen lock From 6ef1eec2e28a94da93f4486c63544cb7e4f513c4 Mon Sep 17 00:00:00 2001 From: clownshen Date: Tue, 2 Apr 2019 19:28:56 +0800 Subject: [PATCH 11/22] Redraw WiFi detail page's header icon Tint 87% dark in day mode and 100% white for night mode Bug: 129413562 Test: make RunSettingsRoboTests -j32 ROBOTEST_FILTER=com.android.settings.wifi.details.WifiDetailPreferenceControllerTest Test: manual test Change-Id: Ia31231ca7871ac4efcea5e1232690ff4374df5b3 (cherry picked from commit 86f65ef488a5648399c1eb29d8e631c952d5dbf1) --- .../WifiDetailPreferenceController.java | 19 +++++++---- .../WifiDetailPreferenceControllerTest.java | 32 +++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 13905c8abbe..9b9f7fe6edf 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -449,8 +449,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController headerPref.findViewById(R.id.entity_header)); ImageView iconView = headerPref.findViewById(R.id.entity_header_icon); - iconView.setBackground( - mContext.getDrawable(R.drawable.ic_settings_widget_background)); + iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); mEntityHeaderController.setLabel(mAccessPoint.getTitle()); @@ -602,10 +601,9 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mRssiSignalLevel = signalLevel; Drawable wifiIcon = mIconInjector.getIcon(mRssiSignalLevel); - wifiIcon.setTintList(Utils.getColorAccent(mContext)); if (mEntityHeaderController != null) { mEntityHeaderController - .setIcon(rescaleIconForHeader(wifiIcon)).done(mFragment.getActivity(), + .setIcon(redrawIconForHeader(wifiIcon)).done(mFragment.getActivity(), true /* rebind */); } @@ -617,7 +615,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mSignalStrengthPref.setVisible(true); } - private Drawable rescaleIconForHeader(Drawable original) { + private Drawable redrawIconForHeader(Drawable original) { final int iconSize = mContext.getResources().getDimensionPixelSize( R.dimen.wifi_detail_page_header_image_size); final int actualWidth = original.getMinimumWidth(); @@ -628,10 +626,19 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController return original; } + // clear tint list to make sure can set 87% black after enlarge + original.setTintList(null); + + // enlarge icon size final Bitmap bitmap = Utils.createBitmap(original, iconSize /*width*/, iconSize /*height*/); - return new BitmapDrawable(null /*resource*/, bitmap); + Drawable newIcon = new BitmapDrawable(null /*resource*/, bitmap); + + // config color for 87% black after enlarge + newIcon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorPrimary)); + + return newIcon; } private void refreshFrequency() { diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 2166e979131..223e81be180 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -36,6 +36,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; @@ -69,6 +70,7 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.core.FeatureFlags; import com.android.settings.development.featureflags.FeatureFlagPersistent; +import com.android.settings.Utils; import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; import com.android.settings.testutils.shadow.ShadowEntityHeaderController; import com.android.settings.widget.EntityHeaderController; @@ -1458,6 +1460,36 @@ public class WifiDetailPreferenceControllerTest { verify(mockSignalStrengthPref, times(2)).setVisible(false); } + @Test + public void testRedrawIconForHeader_shouldEnlarge() { + ArgumentCaptor drawableCaptor = + ArgumentCaptor.forClass(BitmapDrawable.class); + Drawable original = mContext.getDrawable(Utils.getWifiIconResource(LEVEL)).mutate(); + when(mockIconInjector.getIcon(anyInt())).thenReturn(original); + + displayAndResume(); + + verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture()); + + int expectedSize = mContext.getResources().getDimensionPixelSize( + R.dimen.wifi_detail_page_header_image_size); + BitmapDrawable icon = drawableCaptor.getValue(); + assertThat(icon.getMinimumWidth()).isEqualTo(expectedSize); + assertThat(icon.getMinimumHeight()).isEqualTo(expectedSize); + } + + @Test + public void testRedrawIconForHeader_shouldNotEnlargeIfNotVectorDrawable() { + ArgumentCaptor drawableCaptor = + ArgumentCaptor.forClass(ColorDrawable.class); + + displayAndResume(); + + verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture()); + ColorDrawable icon = drawableCaptor.getValue(); + assertThat(icon).isNotNull(); + } + private ActionButtonsPreference createMock() { final ActionButtonsPreference pref = mock(ActionButtonsPreference.class); when(pref.setButton1Text(anyInt())).thenReturn(pref); From 4a5ff585116d9a1d1f0db494b3af554269493958 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 3 Apr 2019 18:45:22 +0800 Subject: [PATCH 12/22] Supports to share Wi-Fi networks of WPA3 security SAE & OWE via QR code generator When scanned a no password ZXing QR code, add both open network & enhanced open network to configured Wi-Fi network list because this kind of QR code may refer to a open network or an enhanced open network. Bug: 124131581 Test: manual Change-Id: Id9f85ef8dcdf72347be8106938437aecd0eed9f5 --- .../WifiDetailPreferenceController.java | 3 +- .../dpp/WifiDppQrCodeScannerFragment.java | 116 ++++++++++-------- .../settings/wifi/dpp/WifiDppUtils.java | 52 +++++--- .../settings/wifi/dpp/WifiNetworkConfig.java | 86 +++++++++---- .../android/settings/wifi/dpp/WifiQrCode.java | 4 +- .../settings/wifi/dpp/WifiQrCodeTest.java | 28 ++++- 6 files changed, 192 insertions(+), 97 deletions(-) diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 13905c8abbe..cbb91a210d9 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -409,7 +409,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController .setButton4Text(R.string.share) .setButton4Icon(R.drawable.ic_qrcode_24dp) .setButton4OnClickListener(view -> shareNetwork()) - .setButton4Visible(WifiDppUtils.isSupportConfiguratorQrCodeGenerator(mAccessPoint)); + .setButton4Visible( + WifiDppUtils.isSupportConfiguratorQrCodeGenerator(mContext, mAccessPoint)); mSignalStrengthPref = screen.findPreference(KEY_SIGNAL_STRENGTH_PREF); mTxLinkSpeedPref = screen.findPreference(KEY_TX_LINK_SPEED); diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java index 21920d2d5dc..fa17f073803 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java +++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java @@ -46,6 +46,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.StringRes; +import androidx.annotation.UiThread; import androidx.lifecycle.ViewModelProviders; import com.android.settings.R; @@ -57,6 +58,7 @@ import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.WifiTracker; import com.android.settingslib.wifi.WifiTrackerFactory; +import java.util.ArrayList; import java.util.List; public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements @@ -104,7 +106,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl private WifiQrCode mWifiQrCode; /** The WifiConfiguration connecting for enrollee usage */ - private WifiConfiguration mWifiConfiguration; + private WifiConfiguration mEnrolleeWifiConfiguration; private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE; @@ -140,14 +142,8 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl break; case MESSAGE_SCAN_WIFI_DPP_SUCCESS: - if (mCamera != null) { - mCamera.stop(); - } - - mDecorateView.setFocused(true); - mErrorMessage.setVisibility(View.INVISIBLE); - if (mScanWifiDppSuccessListener == null) { + // mScanWifiDppSuccessListener may be null after onDetach(), do nothing here return; } mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj); @@ -160,23 +156,43 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } - WifiDppUtils.triggerVibrationForQrCodeRecognition(getContext()); + notifyUserForQrCodeRecognition(); break; case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS: - if (mCamera != null) { - mCamera.stop(); + // We may get 2 WifiConfiguration if the QR code has no password in it, + // one for open network and one for enhanced open network. + final WifiManager wifiManager = + getContext().getSystemService(WifiManager.class); + final WifiNetworkConfig qrCodeWifiNetworkConfig = + (WifiNetworkConfig)msg.obj; + final List qrCodeWifiConfigurations = + qrCodeWifiNetworkConfig.getWifiConfigurations(); + + // Adds all Wi-Fi networks in QR code to the set of configured networks and + // connects to it if it's reachable. + boolean hasReachableWifiNetwork = false; + for (WifiConfiguration qrCodeWifiConfiguration : qrCodeWifiConfigurations) { + final int id = wifiManager.addNetwork(qrCodeWifiConfiguration); + if (id == -1) { + continue; + } + wifiManager.enableNetwork(id, /* attemptConnect */ false); + if (isReachableWifiNetwork(qrCodeWifiConfiguration)) { + hasReachableWifiNetwork = true; + mEnrolleeWifiConfiguration = qrCodeWifiConfiguration; + wifiManager.connect(id, + /* listener */ WifiDppQrCodeScannerFragment.this); + } } - mDecorateView.setFocused(true); - mErrorMessage.setVisibility(View.INVISIBLE); + if (hasReachableWifiNetwork == false) { + showErrorMessageAndRestartCamera( + R.string.wifi_dpp_check_connection_try_again); + return; + } - final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj; - mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull(); - wifiNetworkConfig.connect(getContext(), - /* listener */ WifiDppQrCodeScannerFragment.this); - - WifiDppUtils.triggerVibrationForQrCodeRecognition(getContext()); + notifyUserForQrCodeRecognition(); break; default: @@ -185,6 +201,30 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl } }; + @UiThread + private void notifyUserForQrCodeRecognition() { + if (mCamera != null) { + mCamera.stop(); + } + + mDecorateView.setFocused(true); + mErrorMessage.setVisibility(View.INVISIBLE); + + WifiDppUtils.triggerVibrationForQrCodeRecognition(getContext()); + } + + private boolean isReachableWifiNetwork(WifiConfiguration wifiConfiguration) { + final List scannedAccessPoints = mWifiTracker.getAccessPoints(); + + for (AccessPoint scannedAccessPoint : scannedAccessPoints) { + if (scannedAccessPoint.matches(wifiConfiguration) && + scannedAccessPoint.isReachable()) { + return true; + } + } + return false; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -192,7 +232,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl if (savedInstanceState != null) { mIsConfiguratorMode = savedInstanceState.getBoolean(KEY_IS_CONFIGURATOR_MODE); mLatestStatusCode = savedInstanceState.getInt(KEY_LATEST_ERROR_CODE); - mWifiConfiguration = savedInstanceState.getParcelable(KEY_WIFI_CONFIGURATION); + mEnrolleeWifiConfiguration = savedInstanceState.getParcelable(KEY_WIFI_CONFIGURATION); } final WifiDppInitiatorViewModel model = @@ -480,7 +520,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl public void onSaveInstanceState(Bundle outState) { outState.putBoolean(KEY_IS_CONFIGURATOR_MODE, mIsConfiguratorMode); outState.putInt(KEY_LATEST_ERROR_CODE, mLatestStatusCode); - outState.putParcelable(KEY_WIFI_CONFIGURATION, mWifiConfiguration); + outState.putParcelable(KEY_WIFI_CONFIGURATION, mEnrolleeWifiConfiguration); super.onSaveInstanceState(outState); } @@ -496,7 +536,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl for (WifiConfiguration wifiConfig : wifiConfigs) { if (wifiConfig.networkId == newNetworkId) { mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_SUCCESS; - mWifiConfiguration = wifiConfig; + mEnrolleeWifiConfiguration = wifiConfig; wifiManager.connect(wifiConfig, WifiDppQrCodeScannerFragment.this); return; } @@ -588,17 +628,13 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl @Override public void onSuccess() { - if (isEnrollingWifiNetworkReachable()) { - final Intent resultIntent = new Intent(); - resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration); + final Intent resultIntent = new Intent(); + resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, + mEnrolleeWifiConfiguration); - final Activity hostActivity = getActivity(); - hostActivity.setResult(Activity.RESULT_OK, resultIntent); - hostActivity.finish(); - } else { - Log.d(TAG, "Enroll Wi-Fi network succeeded but it's not reachable"); - showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again); - } + final Activity hostActivity = getActivity(); + hostActivity.setResult(Activity.RESULT_OK, resultIntent); + hostActivity.finish(); } @Override @@ -607,22 +643,6 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again); } - private boolean isEnrollingWifiNetworkReachable() { - if (mWifiConfiguration == null) { - Log.e(TAG, "Connect succeeded but lost WifiConfiguration"); - return false; - } - - final List scannedAccessPoints = mWifiTracker.getAccessPoints(); - for (AccessPoint accessPoint : scannedAccessPoints) { - if (accessPoint.matches(mWifiConfiguration) && - accessPoint.isReachable()) { - return true; - } - } - return false; - } - // Check is Easy Connect handshaking or not private boolean isGoingInitiator() { final WifiDppInitiatorViewModel model = diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java index 2ec3137c27c..695de76fffb 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java +++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java @@ -162,6 +162,9 @@ public class WifiDppUtils { if (config.allowedKeyManagement.get(KeyMgmt.SAE)) { return WifiQrCode.SECURITY_SAE; } + if (config.allowedKeyManagement.get(KeyMgmt.OWE)) { + return WifiQrCode.SECURITY_NO_PASSWORD; + } if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK) || config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { return WifiQrCode.SECURITY_WPA_PSK; @@ -185,7 +188,7 @@ public class WifiDppUtils { public static Intent getConfiguratorQrCodeGeneratorIntentOrNull(Context context, WifiManager wifiManager, AccessPoint accessPoint) { final Intent intent = new Intent(context, WifiDppConfiguratorActivity.class); - if (isSupportConfiguratorQrCodeGenerator(accessPoint)) { + if (isSupportConfiguratorQrCodeGenerator(context, accessPoint)) { intent.setAction(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR); } else { return null; @@ -343,22 +346,24 @@ public class WifiDppUtils { /** * Checks if QR code generator supports to config other devices with the Wi-Fi network * + * @param context The context to use for {@code WifiManager} * @param accessPoint The {@link AccessPoint} of the Wi-Fi network */ - public static boolean isSupportConfiguratorQrCodeGenerator(AccessPoint accessPoint) { - return isSupportZxing(accessPoint.getSecurity()); + public static boolean isSupportConfiguratorQrCodeGenerator(Context context, + AccessPoint accessPoint) { + return isSupportZxing(context, accessPoint.getSecurity()); } /** * Checks if this device supports to be configured by the Wi-Fi network of the security * - * @param context The context to use for {@link WifiManager#isEasyConnectSupported()} + * @param context The context to use for {@code WifiManager} * @param accesspointSecurity The security constants defined in {@link AccessPoint} */ public static boolean isSupportEnrolleeQrCodeScanner(Context context, int accesspointSecurity) { return isSupportWifiDpp(context, accesspointSecurity) || - isSupportZxing(accesspointSecurity); + isSupportZxing(context, accesspointSecurity); } private static boolean isSupportHotspotConfiguratorQrCodeGenerator( @@ -376,19 +381,38 @@ public class WifiDppUtils { } // DPP 1.0 only supports SAE and PSK. - if (accesspointSecurity == AccessPoint.SECURITY_SAE || - accesspointSecurity == AccessPoint.SECURITY_PSK) { - return true; + final WifiManager wifiManager = context.getSystemService(WifiManager.class); + switch (accesspointSecurity) { + case AccessPoint.SECURITY_SAE: + if (wifiManager.isWpa3SaeSupported()) { + return true; + } + break; + case AccessPoint.SECURITY_PSK: + return true; + default: } return false; } - // TODO (b/124131581 b/129396816): TO support WPA3 securities (SAE & OWE), change here at first - private static boolean isSupportZxing(int accesspointSecurity) { - if (accesspointSecurity == AccessPoint.SECURITY_PSK || - accesspointSecurity == AccessPoint.SECURITY_WEP || - accesspointSecurity == AccessPoint.SECURITY_NONE) { - return true; + private static boolean isSupportZxing(Context context, int accesspointSecurity) { + final WifiManager wifiManager = context.getSystemService(WifiManager.class); + switch (accesspointSecurity) { + case AccessPoint.SECURITY_PSK: + case AccessPoint.SECURITY_WEP: + case AccessPoint.SECURITY_NONE: + return true; + case AccessPoint.SECURITY_SAE: + if (wifiManager.isWpa3SaeSupported()) { + return true; + } + break; + case AccessPoint.SECURITY_OWE: + if (wifiManager.isEnhancedOpenSupported()) { + return true; + } + break; + default: } return false; } diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java index fdc74d87b0f..74235612860 100644 --- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java +++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java @@ -32,6 +32,9 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import java.util.ArrayList; +import java.util.List; + /** * Wraps the parameters of ZXing reader library's Wi-Fi Network config format. * Please check {@code WifiQrCode} for detail of the format. @@ -203,50 +206,63 @@ public class WifiNetworkConfig { return mIsHotspot; } - public void connect(Context context, WifiManager.ActionListener listener) { - WifiConfiguration wifiConfiguration = getWifiConfigurationOrNull(); - if (wifiConfiguration == null) { - if (listener != null) { - listener.onFailure(WifiManager.ERROR); - } - return; - } - - WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); - wifiManager.connect(wifiConfiguration, listener); - } - public boolean isSupportWifiDpp(Context context) { if (!WifiDppUtils.isWifiDppEnabled(context)) { return false; } - // DPP 1.0 only supports SAE and PSK. - if (SECURITY_SAE.equals(mSecurity) || SECURITY_WPA_PSK.equals(mSecurity)) { - return true; + if (TextUtils.isEmpty(mSecurity)) { + return false; } + // DPP 1.0 only supports SAE and PSK. + final WifiManager wifiManager = context.getSystemService(WifiManager.class); + switch (mSecurity) { + case SECURITY_SAE: + if (wifiManager.isWpa3SaeSupported()) { + return true; + } + break; + case SECURITY_WPA_PSK: + return true; + default: + } return false; } /** * This is a simplified method from {@code WifiConfigController.getConfig()} + * + * TODO (b/129021867): WifiConfiguration is a deprecated class, should replace it with + * {@code android.net.wifi.WifiNetworkSuggestion} + * + * @return When it's a open network, returns 2 WifiConfiguration in the List, the 1st is + * open network and the 2nd is enhanced open network. Returns 1 WifiConfiguration in the + * List for all other supported Wi-Fi securities. */ - WifiConfiguration getWifiConfigurationOrNull() { - if (!isValidConfig(this)) { - return null; - } + List getWifiConfigurations() { + final List wifiConfigurations = new ArrayList<>(); - final WifiConfiguration wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = addQuotationIfNeeded(mSsid); - wifiConfiguration.hiddenSSID = mHiddenSsid; - wifiConfiguration.networkId = mNetworkId; + if (!isValidConfig(this)) { + return wifiConfigurations; + } if (TextUtils.isEmpty(mSecurity) || SECURITY_NO_PASSWORD.equals(mSecurity)) { - wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE); - return wifiConfiguration; + // TODO (b/129835824): we add both open network and enhanced open network to WifiManager + // for android Q, should improve it in the future. + final WifiConfiguration openNetworkWifiConfiguration = getBasicWifiConfiguration(); + openNetworkWifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE); + wifiConfigurations.add(openNetworkWifiConfiguration); + + final WifiConfiguration enhancedOpenNetworkWifiConfiguration = + getBasicWifiConfiguration(); + enhancedOpenNetworkWifiConfiguration.allowedKeyManagement.set(KeyMgmt.OWE); + enhancedOpenNetworkWifiConfiguration.requirePMF = true; + wifiConfigurations.add(enhancedOpenNetworkWifiConfiguration); + return wifiConfigurations; } + final WifiConfiguration wifiConfiguration = getBasicWifiConfiguration(); if (mSecurity.startsWith(SECURITY_WEP)) { wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE); wifiConfiguration.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); @@ -268,11 +284,27 @@ public class WifiNetworkConfig { } else { wifiConfiguration.preSharedKey = addQuotationIfNeeded(mPreSharedKey); } + } else if (mSecurity.startsWith(SECURITY_SAE)) { + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.SAE); + wifiConfiguration.requirePMF = true; + if (mPreSharedKey.length() != 0) { + wifiConfiguration.preSharedKey = addQuotationIfNeeded(mPreSharedKey); + } } else { Log.w(TAG, "Unsupported security"); - return null; + return wifiConfigurations; } + wifiConfigurations.add(wifiConfiguration); + return wifiConfigurations; + } + + private WifiConfiguration getBasicWifiConfiguration() { + final WifiConfiguration wifiConfiguration = new WifiConfiguration(); + + wifiConfiguration.SSID = addQuotationIfNeeded(mSsid); + wifiConfiguration.hiddenSSID = mHiddenSsid; + wifiConfiguration.networkId = mNetworkId; return wifiConfiguration; } diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java index 8296a627de2..40ae111343d 100644 --- a/src/com/android/settings/wifi/dpp/WifiQrCode.java +++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java @@ -64,10 +64,10 @@ public class WifiQrCode { public static final String DELIMITER_QR_CODE = ";"; // Ignores password if security is SECURITY_NO_PASSWORD or absent - public static final String SECURITY_NO_PASSWORD = "nopass"; + public static final String SECURITY_NO_PASSWORD = "nopass"; //open network or OWE public static final String SECURITY_WEP = "WEP"; public static final String SECURITY_WPA_PSK = "WPA"; - public static final String SECURITY_SAE = "WPA3"; + public static final String SECURITY_SAE = "SAE"; private String mQrCode; diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java index 3595597160b..e4d3a7bb16c 100644 --- a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java @@ -41,9 +41,13 @@ public class WifiQrCodeTest { "SN=4774LH2b4044"; // Valid ZXing reader library's Wi-Fi Network config format & it's parameters - private static final String VALID_ZXING_WIFI_QR_CODE = + private static final String VALID_ZXING_WIFI_QR_CODE_WPA = "WIFI:T:WPA;S:mynetwork;P:mypass;H:true;;"; + // Valid ZXing reader library's Wi-Fi Network config format - security type SAE + private static final String VALID_ZXING_WIFI_QR_CODE_SAE = + "WIFI:T:SAE;S:mynetwork;P:mypass;H:true;;"; + // Valid ZXing reader library's Wi-Fi Network config format - security type nopass and no password private static final String VALID_ZXING_WIFI_QR_CODE_NOPASS_AND_NO_PASSWORD = "WIFI:T:nopass;S:mynetwork;;"; @@ -52,7 +56,8 @@ public class WifiQrCodeTest { private static final String VALID_ZXING_WIFI_QR_CODE_NO_SECURITY_AND_NO_PASSWORD = "WIFI:T:;S:mynetwork;P:;H:false;;"; - private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE = "WPA"; + private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA = "WPA"; + private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE = "SAE"; private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_NOPASS = "nopass"; private static final String SSID_OF_VALID_ZXING_WIFI_QR_CODE = "mynetwork"; private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE = "mypass"; @@ -94,12 +99,25 @@ public class WifiQrCodeTest { @Test public void parseValidZxingWifiQrCode() { - WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE); + WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_WPA); WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig(); assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme()); assertNotNull(config); - assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE, config.getSecurity()); + assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity()); + assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid()); + assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey()); + assertEquals(true, config.getHiddenSsid()); + } + + @Test + public void parseValidZxingWifiQrCodeSae() { + WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SAE); + WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig(); + + assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme()); + assertNotNull(config); + assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE, config.getSecurity()); assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid()); assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey()); assertEquals(true, config.getHiddenSsid()); @@ -138,7 +156,7 @@ public class WifiQrCodeTest { assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme()); assertNotNull(config); - assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE, config.getSecurity()); + assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity()); assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid()); assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS, config.getPreSharedKey()); From 470ec69461cd789a0e541ca00dbcf44249c3424c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Sat, 6 Apr 2019 16:21:32 +0800 Subject: [PATCH 13/22] Move default payment app to special app access. Bug: 124452117 Bug: 124522992 Test: build Change-Id: I58e7127920d939dc3635bcc2e608cee6baa21998 --- res/xml/app_default_settings.xml | 7 -- res/xml/special_access.xml | 7 ++ .../applications/DefaultAppSettings.java | 2 - ...ltPaymentSettingsPreferenceController.java | 80 ------------------- ...ltPaymentSettingsPreferenceController.java | 55 +++++++++++++ ...ymentSettingsPreferenceControllerTest.java | 31 +------ 6 files changed, 65 insertions(+), 117 deletions(-) delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultPaymentSettingsPreferenceController.java create mode 100644 src/com/android/settings/applications/specialaccess/DefaultPaymentSettingsPreferenceController.java rename tests/robotests/src/com/android/settings/applications/{defaultapps => specialaccess}/DefaultPaymentSettingsPreferenceControllerTest.java (70%) diff --git a/res/xml/app_default_settings.xml b/res/xml/app_default_settings.xml index 1f1b24a94ce..c6fde399ef0 100644 --- a/res/xml/app_default_settings.xml +++ b/res/xml/app_default_settings.xml @@ -54,13 +54,6 @@ android:fragment="com.android.settings.applications.defaultapps.DefaultSmsPicker" settings:keywords="@string/keywords_more_default_sms_app" /> - - + + Date: Sat, 6 Apr 2019 15:45:42 +0800 Subject: [PATCH 14/22] Remove old default apps code and use roles instead. Default apps are moved into PermissionController. Bug: 124452117 Bug: 124457823 Test: presubmit & manual Change-Id: I5f68e5b77cd6163d093590185314270706d75391 --- AndroidManifest.xml | 24 -- res/values/config.xml | 3 - res/values/strings.xml | 10 - res/xml/app_and_notification.xml | 8 + res/xml/app_default_settings.xml | 106 -------- res/xml/default_assist_settings.xml | 20 -- res/xml/default_browser_settings.xml | 20 -- res/xml/default_emergency_settings.xml | 20 -- res/xml/default_home_settings.xml | 20 -- res/xml/default_phone_settings.xml | 20 -- res/xml/default_sms_settings.xml | 20 -- src/com/android/settings/Settings.java | 1 - .../applications/DefaultAppSettings.java | 156 ------------ ...a => DefaultAppsPreferenceController.java} | 40 +-- .../defaultapps/DefaultBrowserPicker.java | 74 ------ .../DefaultBrowserPreferenceController.java | 198 --------------- .../defaultapps/DefaultEmergencyPicker.java | 115 --------- .../DefaultEmergencyPreferenceController.java | 79 ------ .../defaultapps/DefaultHomePicker.java | 152 ------------ .../DefaultHomePreferenceController.java | 129 ---------- .../defaultapps/DefaultPhonePicker.java | 111 --------- .../DefaultPhonePreferenceController.java | 85 ------- .../defaultapps/DefaultSmsPicker.java | 106 -------- .../DefaultSmsPreferenceController.java | 71 ------ ...efaultWorkBrowserPreferenceController.java | 50 ---- .../DefaultWorkPhonePreferenceController.java | 49 ---- .../ManageApplications.java | 10 +- .../core/gateway/SettingsGateway.java | 3 - .../dashboard/DashboardFragmentRegistry.java | 3 - tests/robotests/res/values-mcc999/config.xml | 1 - .../applications/DefaultAppSettingsTest.java | 174 ------------- ... DefaultAppsPreferenceControllerTest.java} | 134 ++-------- .../defaultapps/DefaultBrowserPickerTest.java | 77 ------ ...efaultBrowserPreferenceControllerTest.java | 231 ------------------ .../DefaultEmergencyPickerTest.java | 97 -------- .../defaultapps/DefaultHomePickerTest.java | 168 ------------- .../DefaultHomePreferenceControllerTest.java | 170 ------------- .../defaultapps/DefaultPhonePickerTest.java | 104 -------- .../defaultapps/DefaultSmsPickerTest.java | 94 ------- 39 files changed, 36 insertions(+), 2917 deletions(-) delete mode 100644 res/xml/app_default_settings.xml delete mode 100644 res/xml/default_assist_settings.xml delete mode 100644 res/xml/default_browser_settings.xml delete mode 100644 res/xml/default_emergency_settings.xml delete mode 100644 res/xml/default_home_settings.xml delete mode 100644 res/xml/default_phone_settings.xml delete mode 100644 res/xml/default_sms_settings.xml delete mode 100644 src/com/android/settings/applications/DefaultAppSettings.java rename src/com/android/settings/applications/{defaultapps/RolesPreferenceController.java => DefaultAppsPreferenceController.java} (67%) delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultEmergencyPicker.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultEmergencyPreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultHomePicker.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultPhonePreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultWorkBrowserPreferenceController.java delete mode 100644 src/com/android/settings/applications/defaultapps/DefaultWorkPhonePreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/applications/DefaultAppSettingsTest.java rename tests/robotests/src/com/android/settings/applications/{defaultapps/RolesPreferenceControllerTest.java => DefaultAppsPreferenceControllerTest.java} (51%) delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 68a7cbb1f03..6d3c207fb55 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2819,30 +2819,6 @@ - - - - - - - - - - - - - - - - true - - true - true diff --git a/res/values/strings.xml b/res/values/strings.xml index 4e1b32eeed4..468eecd4a9a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7160,10 +7160,8 @@ Flashlight, Light, Torch wifi, wi-fi, toggle, control - text message, texting, messages, messaging, default cellular, mobile, cell carrier, wireless, data, 4g,3g, 2g, lte wifi, wi-fi, call, calling - launcher, default, apps screen, touchscreen dim screen, touchscreen, battery, bright dim screen, night, tint, night shift, brightness, screen color, colour, color @@ -7188,8 +7186,6 @@ restriction, restrict, restricted text correction, correct, sound, vibrate, auto, language, gesture, suggest, suggestion, theme, offensive, word, type, emoji, international reset, preferences, default - emergency, ice, app, default - phone, dialer, default apps, download, applications, system apps, permissions, security apps, default @@ -7261,15 +7257,9 @@ default, assistant - - default, default browser - payment, default - - default - incoming notification diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml index fd3725af795..cdeb35eb0e0 100644 --- a/res/xml/app_and_notification.xml +++ b/res/xml/app_and_notification.xml @@ -50,6 +50,14 @@ android:key="dashboard_tile_placeholder" android:order="10"/> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/default_assist_settings.xml b/res/xml/default_assist_settings.xml deleted file mode 100644 index e1f59008558..00000000000 --- a/res/xml/default_assist_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/res/xml/default_browser_settings.xml b/res/xml/default_browser_settings.xml deleted file mode 100644 index a319a7cc4a7..00000000000 --- a/res/xml/default_browser_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/res/xml/default_emergency_settings.xml b/res/xml/default_emergency_settings.xml deleted file mode 100644 index db418ebb786..00000000000 --- a/res/xml/default_emergency_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/res/xml/default_home_settings.xml b/res/xml/default_home_settings.xml deleted file mode 100644 index 136f8cc77b4..00000000000 --- a/res/xml/default_home_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/res/xml/default_phone_settings.xml b/res/xml/default_phone_settings.xml deleted file mode 100644 index 1ae3ab12b54..00000000000 --- a/res/xml/default_phone_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/res/xml/default_sms_settings.xml b/res/xml/default_sms_settings.xml deleted file mode 100644 index 0a8bcc3231b..00000000000 --- a/res/xml/default_sms_settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index e1c9aff8949..90ffc5ad029 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -136,7 +136,6 @@ public class Settings extends SettingsActivity { public static class ChangeWifiStateActivity extends SettingsActivity { /* empty */ } public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ } public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ } - public static class AdvancedAppsActivity extends SettingsActivity { /* empty */ } public static class ManageExternalSourcesActivity extends SettingsActivity {/* empty */ } public static class ManageAppExternalSourcesActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/applications/DefaultAppSettings.java b/src/com/android/settings/applications/DefaultAppSettings.java deleted file mode 100644 index ca48369e62f..00000000000 --- a/src/com/android/settings/applications/DefaultAppSettings.java +++ /dev/null @@ -1,156 +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.applications; - -import android.app.Activity; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.icu.text.ListFormatter; -import android.provider.SearchIndexableResource; -import android.text.TextUtils; - -import com.android.settings.R; -import com.android.settings.applications.assist.DefaultAssistPreferenceController; -import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController; -import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController; -import com.android.settings.applications.defaultapps.DefaultHomePreferenceController; -import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController; -import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController; -import com.android.settings.applications.defaultapps.DefaultWorkBrowserPreferenceController; -import com.android.settings.applications.defaultapps.DefaultWorkPhonePreferenceController; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.dashboard.SummaryLoader; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settings.widget.PreferenceCategoryController; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.search.SearchIndexable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@SearchIndexable -public class DefaultAppSettings extends DashboardFragment { - - static final String TAG = "DefaultAppSettings"; - - private static final String KEY_DEFAULT_WORK_CATEGORY = "work_app_defaults"; - private static final String KEY_ASSIST_VOICE_INPUT = "assist_and_voice_input"; - - @Override - protected String getLogTag() { - return TAG; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.app_default_settings; - } - - @Override - protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.APPLICATIONS_ADVANCED; - } - - private static List buildPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - final List workControllers = new ArrayList<>(); - workControllers.add(new DefaultWorkPhonePreferenceController(context)); - workControllers.add(new DefaultWorkBrowserPreferenceController(context)); - controllers.addAll(workControllers); - controllers.add(new PreferenceCategoryController( - context, KEY_DEFAULT_WORK_CATEGORY).setChildren(workControllers)); - controllers.add(new DefaultAssistPreferenceController(context, KEY_ASSIST_VOICE_INPUT, - false /* showSetting */)); - controllers.add(new DefaultBrowserPreferenceController(context)); - controllers.add(new DefaultPhonePreferenceController(context)); - controllers.add(new DefaultSmsPreferenceController(context)); - controllers.add(new DefaultEmergencyPreferenceController(context)); - controllers.add(new DefaultHomePreferenceController(context)); - return controllers; - } - - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getXmlResourcesToIndex( - Context context, boolean enabled) { - final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = R.xml.app_default_settings; - return Arrays.asList(sir); - } - - @Override - public List createPreferenceControllers( - Context context) { - return buildPreferenceControllers(context); - } - }; - - static class SummaryProvider implements SummaryLoader.SummaryProvider { - - private final Context mContext; - private final SummaryLoader mSummaryLoader; - private final DefaultSmsPreferenceController mDefaultSmsPreferenceController; - private final DefaultBrowserPreferenceController mDefaultBrowserPreferenceController; - private final DefaultPhonePreferenceController mDefaultPhonePreferenceController; - - public SummaryProvider(Context context, SummaryLoader summaryLoader) { - mContext = context; - mSummaryLoader = summaryLoader; - mDefaultSmsPreferenceController = new DefaultSmsPreferenceController(mContext); - mDefaultBrowserPreferenceController = new DefaultBrowserPreferenceController(mContext); - mDefaultPhonePreferenceController = new DefaultPhonePreferenceController(mContext); - } - - @Override - public void setListening(boolean listening) { - if (!listening) { - return; - } - final List summaries = new ArrayList<>(); - if(!TextUtils.isEmpty(mDefaultBrowserPreferenceController.getDefaultAppLabel())) { - summaries.add(mDefaultBrowserPreferenceController.getDefaultAppLabel()); - } - if(!TextUtils.isEmpty(mDefaultPhonePreferenceController.getDefaultAppLabel())) { - summaries.add(mDefaultPhonePreferenceController.getDefaultAppLabel()); - } - if(!TextUtils.isEmpty(mDefaultSmsPreferenceController.getDefaultAppLabel())) { - summaries.add(mDefaultSmsPreferenceController.getDefaultAppLabel()); - } - - CharSequence summary = ListFormatter.getInstance().format(summaries); - if (!TextUtils.isEmpty(summary)) { - mSummaryLoader.setSummary(this, summary); - } - } - } - - public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY = - new SummaryLoader.SummaryProviderFactory() { - @Override - public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity, - SummaryLoader summaryLoader) { - return new DefaultAppSettings.SummaryProvider(activity, summaryLoader); - } - }; -} diff --git a/src/com/android/settings/applications/defaultapps/RolesPreferenceController.java b/src/com/android/settings/applications/DefaultAppsPreferenceController.java similarity index 67% rename from src/com/android/settings/applications/defaultapps/RolesPreferenceController.java rename to src/com/android/settings/applications/DefaultAppsPreferenceController.java index c7cab15f7b2..4d4165b8f17 100644 --- a/src/com/android/settings/applications/defaultapps/RolesPreferenceController.java +++ b/src/com/android/settings/applications/DefaultAppsPreferenceController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,66 +11,38 @@ * 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. + * limitations under the License */ -package com.android.settings.applications.defaultapps; +package com.android.settings.applications; import android.app.role.RoleManager; import android.content.Context; -import android.content.Intent; import android.content.pm.PackageManager; import android.icu.text.ListFormatter; -import android.provider.Settings; import android.text.TextUtils; -import androidx.preference.Preference; - import com.android.settings.core.BasePreferenceController; import com.android.settingslib.applications.AppUtils; import java.util.ArrayList; import java.util.List; -/** - * STOPSHIP(b/110557011): Remove once the new UI is ready. - */ -public class RolesPreferenceController extends BasePreferenceController { +public class DefaultAppsPreferenceController extends BasePreferenceController { private final PackageManager mPackageManager; private final RoleManager mRoleManager; - private final Intent mIntent; - - public RolesPreferenceController(Context context, String preferenceKey) { + public DefaultAppsPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); mPackageManager = context.getPackageManager(); mRoleManager = context.getSystemService(RoleManager.class); - - final String packageName = mPackageManager.getPermissionControllerPackageName(); - if (packageName != null) { - mIntent = new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) - .setPackage(packageName); - } else { - mIntent = null; - } } @Override public int getAvailabilityStatus() { - return mIntent != null ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE; - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (TextUtils.equals(preference.getKey(), mPreferenceKey)) { - if (mIntent != null) { - mContext.startActivity(mIntent); - } - return true; - } - return false; + return AVAILABLE; } @Override diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java deleted file mode 100644 index 40ea25ed663..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java +++ /dev/null @@ -1,74 +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.applications.defaultapps; - -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; - -import com.android.settings.R; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.ArrayList; -import java.util.List; - -/** - * Fragment for choosing default browser. - */ -public class DefaultBrowserPicker extends DefaultAppPickerFragment { - - @Override - protected int getPreferenceScreenResId() { - return R.xml.default_browser_settings; - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.DEFAULT_BROWSER_PICKER; - } - - @Override - protected String getDefaultKey() { - return mPm.getDefaultBrowserPackageNameAsUser(mUserId); - } - - @Override - protected boolean setDefaultKey(String packageName) { - return mPm.setDefaultBrowserPackageNameAsUser(packageName, mUserId); - } - - @Override - protected List getCandidates() { - final List candidates = new ArrayList<>(); - final Context context = getContext(); - // Resolve that intent and check that the handleAllWebDataURI boolean is set - final List list = - DefaultBrowserPreferenceController.getCandidates(mPm, mUserId); - - for (ResolveInfo info : list) { - try { - candidates.add(new DefaultAppInfo(context, mPm, mUserId, - mPm.getApplicationInfoAsUser(info.activityInfo.packageName, 0, mUserId))); - } catch (PackageManager.NameNotFoundException e) { - // Skip unknown packages. - } - } - - return candidates; - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java deleted file mode 100644 index 6cd72f70db8..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java +++ /dev/null @@ -1,198 +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.applications.defaultapps; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.ComponentInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.IconDrawableFactory; -import android.util.Log; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; - -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -public class DefaultBrowserPreferenceController extends DefaultAppPreferenceController { - - private static final String TAG = "BrowserPrefCtrl"; - - static final Intent BROWSE_PROBE = new Intent() - .setAction(Intent.ACTION_VIEW) - .addCategory(Intent.CATEGORY_BROWSABLE) - .setData(Uri.parse("http:")) - .addFlags(Intent.FLAG_IGNORE_EPHEMERAL); - - public DefaultBrowserPreferenceController(Context context) { - super(context); - } - - @Override - public boolean isAvailable() { - final List candidates = getCandidates(mPackageManager, mUserId); - return candidates != null && !candidates.isEmpty(); - } - - @Override - public String getPreferenceKey() { - return "default_browser"; - } - - @Override - public void updateState(Preference preference) { - super.updateState(preference); - final CharSequence defaultAppLabel = getDefaultAppLabel(); - if (!TextUtils.isEmpty(defaultAppLabel)) { - preference.setSummary(defaultAppLabel); - } - } - - @Override - protected DefaultAppInfo getDefaultAppInfo() { - try { - final String packageName = mPackageManager.getDefaultBrowserPackageNameAsUser(mUserId); - Log.d(TAG, "Get default browser package: " + packageName); - return new DefaultAppInfo(mContext, mPackageManager, mUserId, - mPackageManager.getApplicationInfoAsUser(packageName, 0, mUserId)); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } - - @Override - public CharSequence getDefaultAppLabel() { - if (!isAvailable()) { - return null; - } - final DefaultAppInfo defaultApp = getDefaultAppInfo(); - final CharSequence defaultAppLabel = defaultApp != null ? defaultApp.loadLabel() : null; - if (!TextUtils.isEmpty(defaultAppLabel)) { - return defaultAppLabel; - } - return getOnlyAppLabel(); - } - - @Override - public Drawable getDefaultAppIcon() { - if (!isAvailable()) { - return null; - } - final DefaultAppInfo defaultApp = getDefaultAppInfo(); - if (defaultApp != null) { - return defaultApp.loadIcon(); - } - return getOnlyAppIcon(); - } - - static List getCandidates(PackageManager packageManager, int userId) { - final List candidates = new ArrayList<>(); - // Resolve that intent and check that the handleAllWebDataURI boolean is set - final List list = packageManager.queryIntentActivitiesAsUser( - BROWSE_PROBE, PackageManager.MATCH_ALL, userId); - if (list != null) { - final Set addedPackages = new ArraySet<>(); - for (ResolveInfo info : list) { - if (!info.handleAllWebDataURI || info.activityInfo == null - || !info.activityInfo.enabled - || !info.activityInfo.applicationInfo.enabled) { - continue; - } - final String packageName = info.activityInfo.packageName; - if (addedPackages.contains(packageName)) { - continue; - } - candidates.add(info); - addedPackages.add(packageName); - } - } - return candidates; - } - - private String getOnlyAppLabel() { - // Resolve that intent and check that the handleAllWebDataURI boolean is set - final List list = getCandidates(mPackageManager, mUserId); - if (list != null && list.size() == 1) { - final ResolveInfo info = list.get(0); - final String label = info.loadLabel(mPackageManager).toString(); - final ComponentInfo cn = info.getComponentInfo(); - final String packageName = cn == null ? null : cn.packageName; - Log.d(TAG, "Getting label for the only browser app: " + packageName + label); - return label; - } - return null; - } - - @VisibleForTesting - Drawable getOnlyAppIcon() { - final List list = getCandidates(mPackageManager, mUserId); - if (list != null && list.size() == 1) { - final ResolveInfo info = list.get(0); - final ComponentInfo cn = info.getComponentInfo(); - final String packageName = cn == null ? null : cn.packageName; - if (TextUtils.isEmpty(packageName)) { - return null; - } - final ApplicationInfo appInfo; - try { - appInfo = mPackageManager.getApplicationInfoAsUser(packageName, 0, mUserId); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Error getting app info for " + packageName); - return null; - } - Log.d(TAG, "Getting icon for the only browser app: " + packageName); - final IconDrawableFactory iconFactory = IconDrawableFactory.newInstance(mContext); - return iconFactory.getBadgedIcon(cn, appInfo, mUserId); - } - return null; - } - - /** - * Whether or not the pkg contains browser capability - */ - public static boolean hasBrowserPreference(String pkg, Context context, int userId) { - final Intent intent = new Intent(BROWSE_PROBE); - intent.setPackage(pkg); - final List resolveInfos = context.getPackageManager() - .queryIntentActivitiesAsUser(intent, 0 /* flags */, userId); - return resolveInfos != null && resolveInfos.size() != 0; - } - - /** - * Whether or not the pkg is the default browser - */ - public boolean isBrowserDefault(String pkg, int userId) { - final String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); - if (defaultPackage != null) { - return defaultPackage.equals(pkg); - } - - final List list = getCandidates(mPackageManager, userId); - // There is only 1 app, it must be the default browser. - return list != null && list.size() == 1; - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultEmergencyPicker.java b/src/com/android/settings/applications/defaultapps/DefaultEmergencyPicker.java deleted file mode 100644 index 32cc9a8979b..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultEmergencyPicker.java +++ /dev/null @@ -1,115 +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.applications.defaultapps; - -import android.app.role.RoleManager; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.AsyncTask; -import android.os.Process; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.util.CollectionUtils; -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settingslib.applications.DefaultAppInfo; -import com.android.settingslib.widget.CandidateInfo; - -import java.util.ArrayList; -import java.util.List; - -public class DefaultEmergencyPicker extends DefaultAppPickerFragment { - private static final String TAG = "DefaultEmergencyPicker"; - @Override - public int getMetricsCategory() { - return SettingsEnums.DEFAULT_EMERGENCY_APP_PICKER; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.default_emergency_settings; - } - - @Override - protected List getCandidates() { - final List candidates = new ArrayList<>(); - final List infos = mPm.queryIntentActivities( - DefaultEmergencyPreferenceController.QUERY_INTENT, 0); - PackageInfo bestMatch = null; - final Context context = getContext(); - for (ResolveInfo info : infos) { - try { - final PackageInfo packageInfo = - mPm.getPackageInfo(info.activityInfo.packageName, 0); - final ApplicationInfo appInfo = packageInfo.applicationInfo; - candidates.add(new DefaultAppInfo(context, mPm, mUserId, appInfo)); - // Get earliest installed system app. - if (isSystemApp(appInfo) && (bestMatch == null || - bestMatch.firstInstallTime > packageInfo.firstInstallTime)) { - bestMatch = packageInfo; - } - } catch (PackageManager.NameNotFoundException e) { - // Skip unknown packages. - } - if (bestMatch != null) { - final String defaultKey = getDefaultKey(); - if (TextUtils.isEmpty(defaultKey)) { - setDefaultKey(bestMatch.packageName); - } - } - } - return candidates; - } - - @Override - protected String getConfirmationMessage(CandidateInfo info) { - return Utils.isPackageDirectBootAware(getContext(), info.getKey()) ? null - : getContext().getString(R.string.direct_boot_unaware_dialog_message); - } - - @Override - protected String getDefaultKey() { - RoleManager roleManager = getContext().getSystemService(RoleManager.class); - return CollectionUtils.firstOrNull(roleManager.getRoleHolders(RoleManager.ROLE_EMERGENCY)); - } - - @Override - protected boolean setDefaultKey(String key) { - final String previousValue = getDefaultKey(); - - if (!TextUtils.isEmpty(key) && !TextUtils.equals(key, previousValue)) { - getContext().getSystemService(RoleManager.class).addRoleHolderAsUser( - RoleManager.ROLE_EMERGENCY, key, 0, Process.myUserHandle(), - AsyncTask.THREAD_POOL_EXECUTOR, successful -> { - if (!successful) { - Log.e(TAG, "Failed to set emergency default app."); - } - }); - return true; - } - return false; - } - - private boolean isSystemApp(ApplicationInfo info) { - return info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultEmergencyPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultEmergencyPreferenceController.java deleted file mode 100644 index 425b2166046..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultEmergencyPreferenceController.java +++ /dev/null @@ -1,79 +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.applications.defaultapps; - -import android.app.role.RoleManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.provider.Settings; -import android.telephony.TelephonyManager; - -import com.android.internal.util.CollectionUtils; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.List; - -public class DefaultEmergencyPreferenceController extends DefaultAppPreferenceController { - - private static final boolean DEFAULT_EMERGENCY_APP_IS_CONFIGURABLE = false; - - public static final Intent QUERY_INTENT = new Intent( - TelephonyManager.ACTION_EMERGENCY_ASSISTANCE); - - public DefaultEmergencyPreferenceController(Context context) { - super(context); - } - - @Override - public boolean isAvailable() { - return DEFAULT_EMERGENCY_APP_IS_CONFIGURABLE - && isCapable() - && mPackageManager.resolveActivity(QUERY_INTENT, 0) != null; - } - - @Override - public String getPreferenceKey() { - return "default_emergency_app"; - } - - @Override - protected DefaultAppInfo getDefaultAppInfo() { - return null; - } - - private boolean isCapable() { - return TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED - && mContext.getResources().getBoolean( - com.android.internal.R.bool.config_voice_capable); - } - - public static boolean hasEmergencyPreference(String pkg, Context context) { - Intent i = new Intent(QUERY_INTENT); - i.setPackage(pkg); - final List resolveInfos = - context.getPackageManager().queryIntentActivities(i, 0); - return resolveInfos != null && resolveInfos.size() != 0; - } - - public static boolean isEmergencyDefault(String pkg, Context context) { - String defaultPackage = CollectionUtils.firstOrNull( - context.getSystemService(RoleManager.class) - .getRoleHolders(RoleManager.ROLE_EMERGENCY)); - return defaultPackage != null && defaultPackage.equals(pkg); - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java b/src/com/android/settings/applications/defaultapps/DefaultHomePicker.java deleted file mode 100644 index 304b307b076..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultHomePicker.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.applications.defaultapps; - -import android.app.settings.SettingsEnums; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; -import android.os.Build; -import android.text.TextUtils; - -import com.android.settings.R; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.ArrayList; -import java.util.List; - -public class DefaultHomePicker extends DefaultAppPickerFragment { - - private String mPackageName; - - @Override - public void onAttach(Context context) { - super.onAttach(context); - mPackageName = context.getPackageName(); - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.default_home_settings; - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.DEFAULT_HOME_PICKER; - } - - @Override - protected List getCandidates() { - final boolean mustSupportManagedProfile = hasManagedProfile(); - final List candidates = new ArrayList<>(); - final List homeActivities = new ArrayList<>(); - final Context context = getContext(); - mPm.getHomeActivities(homeActivities); - - for (ResolveInfo resolveInfo : homeActivities) { - final ActivityInfo info = resolveInfo.activityInfo; - final ComponentName activityName = new ComponentName(info.packageName, info.name); - if (info.packageName.equals(mPackageName)) { - continue; - } - - final String summary; - boolean enabled = true; - if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(resolveInfo)) { - summary = getContext().getString(R.string.home_work_profile_not_supported); - enabled = false; - } else { - summary = null; - } - final DefaultAppInfo candidate = - new DefaultAppInfo(context, mPm, mUserId, activityName, summary, enabled); - candidates.add(candidate); - } - return candidates; - } - - @Override - protected String getDefaultKey() { - final ArrayList homeActivities = new ArrayList<>(); - final ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); - if (currentDefaultHome != null) { - return currentDefaultHome.flattenToString(); - } - return null; - } - - @Override - protected boolean setDefaultKey(String key) { - if (!TextUtils.isEmpty(key)) { - final ComponentName component = ComponentName.unflattenFromString(key); - final List homeActivities = new ArrayList<>(); - mPm.getHomeActivities(homeActivities); - final List allComponents = new ArrayList<>(); - for (ResolveInfo info : homeActivities) { - final ActivityInfo appInfo = info.activityInfo; - ComponentName activityName = new ComponentName(appInfo.packageName, appInfo.name); - allComponents.add(activityName); - } - mPm.replacePreferredActivity( - DefaultHomePreferenceController.HOME_FILTER, - IntentFilter.MATCH_CATEGORY_EMPTY, - allComponents.toArray(new ComponentName[0]), - component); - - // Launch the new Home app so the change is immediately visible even if - // the Home button is not pressed. - final Context context = getContext(); - Intent i = new Intent(Intent.ACTION_MAIN); - i.addCategory(Intent.CATEGORY_HOME); - i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(i); - return true; - } - return false; - } - - private boolean hasManagedProfile() { - final Context context = getContext(); - List profiles = mUserManager.getProfiles(context.getUserId()); - for (UserInfo userInfo : profiles) { - if (userInfo.isManagedProfile()) { - return true; - } - } - return false; - } - - private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo) { - try { - ApplicationInfo appInfo = mPm.getApplicationInfo(resolveInfo.activityInfo.packageName, - 0 /* default flags */); - return versionNumberAtLeastL(appInfo.targetSdkVersion); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - } - - private boolean versionNumberAtLeastL(int versionNumber) { - return versionNumber >= Build.VERSION_CODES.LOLLIPOP; - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java deleted file mode 100644 index 9fbde3e25b8..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java +++ /dev/null @@ -1,129 +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.applications.defaultapps; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; - -import com.android.settings.R; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.ArrayList; -import java.util.List; - -public class DefaultHomePreferenceController extends DefaultAppPreferenceController { - - static final IntentFilter HOME_FILTER; - - private final String mPackageName; - - static { - HOME_FILTER = new IntentFilter(Intent.ACTION_MAIN); - HOME_FILTER.addCategory(Intent.CATEGORY_HOME); - HOME_FILTER.addCategory(Intent.CATEGORY_DEFAULT); - } - - public DefaultHomePreferenceController(Context context) { - super(context); - mPackageName = mContext.getPackageName(); - } - - @Override - public String getPreferenceKey() { - return "default_home"; - } - - @Override - public boolean isAvailable() { - return mContext.getResources().getBoolean(R.bool.config_show_default_home); - } - - @Override - protected DefaultAppInfo getDefaultAppInfo() { - final ArrayList homeActivities = new ArrayList<>(); - final ComponentName currentDefaultHome = mPackageManager.getHomeActivities(homeActivities); - if (currentDefaultHome != null) { - return new DefaultAppInfo(mContext, mPackageManager, mUserId, currentDefaultHome); - } - final ActivityInfo onlyAppInfo = getOnlyAppInfo(homeActivities); - if (onlyAppInfo != null) { - return new DefaultAppInfo(mContext, mPackageManager, mUserId, - onlyAppInfo.getComponentName()); - } - return null; - } - - private ActivityInfo getOnlyAppInfo(List homeActivities) { - final List appLabels = new ArrayList<>(); - - mPackageManager.getHomeActivities(homeActivities); - for (ResolveInfo candidate : homeActivities) { - final ActivityInfo info = candidate.activityInfo; - if (info.packageName.equals(mPackageName)) { - continue; - } - appLabels.add(info); - } - return appLabels.size() == 1 - ? appLabels.get(0) - : null; - } - - @Override - protected Intent getSettingIntent(DefaultAppInfo info) { - if (info == null) { - return null; - } - final String packageName; - if (info.componentName != null) { - packageName = info.componentName.getPackageName(); - } else if (info.packageItemInfo != null) { - packageName = info.packageItemInfo.packageName; - } else { - return null; - } - - Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES) - .setPackage(packageName) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - return intent.resolveActivity(mPackageManager) != null ? intent : null; - } - - public static boolean hasHomePreference(String pkg, Context context) { - ArrayList homeActivities = new ArrayList<>(); - PackageManager pm = context.getPackageManager(); - pm.getHomeActivities(homeActivities); - for (int i = 0; i < homeActivities.size(); i++) { - if (homeActivities.get(i).activityInfo.packageName.equals(pkg)) { - return true; - } - } - return false; - } - - public static boolean isHomeDefault(String pkg, PackageManager pm) { - final ArrayList homeActivities = new ArrayList<>(); - ComponentName def = pm.getHomeActivities(homeActivities); - - return def == null || def.getPackageName().equals(pkg); - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java b/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java deleted file mode 100644 index 8b16be1f061..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultPhonePicker.java +++ /dev/null @@ -1,111 +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.applications.defaultapps; - -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.pm.PackageManager; -import android.telecom.DefaultDialerManager; -import android.telecom.TelecomManager; -import android.text.TextUtils; - -import com.android.settings.R; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.ArrayList; -import java.util.List; - -public class DefaultPhonePicker extends DefaultAppPickerFragment { - - private DefaultKeyUpdater mDefaultKeyUpdater; - - @Override - public int getMetricsCategory() { - return SettingsEnums.DEFAULT_PHONE_PICKER; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - mDefaultKeyUpdater = new DefaultKeyUpdater( - (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE)); - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.default_phone_settings; - } - - @Override - protected List getCandidates() { - final List candidates = new ArrayList<>(); - final List dialerPackages = - DefaultDialerManager.getInstalledDialerApplications(getContext(), mUserId); - final Context context = getContext(); - for (String packageName : dialerPackages) { - try { - candidates.add(new DefaultAppInfo(context, mPm, mUserId, - mPm.getApplicationInfoAsUser(packageName, 0, mUserId))); - } catch (PackageManager.NameNotFoundException e) { - // Skip unknown packages. - } - } - return candidates; - } - - @Override - protected String getDefaultKey() { - return mDefaultKeyUpdater.getDefaultDialerApplication(getContext(), mUserId); - } - - @Override - protected String getSystemDefaultKey() { - return mDefaultKeyUpdater.getSystemDialerPackage(); - } - - @Override - protected boolean setDefaultKey(String key) { - if (!TextUtils.isEmpty(key) && !TextUtils.equals(key, getDefaultKey())) { - mBatteryUtils.clearForceAppStandby(key); - return mDefaultKeyUpdater.setDefaultDialerApplication(getContext(), key, mUserId); - } - return false; - } - - /** - * Wrapper class to handle default phone app update. - */ - static class DefaultKeyUpdater { - private final TelecomManager mTelecomManager; - - public DefaultKeyUpdater(TelecomManager telecomManager) { - mTelecomManager = telecomManager; - } - - public String getSystemDialerPackage() { - return mTelecomManager.getSystemDialerPackage(); - } - - public String getDefaultDialerApplication(Context context, int uid) { - return DefaultDialerManager.getDefaultDialerApplication(context, uid); - } - - public boolean setDefaultDialerApplication(Context context, String key, int uid) { - return DefaultDialerManager.setDefaultDialerApplication(context, key, uid); - } - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultPhonePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultPhonePreferenceController.java deleted file mode 100644 index 7b7755d9083..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultPhonePreferenceController.java +++ /dev/null @@ -1,85 +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.applications.defaultapps; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.telecom.DefaultDialerManager; -import android.telephony.TelephonyManager; - -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.List; - -public class DefaultPhonePreferenceController extends DefaultAppPreferenceController { - - public DefaultPhonePreferenceController(Context context) { - super(context); - } - - @Override - public boolean isAvailable() { - final TelephonyManager tm = - (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - if (!tm.isVoiceCapable()) { - return false; - } - final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - final boolean hasUserRestriction = - um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS); - - if (hasUserRestriction) { - return false; - } - final List candidates = getCandidates(); - return candidates != null && !candidates.isEmpty(); - } - - @Override - public String getPreferenceKey() { - return "default_phone_app"; - } - - @Override - protected DefaultAppInfo getDefaultAppInfo() { - try { - return new DefaultAppInfo(mContext, mPackageManager, mUserId, - mPackageManager.getApplicationInfo( - DefaultDialerManager.getDefaultDialerApplication(mContext, mUserId), 0)); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } - - private List getCandidates() { - return DefaultDialerManager.getInstalledDialerApplications(mContext, mUserId); - } - - public static boolean hasPhonePreference(String pkg, Context context) { - List dialerPackages = - DefaultDialerManager.getInstalledDialerApplications(context, UserHandle.myUserId()); - return dialerPackages.contains(pkg); - } - - public static boolean isPhoneDefault(String pkg, Context context) { - String def = DefaultDialerManager.getDefaultDialerApplication(context, - UserHandle.myUserId()); - return def != null && def.equals(pkg); - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java b/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java deleted file mode 100644 index 4c6b6e87f26..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultSmsPicker.java +++ /dev/null @@ -1,106 +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.applications.defaultapps; - -import android.app.settings.SettingsEnums; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageManager; -import android.text.TextUtils; - -import com.android.internal.telephony.SmsApplication; -import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settingslib.applications.DefaultAppInfo; -import com.android.settingslib.widget.CandidateInfo; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class DefaultSmsPicker extends DefaultAppPickerFragment { - - private DefaultKeyUpdater mDefaultKeyUpdater = new DefaultKeyUpdater(); - - @Override - public int getMetricsCategory() { - return SettingsEnums.DEFAULT_SMS_PICKER; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.default_sms_settings; - } - - @Override - protected List getCandidates() { - final Context context = getContext(); - final Collection smsApplications = - SmsApplication.getApplicationCollection(context); - final List candidates = new ArrayList<>(smsApplications.size()); - - for (SmsApplication.SmsApplicationData smsApplicationData : smsApplications) { - try { - candidates.add(new DefaultAppInfo(context, mPm, mUserId, - mPm.getApplicationInfoAsUser(smsApplicationData.mPackageName, 0, mUserId))); - } catch (PackageManager.NameNotFoundException e) { - // Skip unknown packages. - } - } - - return candidates; - } - - @Override - protected String getDefaultKey() { - return mDefaultKeyUpdater.getDefaultApplication(getContext()); - } - - @Override - protected boolean setDefaultKey(String key) { - if (!TextUtils.isEmpty(key) && !TextUtils.equals(key, getDefaultKey())) { - mDefaultKeyUpdater.setDefaultApplication(getContext(), key); - mBatteryUtils.clearForceAppStandby(key); - return true; - } - return false; - } - - @Override - protected String getConfirmationMessage(CandidateInfo info) { - return Utils.isPackageDirectBootAware(getContext(), info.getKey()) ? null - : getContext().getString(R.string.direct_boot_unaware_dialog_message); - } - - /** - * Wrapper class to handle default phone app update. - */ - static class DefaultKeyUpdater { - - public String getDefaultApplication(Context context) { - final ComponentName appName = SmsApplication.getDefaultSmsApplication(context, true); - if (appName != null) { - return appName.getPackageName(); - } - return null; - } - - public void setDefaultApplication(Context context, String key) { - SmsApplication.setDefaultApplication(key, context); - } - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java deleted file mode 100644 index cb86b2ec955..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java +++ /dev/null @@ -1,71 +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.applications.defaultapps; - -import android.content.ComponentName; -import android.content.Context; -import android.telephony.TelephonyManager; - -import com.android.internal.telephony.SmsApplication; -import com.android.settingslib.applications.DefaultAppInfo; - -import java.util.Collection; - -public class DefaultSmsPreferenceController extends DefaultAppPreferenceController { - - public DefaultSmsPreferenceController(Context context) { - super(context); - } - - @Override - public boolean isAvailable() { - boolean isRestrictedUser = mUserManager.getUserInfo(mUserId).isRestricted(); - TelephonyManager tm = - (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - return !isRestrictedUser && tm.isSmsCapable(); - } - - @Override - public String getPreferenceKey() { - return "default_sms_app"; - } - - @Override - protected DefaultAppInfo getDefaultAppInfo() { - final ComponentName app = SmsApplication.getDefaultSmsApplication(mContext, true); - if (app != null) { - return new DefaultAppInfo(mContext, mPackageManager, mUserId, app); - } - return null; - } - - public static boolean hasSmsPreference(String pkg, Context context) { - Collection smsApplications = - SmsApplication.getApplicationCollection(context); - for (SmsApplication.SmsApplicationData data : smsApplications) { - if (data.mPackageName.equals(pkg)) { - return true; - } - } - return false; - } - - public static boolean isSmsDefault(String pkg, Context context) { - ComponentName appName = SmsApplication.getDefaultSmsApplication(context, true); - return appName != null && appName.getPackageName().equals(pkg); - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultWorkBrowserPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultWorkBrowserPreferenceController.java deleted file mode 100644 index 46528558fcd..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultWorkBrowserPreferenceController.java +++ /dev/null @@ -1,50 +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.applications.defaultapps; - -import android.content.Context; -import android.os.UserHandle; - -import com.android.settings.Utils; - - -public class DefaultWorkBrowserPreferenceController extends DefaultBrowserPreferenceController { - - public static final String KEY = "work_default_browser"; - private final UserHandle mUserHandle; - - public DefaultWorkBrowserPreferenceController(Context context) { - super(context); - mUserHandle = Utils.getManagedProfile(mUserManager); - if (mUserHandle != null) { - mUserId = mUserHandle.getIdentifier(); - } - } - - @Override - public String getPreferenceKey() { - return KEY; - } - - @Override - public boolean isAvailable() { - if (mUserHandle == null) { - return false; - } - return super.isAvailable(); - } -} diff --git a/src/com/android/settings/applications/defaultapps/DefaultWorkPhonePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultWorkPhonePreferenceController.java deleted file mode 100644 index decff06759c..00000000000 --- a/src/com/android/settings/applications/defaultapps/DefaultWorkPhonePreferenceController.java +++ /dev/null @@ -1,49 +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.applications.defaultapps; - -import android.content.Context; -import android.os.UserHandle; - -import com.android.settings.Utils; - -public class DefaultWorkPhonePreferenceController extends DefaultPhonePreferenceController { - - public static final String KEY = "work_default_phone_app"; - private final UserHandle mUserHandle; - - public DefaultWorkPhonePreferenceController(Context context) { - super(context); - mUserHandle = Utils.getManagedProfile(mUserManager); - if (mUserHandle != null) { - mUserId = mUserHandle.getIdentifier(); - } - } - - @Override - public boolean isAvailable() { - if (mUserHandle == null) { - return false; - } - return super.isAvailable(); - } - - @Override - public String getPreferenceKey() { - return KEY; - } -} diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 6315ab12287..b4b909d586a 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -92,7 +92,6 @@ import com.android.settings.applications.AppStateUsageBridge; import com.android.settings.applications.AppStateUsageBridge.UsageState; import com.android.settings.applications.AppStateWriteSettingsBridge; import com.android.settings.applications.AppStorageSettings; -import com.android.settings.applications.DefaultAppSettings; import com.android.settings.applications.InstalledAppCounter; import com.android.settings.applications.UsageAccessDetails; import com.android.settings.applications.appinfo.AppInfoDashboardFragment; @@ -704,12 +703,9 @@ public class ManageApplications extends InstrumentedFragment .setResultListener(this, ADVANCED_SETTINGS) .launch(); } else { - new SubSettingLauncher(getContext()) - .setDestination(DefaultAppSettings.class.getName()) - .setTitleRes(R.string.configure_apps) - .setSourceMetricsCategory(getMetricsCategory()) - .setResultListener(this, ADVANCED_SETTINGS) - .launch(); + Intent intent = new Intent( + android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS); + startActivityForResult(intent, ADVANCED_SETTINGS); } return true; default: diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index 30f6afcd6ca..35a162785fe 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -34,7 +34,6 @@ import com.android.settings.accounts.AccountSyncSettings; import com.android.settings.accounts.ChooseAccountFragment; import com.android.settings.accounts.ManagedProfileSettings; import com.android.settings.applications.AppAndNotificationDashboardFragment; -import com.android.settings.applications.DefaultAppSettings; import com.android.settings.applications.ProcessStatsSummary; import com.android.settings.applications.ProcessStatsUi; import com.android.settings.applications.UsageAccessDetails; @@ -247,7 +246,6 @@ public class SettingsGateway { DrawOverlayDetails.class.getName(), WriteSettingsDetails.class.getName(), ExternalSourcesDetails.class.getName(), - DefaultAppSettings.class.getName(), WallpaperTypeSettings.class.getName(), VrListenerSettings.class.getName(), PictureInPictureSettings.class.getName(), @@ -308,7 +306,6 @@ public class SettingsGateway { // Home page > Apps & Notifications Settings.UserSettingsActivity.class.getName(), Settings.ConfigureNotificationSettingsActivity.class.getName(), - Settings.AdvancedAppsActivity.class.getName(), Settings.ManageApplicationsActivity.class.getName(), Settings.PaymentSettingsActivity.class.getName(), // Home page > Security & screen lock diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java index 34afad66329..b499b59d7e7 100644 --- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java +++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java @@ -23,7 +23,6 @@ import com.android.settings.LegalSettings; import com.android.settings.accounts.AccountDashboardFragment; import com.android.settings.accounts.AccountDetailDashboardFragment; import com.android.settings.applications.AppAndNotificationDashboardFragment; -import com.android.settings.applications.DefaultAppSettings; import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.development.DevelopmentSettingsDashboardFragment; @@ -79,8 +78,6 @@ public class DashboardFragmentRegistry { CategoryKey.CATEGORY_APPS); PARENT_TO_CATEGORY_KEY_MAP.put(PowerUsageSummary.class.getName(), CategoryKey.CATEGORY_BATTERY); - PARENT_TO_CATEGORY_KEY_MAP.put(DefaultAppSettings.class.getName(), - CategoryKey.CATEGORY_APPS_DEFAULT); PARENT_TO_CATEGORY_KEY_MAP.put(DisplaySettings.class.getName(), CategoryKey.CATEGORY_DISPLAY); PARENT_TO_CATEGORY_KEY_MAP.put(SoundSettings.class.getName(), diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml index 1fe4bbeecf0..cacecd6acb2 100644 --- a/tests/robotests/res/values-mcc999/config.xml +++ b/tests/robotests/res/values-mcc999/config.xml @@ -46,7 +46,6 @@ false false false - false false false false diff --git a/tests/robotests/src/com/android/settings/applications/DefaultAppSettingsTest.java b/tests/robotests/src/com/android/settings/applications/DefaultAppSettingsTest.java deleted file mode 100644 index 1ab086ccf8b..00000000000 --- a/tests/robotests/src/com/android/settings/applications/DefaultAppSettingsTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2016 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.applications; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserManager; -import android.telephony.TelephonyManager; - -import com.android.settings.R; -import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController; -import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController; -import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController; -import com.android.settings.dashboard.SummaryLoader; -import com.android.settings.testutils.XmlTestUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; - -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class DefaultAppSettingsTest { - - private Context mContext; - - private DefaultAppSettings mFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mFragment = new DefaultAppSettings(); - mFragment.onAttach(mContext); - } - - @Test - public void getPreferenceScreenResId_shouldUseAppDefaultSettingPrefLayout() { - assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.app_default_settings); - } - - @Test - public void setListening_shouldUpdateSummary() { - final SummaryLoader summaryLoader = mock(SummaryLoader.class); - final DefaultAppSettings.SummaryProvider summaryProvider = - new DefaultAppSettings.SummaryProvider(mContext, summaryLoader); - final DefaultSmsPreferenceController defaultSms = - mock(DefaultSmsPreferenceController.class); - final DefaultBrowserPreferenceController defaultBrowser = - mock(DefaultBrowserPreferenceController.class); - final DefaultPhonePreferenceController defaultPhone = - mock(DefaultPhonePreferenceController.class); - ReflectionHelpers.setField(summaryProvider, "mDefaultSmsPreferenceController", defaultSms); - ReflectionHelpers.setField( - summaryProvider, "mDefaultBrowserPreferenceController", defaultBrowser); - ReflectionHelpers.setField( - summaryProvider, "mDefaultPhonePreferenceController", defaultPhone); - - // all available - when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1"); - when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1"); - when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1"); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Browser1, Phone1, and Sms1"); - - // 2 available - when(defaultSms.getDefaultAppLabel()).thenReturn(null); - when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1"); - when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1"); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Browser1 and Phone1"); - - when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1"); - when(defaultBrowser.getDefaultAppLabel()).thenReturn(null); - when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1"); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Phone1 and Sms1"); - - when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1"); - when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1"); - when(defaultPhone.getDefaultAppLabel()).thenReturn(null); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Browser1 and Sms1"); - - // 1 available - when(defaultSms.getDefaultAppLabel()).thenReturn(null); - when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1"); - when(defaultPhone.getDefaultAppLabel()).thenReturn(null); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Browser1"); - - when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1"); - when(defaultBrowser.getDefaultAppLabel()).thenReturn(null); - when(defaultPhone.getDefaultAppLabel()).thenReturn(null); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Sms1"); - - when(defaultSms.getDefaultAppLabel()).thenReturn(null); - when(defaultBrowser.getDefaultAppLabel()).thenReturn(null); - when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1"); - summaryProvider.setListening(true); - - verify(summaryLoader).setSummary(summaryProvider, "Phone1"); - - // None available - when(defaultSms.getDefaultAppLabel()).thenReturn(null); - when(defaultBrowser.getDefaultAppLabel()).thenReturn(null); - when(defaultPhone.getDefaultAppLabel()).thenReturn(null); - summaryProvider.setListening(true); - - verify(summaryLoader, never()).setSummary(summaryProvider, eq(anyString())); - } - - @Test - public void testNonIndexableKeys_existInXmlLayout() { - final Context context = spy(RuntimeEnvironment.application); - when(context.getApplicationContext()).thenReturn(context); - final UserManager userManager = mock(UserManager.class, RETURNS_DEEP_STUBS); - - when(context.getSystemService(Context.USER_SERVICE)) - .thenReturn(userManager); - when(userManager.getUserInfo(anyInt()).isRestricted()).thenReturn(true); - - when(context.getSystemService(Context.TELEPHONY_SERVICE)) - .thenReturn(mock(TelephonyManager.class)); - when(context.getPackageManager()) - .thenReturn(mock(PackageManager.class)); - final List niks = DefaultAppSettings.SEARCH_INDEX_DATA_PROVIDER - .getNonIndexableKeys(context); - - final int xmlId = new DefaultAppSettings().getPreferenceScreenResId(); - - final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); - - assertThat(keys).containsAllIn(niks); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/DefaultAppsPreferenceControllerTest.java similarity index 51% rename from tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java rename to tests/robotests/src/com/android/settings/applications/DefaultAppsPreferenceControllerTest.java index 92468a084f9..6d53179f45e 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/DefaultAppsPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,36 +11,25 @@ * 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. + * limitations under the License */ -package com.android.settings.applications.defaultapps; +package com.android.settings.applications; 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.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.role.RoleManager; import android.content.Context; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.provider.Settings; - -import androidx.preference.Preference; - -import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; @@ -48,13 +37,9 @@ import org.robolectric.RobolectricTestRunner; import java.util.Collections; @RunWith(RobolectricTestRunner.class) -public class RolesPreferenceControllerTest { +public class DefaultAppsPreferenceControllerTest { - private static final String PREFERENCE_KEY = "roles"; - private static final String DIFFERENT_PREFERENCE_KEY = "different"; - - private static final String PERMISSION_CONTROLLER_PACKAGE_NAME = - "com.android.permissioncontroller"; + private static final String PREFERENCE_KEY = "DefaultApps"; private static final String BROWSER_PACKAGE_NAME = "com.example.browser1"; private static final String DIALER_PACKAGE_NAME = "com.example.dialer1"; @@ -73,6 +58,8 @@ public class RolesPreferenceControllerTest { @Mock private ApplicationInfo mSmsApplicationInfo; + private DefaultAppsPreferenceController mPreferenceController; + @Before public void setUp() throws PackageManager.NameNotFoundException { MockitoAnnotations.initMocks(this); @@ -89,80 +76,13 @@ public class RolesPreferenceControllerTest { when(mSmsApplicationInfo.loadLabel(mPackageManager)).thenReturn("Sms1"); when(mPackageManager.getApplicationInfo(eq(SMS_PACKAGE_NAME), anyInt())).thenReturn( mSmsApplicationInfo); + + mPreferenceController = new DefaultAppsPreferenceController(mContext, PREFERENCE_KEY); } @Test - public void getAvailabilityStatus_noPermissionController_shouldReturnUnsupportedOnDevice() { - when(mPackageManager.getPermissionControllerPackageName()).thenReturn(null); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - - assertThat(preferenceController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); - } - - @Test - public void getAvailabilityStatus_hasPermissionController_shouldReturnAvailableUnsearchable() { - when(mPackageManager.getPermissionControllerPackageName()) - .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - - assertThat(preferenceController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.AVAILABLE_UNSEARCHABLE); - } - - @Test - public void handlePreferenceTreeClick_differentKey_shouldReturnFalse() { - when(mPackageManager.getPermissionControllerPackageName()) - .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - Preference preference = mock(Preference.class); - when(preference.getKey()).thenReturn(DIFFERENT_PREFERENCE_KEY); - - assertThat(preferenceController.handlePreferenceTreeClick(preference)).isFalse(); - } - - @Test - public void handlePreferenceTreeClick_sameKey_shouldReturnTrue() { - when(mPackageManager.getPermissionControllerPackageName()) - .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - Preference preference = mock(Preference.class); - when(preference.getKey()).thenReturn(PREFERENCE_KEY); - - assertThat(preferenceController.handlePreferenceTreeClick(preference)).isTrue(); - } - - @Test - public void handlePreferenceTreeClick_noPermissionController_shouldNotStartActivity() { - when(mPackageManager.getPermissionControllerPackageName()).thenReturn(null); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - Preference preference = mock(Preference.class); - when(preference.getKey()).thenReturn(PREFERENCE_KEY); - preferenceController.handlePreferenceTreeClick(preference); - - verify(mContext, never()).startActivity(any(Intent.class)); - } - - @Test - public void handlePreferenceTreeClick_hasPermissionController_shouldStartActivityWithIntent() { - when(mPackageManager.getPermissionControllerPackageName()) - .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - Preference preference = mock(Preference.class); - when(preference.getKey()).thenReturn(PREFERENCE_KEY); - preferenceController.handlePreferenceTreeClick(preference); - ArgumentCaptor intent = ArgumentCaptor.forClass(Intent.class); - - verify(mContext).startActivity(intent.capture()); - assertThat(intent.getValue().getAction()) - .isEqualTo(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS); - assertThat(intent.getValue().getPackage()).isEqualTo(PERMISSION_CONTROLLER_PACKAGE_NAME); + public void isAvailable_shouldReturnTrue() { + assertThat(mPreferenceController.isAvailable()).isTrue(); } @Test @@ -173,10 +93,8 @@ public class RolesPreferenceControllerTest { Collections.singletonList(DIALER_PACKAGE_NAME)); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn( Collections.singletonList(SMS_PACKAGE_NAME)); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Browser1, Phone1, and Sms1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Browser1, Phone1, and Sms1"); } @Test @@ -186,10 +104,8 @@ public class RolesPreferenceControllerTest { when(mRoleManager.getRoleHolders(RoleManager.ROLE_DIALER)).thenReturn( Collections.singletonList(DIALER_PACKAGE_NAME)); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn(Collections.emptyList()); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Browser1 and Phone1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Browser1 and Phone1"); } @Test @@ -200,10 +116,8 @@ public class RolesPreferenceControllerTest { Collections.emptyList()); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn( Collections.singletonList(SMS_PACKAGE_NAME)); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Browser1 and Sms1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Browser1 and Sms1"); } @Test @@ -214,10 +128,8 @@ public class RolesPreferenceControllerTest { Collections.singletonList(DIALER_PACKAGE_NAME)); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn( Collections.singletonList(SMS_PACKAGE_NAME)); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Phone1 and Sms1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Phone1 and Sms1"); } @Test @@ -227,10 +139,8 @@ public class RolesPreferenceControllerTest { when(mRoleManager.getRoleHolders(RoleManager.ROLE_DIALER)).thenReturn( Collections.emptyList()); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn(Collections.emptyList()); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Browser1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Browser1"); } @Test @@ -240,10 +150,8 @@ public class RolesPreferenceControllerTest { when(mRoleManager.getRoleHolders(RoleManager.ROLE_DIALER)).thenReturn( Collections.singletonList(DIALER_PACKAGE_NAME)); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn(Collections.emptyList()); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Phone1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Phone1"); } @Test @@ -254,10 +162,8 @@ public class RolesPreferenceControllerTest { Collections.emptyList()); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn( Collections.singletonList(SMS_PACKAGE_NAME)); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isEqualTo("Sms1"); + assertThat(mPreferenceController.getSummary()).isEqualTo("Sms1"); } @Test @@ -267,9 +173,7 @@ public class RolesPreferenceControllerTest { when(mRoleManager.getRoleHolders(RoleManager.ROLE_DIALER)).thenReturn( Collections.emptyList()); when(mRoleManager.getRoleHolders(RoleManager.ROLE_SMS)).thenReturn(Collections.emptyList()); - RolesPreferenceController preferenceController = new RolesPreferenceController(mContext, - PREFERENCE_KEY); - assertThat(preferenceController.getSummary()).isNull(); + assertThat(mPreferenceController.getSummary()).isNull(); } } diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java deleted file mode 100644 index 3386d83565f..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java +++ /dev/null @@ -1,77 +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.applications.defaultapps; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserManager; - -import com.android.settings.testutils.FakeFeatureFactory; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(RobolectricTestRunner.class) -public class DefaultBrowserPickerTest { - - private static final String TEST_APP_KEY = ""; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Activity mActivity; - @Mock - private UserManager mUserManager; - @Mock - private PackageManager mPackageManager; - - private DefaultBrowserPicker mPicker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - FakeFeatureFactory.setupForTest(); - when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - - mPicker = new DefaultBrowserPicker(); - mPicker.onAttach(mActivity); - - ReflectionHelpers.setField(mPicker, "mPm", mPackageManager); - } - - @Test - public void setDefaultAppKey_shouldUpdateDefaultBrowser() { - mPicker.setDefaultKey(TEST_APP_KEY); - verify(mPackageManager).setDefaultBrowserPackageNameAsUser(eq(TEST_APP_KEY), anyInt()); - } - - @Test - public void getDefaultAppKey_shouldReturnDefaultBrowser() { - mPicker.getDefaultKey(); - verify(mPackageManager).getDefaultBrowserPackageNameAsUser(anyInt()); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java deleted file mode 100644 index 5197eb30c03..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java +++ /dev/null @@ -1,231 +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.applications.defaultapps; - -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.eq; -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 static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.os.UserManager; - -import androidx.preference.Preference; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.util.ReflectionHelpers; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class DefaultBrowserPreferenceControllerTest { - - @Mock - private Context mContext; - @Mock - private UserManager mUserManager; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private PackageManager mPackageManager; - - private DefaultBrowserPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - - mController = new DefaultBrowserPreferenceController(mContext); - ReflectionHelpers.setField(mController, "mPackageManager", mPackageManager); - } - - @Test - public void isAvailable_noBrowser_shouldReturnFalse() { - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(null); - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_hasBrowser_shouldReturnTrue() { - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(Collections.singletonList(createResolveInfo("com.test.pkg"))); - - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void getSoleAppLabel_hasNoApp_shouldNotReturnLabel() { - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(null); - final Preference pref = mock(Preference.class); - - mController.updateState(pref); - verify(pref).setSummary(R.string.app_list_preference_none); - } - - @Test - public void getDefaultAppLabel_hasAppWithMultipleResolvedInfo_shouldReturnLabel() - throws NameNotFoundException { - DefaultBrowserPreferenceController spyController = spy(mController); - doReturn(null).when(spyController).getDefaultAppIcon(); - final List resolveInfos = new ArrayList<>(); - final CharSequence PACKAGE_NAME = "com.test.package"; - - // This ResolveInfo will return a non-null label from loadLabel. - final ResolveInfo info1 = createResolveInfo(PACKAGE_NAME.toString()); - info1.nonLocalizedLabel = PACKAGE_NAME; - resolveInfos.add(info1); - - // This ResolveInfo will return a null label from loadLabel. - final ResolveInfo info2 = createResolveInfo(PACKAGE_NAME.toString()); - resolveInfos.add(info2); - - when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null); - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(resolveInfos); - when(mPackageManager.getApplicationInfoAsUser( - eq(PACKAGE_NAME.toString()), anyInt(), anyInt())) - .thenReturn(createApplicationInfo(PACKAGE_NAME.toString())); - - assertThat(spyController.getDefaultAppLabel()).isEqualTo(PACKAGE_NAME); - } - - @Test - public void getDefaultApp_shouldGetDefaultBrowserPackage() { - mController.getDefaultAppInfo(); - - verify(mPackageManager).getDefaultBrowserPackageNameAsUser(anyInt()); - } - - @Test - public void getDefaultApp_shouldGetApplicationInfoAsUser() throws NameNotFoundException { - final String PACKAGE_NAME = "com.test.package"; - when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(PACKAGE_NAME); - - mController.getDefaultAppInfo(); - - verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), anyInt()); - } - - @Test - public void isBrowserDefault_onlyApp_shouldReturnTrue() { - when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null); - final List resolveInfos = new ArrayList<>(); - final String PACKAGE_ONE = "pkg"; - resolveInfos.add(createResolveInfo(PACKAGE_ONE)); - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(resolveInfos); - - assertThat(mController.isBrowserDefault("pkg", 0)).isTrue(); - } - - @Test - public void getCandidates_shouldNotIncludeDuplicatePackageName() throws NameNotFoundException { - final List resolveInfos = new ArrayList<>(); - final String PACKAGE_ONE = "com.first.package"; - final String PACKAGE_TWO = "com.second.package"; - resolveInfos.add(createResolveInfo(PACKAGE_ONE)); - resolveInfos.add(createResolveInfo(PACKAGE_TWO)); - resolveInfos.add(createResolveInfo(PACKAGE_ONE)); - resolveInfos.add(createResolveInfo(PACKAGE_TWO)); - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(resolveInfos); - when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_ONE), anyInt(), anyInt())) - .thenReturn(createApplicationInfo(PACKAGE_ONE)); - when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_TWO), anyInt(), anyInt())) - .thenReturn(createApplicationInfo(PACKAGE_TWO)); - - final List defaultBrowserInfo = - DefaultBrowserPreferenceController.getCandidates(mPackageManager, 0 /* userId */); - - assertThat(defaultBrowserInfo.size()).isEqualTo(2); - } - - @Test - public void getCandidates_shouldQueryActivityWithMatchAll() { - DefaultBrowserPreferenceController.getCandidates(mPackageManager, 0 /* userId */); - - verify(mPackageManager).queryIntentActivitiesAsUser( - any(Intent.class), eq(PackageManager.MATCH_ALL), eq(0) /* userId */); - } - - @Test - public void getOnlyAppIcon_shouldGetApplicationInfoAsUser() throws NameNotFoundException { - final List resolveInfos = new ArrayList<>(); - final String PACKAGE_NAME = "com.test.package"; - resolveInfos.add(createResolveInfo(PACKAGE_NAME)); - when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(resolveInfos); - when(mContext.getPackageManager()).thenReturn(mPackageManager); - when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); - when(mContext.getResources()).thenReturn(mock(Resources.class)); - - mController.getOnlyAppIcon(); - - verify(mPackageManager).getApplicationInfoAsUser( - eq(PACKAGE_NAME), eq(0) /* flags */, eq(0) /* userId */); - } - - @Test - public void hasBrowserPreference_shouldQueryIntentActivitiesAsUser() { - when(mContext.getPackageManager()).thenReturn(mPackageManager); - - DefaultBrowserPreferenceController - .hasBrowserPreference("com.test.package", mContext, 0 /* userId */); - - verify(mPackageManager).queryIntentActivitiesAsUser( - any(Intent.class), eq(0) /* flags */, eq(0) /* userId */); - } - - private ResolveInfo createResolveInfo(String packageName) { - final ResolveInfo info = new ResolveInfo(); - info.handleAllWebDataURI = true; - info.activityInfo = new ActivityInfo(); - info.activityInfo.packageName = packageName; - info.activityInfo.applicationInfo = createApplicationInfo(packageName); - return info; - } - - private ApplicationInfo createApplicationInfo(String packageName) { - final ApplicationInfo info = new ApplicationInfo(); - info.packageName = packageName; - return info; - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java deleted file mode 100644 index b7b046ce000..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java +++ /dev/null @@ -1,97 +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.applications.defaultapps; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.app.role.RoleManager; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserHandle; -import android.os.UserManager; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowApplication; -import org.robolectric.util.ReflectionHelpers; - -import java.util.Arrays; -import java.util.concurrent.Executor; -import java.util.function.Consumer; - -@RunWith(RobolectricTestRunner.class) -public class DefaultEmergencyPickerTest { - private static final String TAG = DefaultEmergencyPickerTest.class.getSimpleName(); - private static final String TEST_APP_KEY = "test_app"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Activity mActivity; - @Mock - private UserManager mUserManager; - @Mock - private PackageManager mPackageManager; - @Mock - private RoleManager mRoleManager; - - private DefaultEmergencyPicker mPicker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - ShadowApplication shadowApplication = ShadowApplication.getInstance(); - shadowApplication.setSystemService(Context.ROLE_SERVICE, mRoleManager); - when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - - mPicker = spy(new DefaultEmergencyPicker()); - mPicker.onAttach(mActivity); - - ReflectionHelpers.setField(mPicker, "mPm", mPackageManager); - when(mPicker.getContext()).thenReturn(RuntimeEnvironment.application); - } - - @Test - public void setDefaultAppKey_shouldUpdateDefault() { - mPicker.setDefaultKey(TEST_APP_KEY); - verify(mRoleManager).addRoleHolderAsUser( - eq(RoleManager.ROLE_EMERGENCY), - eq(TEST_APP_KEY), - eq(0), - any(UserHandle.class), - any(Executor.class), - any(Consumer.class)); - } - - @Test - public void getDefaultAppKey_shouldReturnDefault() { - when(mRoleManager.getRoleHolders(RoleManager.ROLE_EMERGENCY)) - .thenReturn(Arrays.asList(TEST_APP_KEY)); - assertThat(mPicker.getDefaultKey()).isEqualTo(TEST_APP_KEY); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java deleted file mode 100644 index be4fdbfb4d8..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java +++ /dev/null @@ -1,168 +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.applications.defaultapps; - -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.anyList; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -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 static org.mockito.Mockito.when; - -import android.app.Activity; -import android.app.AppOpsManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; -import android.os.Build; -import android.os.UserManager; - -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settingslib.applications.DefaultAppInfo; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class DefaultHomePickerTest { - - private static final String TEST_APP_KEY = "com.android.settings/DefaultEmergencyPickerTest"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Activity mActivity; - @Mock - private UserManager mUserManager; - @Mock - private AppOpsManager mAppOpsManager; - @Mock - private PackageManager mPackageManager; - - private Context mContext; - private DefaultHomePicker mPicker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - FakeFeatureFactory.setupForTest(); - - when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - when(mActivity.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); - when(mActivity.getApplicationContext()).thenReturn(RuntimeEnvironment.application); - - mPicker = spy(new DefaultHomePicker()); - mPicker.onAttach((Context) mActivity); - - ReflectionHelpers.setField(mPicker, "mPm", mPackageManager); - mContext = spy(RuntimeEnvironment.application); - doReturn(mContext).when(mPicker).getContext(); - } - - @Test - public void setDefaultAppKey_shouldUpdateDefault() { - assertThat(mPicker.setDefaultKey(TEST_APP_KEY)).isTrue(); - - verify(mPackageManager).replacePreferredActivity(any(IntentFilter.class), - anyInt(), any(ComponentName[].class), any(ComponentName.class)); - verify(mContext).startActivity(any()); - } - - @Test - public void getDefaultAppKey_shouldReturnDefault() { - final ComponentName cn = mock(ComponentName.class); - when(mPackageManager.getHomeActivities(anyList())).thenReturn(cn); - mPicker.getDefaultKey(); - verify(cn).flattenToString(); - } - - @Test - public void getCandidates_allLaunchersAvailableIfNoManagedProfile() { - addLaunchers(); - List candidates = mPicker.getCandidates(); - assertThat(candidates.size()).isEqualTo(2); - assertThat(candidates.get(0).summary).isNull(); - assertThat(candidates.get(0).enabled).isTrue(); - assertThat(candidates.get(1).summary).isNull(); - assertThat(candidates.get(1).enabled).isTrue(); - } - - @Test - public void getCandidates_onlyLollipopPlusLaunchersAvailableIfManagedProfile() { - List profiles = new ArrayList<>(); - profiles.add(new UserInfo(/*id=*/ 10, "TestUserName", UserInfo.FLAG_MANAGED_PROFILE)); - when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); - - addLaunchers(); - List candidates = mPicker.getCandidates(); - assertThat(candidates.size()).isEqualTo(2); - DefaultAppInfo lollipopPlusLauncher = candidates.get(0); - assertThat(lollipopPlusLauncher.summary).isNull(); - assertThat(lollipopPlusLauncher.enabled).isTrue(); - - DefaultAppInfo preLollipopLauncher = candidates.get(1); - assertThat(preLollipopLauncher.summary).isNotNull(); - assertThat(preLollipopLauncher.enabled).isFalse(); - } - - private ResolveInfo createLauncher( - String packageName, String className, int targetSdk) throws NameNotFoundException { - ResolveInfo launcher = new ResolveInfo(); - launcher.activityInfo = new ActivityInfo(); - launcher.activityInfo.packageName = packageName; - launcher.activityInfo.name = className; - ApplicationInfo launcherAppInfo = new ApplicationInfo(); - launcherAppInfo.targetSdkVersion = targetSdk; - when(mPackageManager.getApplicationInfo(eq(launcher.activityInfo.packageName), anyInt())) - .thenReturn(launcherAppInfo); - return launcher; - } - - private void addLaunchers() { - doAnswer(invocation -> { - // The result of this method is stored in the first parameter... - List parameter = (List) invocation.getArguments()[0]; - parameter.add(createLauncher( - "package.1", "LollipopPlusLauncher", Build.VERSION_CODES.LOLLIPOP)); - parameter.add(createLauncher( - "package.2", "PreLollipopLauncher", Build.VERSION_CODES.KITKAT)); - return null; - }) - .when(mPackageManager).getHomeActivities(anyList()); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java deleted file mode 100644 index c19b3159833..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java +++ /dev/null @@ -1,170 +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.applications.defaultapps; - -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.anyList; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.UserManager; - -import androidx.preference.Preference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(RobolectricTestRunner.class) -public class DefaultHomePreferenceControllerTest { - - private static final String TEST_PACKAGE = "test.pkg"; - private static final String TEST_CLASS = "class"; - - @Mock - private UserManager mUserManager; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private PackageManager mPackageManager; - - private Context mContext; - private DefaultHomePreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - - mController = spy(new DefaultHomePreferenceController(mContext)); - ReflectionHelpers.setField(mController, "mPackageManager", mPackageManager); - } - - @Test - public void testDefaultHome_byDefault_shouldBeShown() { - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - @Config(qualifiers = "mcc999") - public void testDefaultHome_ifDisabled_shouldNotBeShown() { - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void getDefaultApp_shouldGetDefaultBrowserPackage() { - assertThat(mController.getDefaultAppInfo()).isNotNull(); - - verify(mPackageManager).getHomeActivities(anyList()); - } - - @Test - public void getDefaultApp_noDefaultHome_shouldReturnNull() { - when(mPackageManager.getHomeActivities(anyList())).thenReturn(null); - - assertThat(mController.getDefaultAppInfo()).isNull(); - } - - @Test - public void updateState_noDefaultApp_shouldAskPackageManagerForOnlyApp() { - when(mPackageManager.getHomeActivities(anyList())).thenReturn(null); - mController.updateState(mock(Preference.class)); - - verify(mPackageManager, atLeastOnce()).getHomeActivities(anyList()); - } - - @Test - public void testIsHomeDefault_noDefaultSet_shouldReturnTrue() { - when(mPackageManager.getHomeActivities(anyList())).thenReturn(null); - assertThat(DefaultHomePreferenceController.isHomeDefault(TEST_PACKAGE, mPackageManager)) - .isTrue(); - } - - @Test - public void testIsHomeDefault_defaultSetToPkg_shouldReturnTrue() { - final String pkgName = TEST_PACKAGE; - final ComponentName defaultHome = new ComponentName(pkgName, TEST_CLASS); - - when(mPackageManager.getHomeActivities(anyList())).thenReturn(defaultHome); - - assertThat(DefaultHomePreferenceController.isHomeDefault(pkgName, mPackageManager)) - .isTrue(); - } - - @Test - public void testIsHomeDefault_defaultSetToOtherPkg_shouldReturnFalse() { - final String pkgName = TEST_PACKAGE; - final ComponentName defaultHome = new ComponentName("not" + pkgName, TEST_CLASS); - - when(mPackageManager.getHomeActivities(anyList())).thenReturn(defaultHome); - - assertThat(DefaultHomePreferenceController.isHomeDefault(pkgName, mPackageManager)) - .isFalse(); - } - - @Test - public void testGetSettingIntent_homeHasNoSetting_shouldNotReturnSettingIntent() { - when(mPackageManager.getHomeActivities(anyList())) - .thenReturn(new ComponentName(TEST_PACKAGE, TEST_CLASS)); - when(mPackageManager.resolveActivity(any(Intent.class), anyInt())) - .thenReturn(null); - - assertThat(mController.getSettingIntent(mController.getDefaultAppInfo())).isNull(); - } - - @Test - public void testGetSettingIntent_homeHasOneSetting_shouldReturnSettingIntent() { - when(mPackageManager.getHomeActivities(anyList())) - .thenReturn(new ComponentName(TEST_PACKAGE, TEST_CLASS)); - final ResolveInfo info = mock(ResolveInfo.class); - info.activityInfo = mock(ActivityInfo.class); - info.activityInfo.name = TEST_CLASS; - info.activityInfo.applicationInfo = mock(ApplicationInfo.class); - info.activityInfo.applicationInfo.packageName = TEST_PACKAGE; - when(mPackageManager.resolveActivity(any(Intent.class), anyInt())) - .thenReturn(info); - - Intent intent = mController.getSettingIntent(mController.getDefaultAppInfo()); - assertThat(intent).isNotNull(); - assertThat(intent.getPackage()).isEqualTo(TEST_PACKAGE); - } - - @Test - public void testGetSettingIntent_noDefauldHome_shouldReturnNull() { - when(mPackageManager.getHomeActivities(anyList())).thenReturn(null); - assertThat(mController.getSettingIntent(mController.getDefaultAppInfo())).isNull(); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java deleted file mode 100644 index 743b096508c..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java +++ /dev/null @@ -1,104 +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.applications.defaultapps; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserManager; - -import com.android.settings.fuelgauge.BatteryUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(RobolectricTestRunner.class) -public class DefaultPhonePickerTest { - - private static final String TEST_APP_KEY = "com.android.settings/PickerTest"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Activity mActivity; - @Mock - private UserManager mUserManager; - @Mock - private DefaultPhonePicker.DefaultKeyUpdater mDefaultKeyUpdater; - @Mock - private PackageManager mPackageManager; - @Mock - private BatteryUtils mBatteryUtils; - - private DefaultPhonePicker mPicker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - when(mActivity.getSystemService(Context.TELECOM_SERVICE)).thenReturn(null); - mPicker = spy(new DefaultPhonePicker()); - mPicker.onAttach(mActivity); - - ReflectionHelpers.setField(mPicker, "mPm", mPackageManager); - ReflectionHelpers.setField(mPicker, "mDefaultKeyUpdater", mDefaultKeyUpdater); - ReflectionHelpers.setField(mPicker, "mBatteryUtils", mBatteryUtils); - doReturn(RuntimeEnvironment.application).when(mPicker).getContext(); - } - - @Test - public void getSystemDefaultPackage_shouldAskDefaultKeyUpdater() { - mPicker.getSystemDefaultKey(); - - verify(mDefaultKeyUpdater).getSystemDialerPackage(); - } - - @Test - public void setDefaultAppKey_shouldUpdateDefault() { - mPicker.setDefaultKey(TEST_APP_KEY); - - verify(mDefaultKeyUpdater) - .setDefaultDialerApplication(any(Context.class), eq(TEST_APP_KEY), anyInt()); - } - - @Test - public void getDefaultAppKey_shouldReturnDefault() { - mPicker.getDefaultKey(); - - verify(mDefaultKeyUpdater).getDefaultDialerApplication(any(Context.class), anyInt()); - } - - @Test - public void setDefaultKey_shouldUnrestrictApp() { - mPicker.setDefaultKey(TEST_APP_KEY); - - verify(mBatteryUtils).clearForceAppStandby(TEST_APP_KEY); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java deleted file mode 100644 index 6fd65b25dd0..00000000000 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java +++ /dev/null @@ -1,94 +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.applications.defaultapps; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.UserManager; - -import com.android.settings.fuelgauge.BatteryUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(RobolectricTestRunner.class) -public class DefaultSmsPickerTest { - - private static final String TEST_APP_KEY = "com.android.settings/PickerTest"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Activity mActivity; - @Mock - private UserManager mUserManager; - @Mock - private DefaultSmsPicker.DefaultKeyUpdater mDefaultKeyUpdater; - @Mock - private PackageManager mPackageManager; - @Mock - private BatteryUtils mBatteryUtils; - - private DefaultSmsPicker mPicker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - mPicker = spy(new DefaultSmsPicker()); - mPicker.onAttach(mActivity); - - ReflectionHelpers.setField(mPicker, "mPm", mPackageManager); - ReflectionHelpers.setField(mPicker, "mDefaultKeyUpdater", mDefaultKeyUpdater); - ReflectionHelpers.setField(mPicker, "mBatteryUtils", mBatteryUtils); - doReturn(RuntimeEnvironment.application).when(mPicker).getContext(); - } - - @Test - public void setDefaultAppKey_shouldUpdateDefault() { - mPicker.setDefaultKey(TEST_APP_KEY); - - verify(mDefaultKeyUpdater).setDefaultApplication(any(Context.class), eq(TEST_APP_KEY)); - } - - @Test - public void getDefaultAppKey_shouldReturnDefault() { - mPicker.getDefaultKey(); - - verify(mDefaultKeyUpdater).getDefaultApplication(any(Context.class)); - } - - @Test - public void setDefaultKey_shouldUnrestrictApp() { - mPicker.setDefaultKey(TEST_APP_KEY); - - verify(mBatteryUtils).clearForceAppStandby(TEST_APP_KEY); - } -} From e2b4bccbf11887757635f3450073a0f84afa2386 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 8 Apr 2019 19:22:44 +0800 Subject: [PATCH 15/22] Should not decode Wi-Fi QR code after onPause Bug: 130141694 Test: manual atest WifiDppQrCodeScannerFragmentTest Change-Id: I412fb7c06220c23bddc7b3c448fcc72a00bdecc3 --- .../dpp/WifiDppQrCodeScannerFragment.java | 24 ++++++++++++++++++ .../settings/wifi/qrcode/QrCamera.java | 10 ++++++++ .../dpp/WifiDppQrCodeScannerFragmentTest.java | 25 +++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java index fa17f073803..d0322b7f4c8 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java +++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java @@ -47,6 +47,7 @@ import android.widget.TextView; import androidx.annotation.StringRes; import androidx.annotation.UiThread; +import androidx.annotation.VisibleForTesting; import androidx.lifecycle.ViewModelProviders; import com.android.settings.R; @@ -261,6 +262,24 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl }); } + @Override + public void onPause() { + if (mCamera != null) { + mCamera.stop(); + } + + super.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + + if (!isGoingInitiator()) { + restartCamera(); + } + } + @Override public int getMetricsCategory() { if (mIsConfiguratorMode) { @@ -702,4 +721,9 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl public void onAccessPointsChanged() { // Do nothing. } + + @VisibleForTesting + protected boolean isDecodeTaskAlive() { + return mCamera != null && mCamera.isDecodeTaskAlive(); + } } diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java index 45de6b5147c..b7d41baf0a2 100644 --- a/src/com/android/settings/wifi/qrcode/QrCamera.java +++ b/src/com/android/settings/wifi/qrcode/QrCamera.java @@ -401,4 +401,14 @@ public class QrCamera extends Handler { mScannerCallback.handleSuccessfulResult(qrCode.getText()); } } + + /** + * After {@link #start(SurfaceTexture)}, DecodingTask runs continuously to capture images and + * decode QR code. DecodingTask become null After {@link #stop()}. + * + * Uses this method in test case to prevent power consumption problem. + */ + public boolean isDecodeTaskAlive() { + return mDecodeTask != null; + } } diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java index 16be216f780..d633689eeff 100644 --- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java @@ -16,9 +16,16 @@ package com.android.settings.wifi.dpp; +import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.Instrumentation; import android.content.Intent; import android.content.pm.ActivityInfo; +import androidx.fragment.app.FragmentManager; +import androidx.test.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; @@ -38,6 +45,7 @@ public class WifiDppQrCodeScannerFragmentTest { Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP"); intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest"); + intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password"); mActivityRule.launchActivity(intent); } @@ -48,4 +56,21 @@ public class WifiDppQrCodeScannerFragmentTest { mActivityRule.getActivity().setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } + + @Test + public void onPause_shouldNotDecodeQrCode() { + final WifiDppConfiguratorActivity hostActivity = + (WifiDppConfiguratorActivity) mActivityRule.getActivity(); + final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager(); + final WifiDppQrCodeScannerFragment scannerFragment = + (WifiDppQrCodeScannerFragment) fragmentManager + .findFragmentByTag(TAG_FRAGMENT_QR_CODE_SCANNER); + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + + instrumentation.runOnMainSync(() -> { + instrumentation.callActivityOnPause(hostActivity); + + assertThat(scannerFragment.isDecodeTaskAlive()).isEqualTo(false); + }); + } } From 083243df7678b8849cfb1da437093c5d8f805a0c Mon Sep 17 00:00:00 2001 From: lindatseng Date: Mon, 8 Apr 2019 15:11:58 -0700 Subject: [PATCH 16/22] Fix panel slices title not updated when locale changed When calling getSliceData from SliceDataConverter, we were returning the old version of List if there's one already existed. So when the Locale get changed and we are re-indexing data, we are still inserting the old List in database. We should reconstruct the List of SliceData instead of reusing the old version here, since we only call SliceDataConverter#getSliceData when we need to reindex. Test: Manual verification Fixes: 126732022 Change-Id: I42a3cf93dc313efefe50a34faabac9e1d616ef6c --- .../android/settings/slices/SliceDataConverter.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java index db46c26d627..14abd1b8118 100644 --- a/src/com/android/settings/slices/SliceDataConverter.java +++ b/src/com/android/settings/slices/SliceDataConverter.java @@ -78,11 +78,8 @@ class SliceDataConverter { private Context mContext; - private List mSliceData; - public SliceDataConverter(Context context) { mContext = context; - mSliceData = new ArrayList<>(); } /** @@ -96,9 +93,7 @@ class SliceDataConverter { * {@link com.android.settings.core.BasePreferenceController}. */ public List getSliceData() { - if (!mSliceData.isEmpty()) { - return mSliceData; - } + List sliceData = new ArrayList<>(); final Collection indexableClasses = FeatureFactory.getFactory(mContext) .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues(); @@ -117,12 +112,12 @@ class SliceDataConverter { final List providerSliceData = getSliceDataFromProvider(provider, fragmentName); - mSliceData.addAll(providerSliceData); + sliceData.addAll(providerSliceData); } final List a11ySliceData = getAccessibilitySliceData(); - mSliceData.addAll(a11ySliceData); - return mSliceData; + sliceData.addAll(a11ySliceData); + return sliceData; } private List getSliceDataFromProvider(SearchIndexProvider provider, From 21ffc13e5aa1fc36cd8ad8da1aa5207d50937329 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Tue, 9 Apr 2019 17:23:06 +0800 Subject: [PATCH 17/22] Only enable feedback dialog in debuggable build. Bug: 129881534 Test: robotests Change-Id: I0dbd8c06f650cc7b3c32697f0c3af055912fab59 --- .../slices/SliceContextualCardController.java | 8 +++- .../SliceContextualCardControllerTest.java | 46 +++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java index eb062e8629f..07e23de5cb6 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java @@ -18,6 +18,7 @@ package com.android.settings.homepage.contextualcards.slices; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.text.TextUtils; import androidx.annotation.VisibleForTesting; @@ -82,7 +83,7 @@ public class SliceContextualCardController implements ContextualCardController { @VisibleForTesting void showFeedbackDialog(ContextualCard card) { final String email = mContext.getString(R.string.config_contextual_card_feedback_email); - if (TextUtils.isEmpty(email)) { + if (!isFeedbackEnabled(email)) { return; } final Intent feedbackIntent = new Intent(mContext, ContextualCardFeedbackDialog.class); @@ -93,6 +94,11 @@ public class SliceContextualCardController implements ContextualCardController { mContext.startActivity(feedbackIntent); } + @VisibleForTesting + boolean isFeedbackEnabled(String email) { + return !TextUtils.isEmpty(email) && Build.IS_DEBUGGABLE; + } + private String getSimpleCardName(ContextualCard card) { final String[] split = card.getName().split("/"); return split[split.length - 1]; diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java index e97e01e9701..94fbb978767 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardControllerTest.java @@ -18,8 +18,10 @@ package com.android.settings.homepage.contextualcards.slices; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -28,7 +30,9 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; +import android.os.Build; +import com.android.settings.R; import com.android.settings.homepage.contextualcards.CardContentProvider; import com.android.settings.homepage.contextualcards.CardDatabaseHelper; import com.android.settings.homepage.contextualcards.ContextualCard; @@ -48,6 +52,7 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowContentResolver; import org.robolectric.shadows.androidx.fragment.FragmentController; +import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class SliceContextualCardControllerTest { @@ -95,11 +100,12 @@ public class SliceContextualCardControllerTest { } @Test - public void onDismissed_noFeedbackEmail_shouldNotShowFeedbackDialog() { + public void onDismissed_feedbackDisabled_shouldNotShowFeedbackDialog() { mResolver.insert(CardContentProvider.REFRESH_CARD_URI, generateOneRow()); final ContextualCardsFragment fragment = FragmentController.of(new ContextualCardsFragment()).create().get(); final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity()); + doReturn(false).when(mController).isFeedbackEnabled(anyString()); mController.onDismissed(getTestSliceCard()); @@ -107,12 +113,12 @@ public class SliceContextualCardControllerTest { } @Test - @Config(qualifiers = "mcc999") - public void onDismissed_hasFeedbackEmail_shouldShowFeedbackDialog() { + public void onDismissed_feedbackEnabled_shouldShowFeedbackDialog() { mResolver.insert(CardContentProvider.REFRESH_CARD_URI, generateOneRow()); final ContextualCardsFragment fragment = FragmentController.of(new ContextualCardsFragment()).create().get(); final ShadowActivity shadowActivity = Shadows.shadowOf(fragment.getActivity()); + doReturn(true).when(mController).isFeedbackEnabled(anyString()); mController.onDismissed(getTestSliceCard()); @@ -120,6 +126,40 @@ public class SliceContextualCardControllerTest { .isEqualTo(ContextualCardFeedbackDialog.class.getName()); } + @Test + @Config(qualifiers = "mcc999") + public void isFeedbackEnabled_hasFeedbackEmail_debug_returnTrue() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); + final String email = mContext.getString(R.string.config_contextual_card_feedback_email); + + assertThat(mController.isFeedbackEnabled(email)).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void isFeedbackEnabled_hasFeedbackEmail_user_returnFalse() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); + final String email = mContext.getString(R.string.config_contextual_card_feedback_email); + + assertThat(mController.isFeedbackEnabled(email)).isFalse(); + } + + @Test + public void isFeedbackEnabled_noFeedbackEmail_debug_returnFalse() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); + final String email = mContext.getString(R.string.config_contextual_card_feedback_email); + + assertThat(mController.isFeedbackEnabled(email)).isFalse(); + } + + @Test + public void isFeedbackEnabled_noFeedbackEmail_user_returnFalse() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); + final String email = mContext.getString(R.string.config_contextual_card_feedback_email); + + assertThat(mController.isFeedbackEnabled(email)).isFalse(); + } + private ContentValues generateOneRow() { final ContentValues values = new ContentValues(); values.put(CardDatabaseHelper.CardColumns.NAME, TEST_CARD_NAME); From dc2b2c7929ffbf4d30a549e8df692885d2fc873e Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Fri, 29 Mar 2019 22:44:27 +0800 Subject: [PATCH 18/22] Inflate dismissal background instead of drawing while swiping - Only swipe the foreground out to have the background revealed. - Inflate dismissal_swipe_background.xml while swiping. - Fix the fly-in transition. - Fix the overlapping problem. Bug: 129742618 Test: robotests Change-Id: I5311e50332d0ea0437d1693d075d5c3a2176a443 --- res/layout/dismissal_swipe_background.xml | 46 +++++++++++++ res/layout/homepage_slice_half_tile.xml | 64 ++++++++++-------- res/layout/homepage_slice_tile.xml | 38 +++++++---- res/values/styles.xml | 1 + .../slices/SliceFullCardRendererHelper.java | 3 + .../slices/SwipeDismissalDelegate.java | 65 +++++++++---------- .../SliceContextualCardRendererTest.java | 4 +- .../slices/SwipeDismissalDelegateTest.java | 4 +- 8 files changed, 147 insertions(+), 78 deletions(-) create mode 100644 res/layout/dismissal_swipe_background.xml diff --git a/res/layout/dismissal_swipe_background.xml b/res/layout/dismissal_swipe_background.xml new file mode 100644 index 00000000000..49e612993cb --- /dev/null +++ b/res/layout/dismissal_swipe_background.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/homepage_slice_half_tile.xml b/res/layout/homepage_slice_half_tile.xml index 8b6d41525cb..205279dd795 100644 --- a/res/layout/homepage_slice_half_tile.xml +++ b/res/layout/homepage_slice_half_tile.xml @@ -21,41 +21,49 @@ android:layout_height="wrap_content" style="@style/ContextualCardStyle"> - - + + + android:layout_height="match_parent"> - - - + android:layout_height="match_parent" + android:paddingEnd="@dimen/homepage_card_padding_end" + android:paddingTop="@dimen/homepage_half_card_padding_top" + android:paddingBottom="@dimen/homepage_half_card_padding_bottom" + android:background="@color/contextual_card_background" + android:orientation="vertical"> - + - - + - + + + + + + + \ No newline at end of file diff --git a/res/layout/homepage_slice_tile.xml b/res/layout/homepage_slice_tile.xml index ca8791f9c07..b996c7e4777 100644 --- a/res/layout/homepage_slice_tile.xml +++ b/res/layout/homepage_slice_tile.xml @@ -21,21 +21,35 @@ android:layout_height="wrap_content" style="@style/ContextualCardStyle"> - + android:layout_height="match_parent"> - + + + android:layout_height="wrap_content"> - - + - + + + + + + + + \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index 8cd22fe4e96..8c3a633fb43 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -492,6 +492,7 @@ 8dp @style/SliceRowStyle + @color/contextual_card_background