From 520b8d0e54754082c5068bb37a069bf676063ce2 Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Wed, 4 Jan 2023 09:40:38 +0000 Subject: [PATCH 1/9] Add DISALLOW_APPS_CONTROL check into uninstall app for all users Settings App info page supports a "Uninstall for all users" function when multiple users are enabled. It bypasses the restriction of DISALLOW_APPS_CONTROL which breaks the user isolation guideline. To fix this vulnerability, we should check the DISALLOW_APPS_CONTROL restriction to provide the "Uninstall for all users" function. Bug: 258653813 Test: manual & robotests Change-Id: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6 Merged-In: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6 (cherry picked from commit 16500a7ada6b0730bec2787055667c4394fa3468) Merged-In: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6 --- .../applications/appinfo/AppInfoDashboardFragment.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) mode change 100755 => 100644 src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java old mode 100755 new mode 100644 index b6251fe47c8..0a81cc16793 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -395,7 +395,13 @@ public void onPrepareOptionsMenu(Menu menu) { return; } super.onPrepareOptionsMenu(menu); - menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry)); + final MenuItem uninstallAllUsersItem = menu.findItem(UNINSTALL_ALL_USERS_MENU); + uninstallAllUsersItem.setVisible( + shouldShowUninstallForAll(mAppEntry) && !mAppsControlDisallowedBySystem); + if (uninstallAllUsersItem.isVisible()) { + RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getActivity(), + uninstallAllUsersItem, mAppsControlDisallowedAdmin); + } mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES); final boolean uninstallUpdateDisabled = getContext().getResources().getBoolean( From 2014f440f5d34648414937423377e0bfbd9ef8f4 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 21 Nov 2022 15:04:24 +0800 Subject: [PATCH 2/9] Settings 2-pane deep link vulnerabilities Settings app must not start an deep link Activity if 1. The deep link Activity is not exported. or 2. Calling package does not have the permission to start the deep link Activity. Bug: 250589026 Test: make RunSettingsRoboTests ROBOTEST_FILTER=SettingsHomepageActivityTest Change-Id: I9a3bddfa5d9d1d2e924dd6f3e5e07dca6c11664f Merged-In: I9a3bddfa5d9d1d2e924dd6f3e5e07dca6c11664f (cherry picked from commit 434c8934c4aa416931a66626016d94712e47d617) Merged-In: I9a3bddfa5d9d1d2e924dd6f3e5e07dca6c11664f --- .../homepage/SettingsHomepageActivity.java | 36 +++++++++++++++++++ .../SettingsHomepageActivityTest.java | 35 ++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index 183a2fbf5f5..4726059455e 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -25,6 +25,8 @@ import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.Bundle; import android.text.TextUtils; @@ -38,6 +40,7 @@ import android.widget.ImageView; import android.widget.Toolbar; +import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -55,6 +58,7 @@ import com.android.settings.core.FeatureFlags; import com.android.settings.homepage.contextualcards.ContextualCardsFragment; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.password.PasswordUtils; import com.android.settingslib.Utils; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; @@ -351,6 +355,32 @@ private void launchDeepLinkIntentToRight() { finish(); return; } + + if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), + getPackageName())) { + ActivityInfo targetActivityInfo = null; + try { + targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, + /* flags= */ 0); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Failed to get target ActivityInfo: " + e); + finish(); + return; + } + + if (!targetActivityInfo.exported) { + Log.e(TAG, "Must not launch an unexported Actvity for deep link"); + finish(); + return; + } + + if (!isCallingAppPermitted(targetActivityInfo.permission)) { + Log.e(TAG, "Calling app must have the permission of deep link Activity"); + finish(); + return; + } + } + targetIntent.setComponent(targetComponentName); // To prevent launchDeepLinkIntentToRight again for configuration change. @@ -386,6 +416,12 @@ private void launchDeepLinkIntentToRight() { startActivity(targetIntent); } + @VisibleForTesting + boolean isCallingAppPermitted(String permission) { + return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( + this, getActivityToken(), permission); + } + private String getHighlightMenuKey() { final Intent intent = getIntent(); if (intent != null && TextUtils.equals(intent.getAction(), diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java index 4d203a8a6b0..4de8b005c3c 100644 --- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java +++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -37,9 +39,11 @@ import com.android.settings.R; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest; +import com.android.settings.testutils.shadow.ShadowPasswordUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -66,6 +70,11 @@ public void setUp() { MockitoAnnotations.initMocks(this); } + @After + public void tearDown() { + ShadowPasswordUtils.reset(); + } + @Test public void launch_shouldHaveAnimationForIaFragment() { final SettingsHomepageActivity activity = Robolectric.buildActivity( @@ -195,6 +204,32 @@ public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } + @Test + @Config(shadows = {ShadowPasswordUtils.class}) + public void isCallingAppPermitted_emptyPermission_returnTrue() { + SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); + + assertTrue(homepageActivity.isCallingAppPermitted("")); + } + + @Test + @Config(shadows = {ShadowPasswordUtils.class}) + public void isCallingAppPermitted_noGrantedPermission_returnFalse() { + SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); + + assertFalse(homepageActivity.isCallingAppPermitted("android.permission.TEST")); + } + + @Test + @Config(shadows = {ShadowPasswordUtils.class}) + public void isCallingAppPermitted_grantedPermission_returnTrue() { + SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); + String permission = "android.permission.TEST"; + ShadowPasswordUtils.addGrantedPermission(permission); + + assertTrue(homepageActivity.isCallingAppPermitted(permission)); + } + @Implements(SuggestionFeatureProviderImpl.class) public static class ShadowSuggestionFeatureProviderImpl { From 1dd8d3221580ae1abf05960ecddb7a22437ab508 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 12 Dec 2022 14:44:16 +0800 Subject: [PATCH 3/9] Allow 2-pane deep link to access unexported Activity If an Activity is not exported, the Activity still can be launched by components of the same application, applications with the same user ID, or privileged system components. Bug: 261678674 Bug: 250589026 Test: manual visual Launcher -> context menu -> Wallpaper & style Change-Id: I662df6cb287361b135e2c596abe946ddeb03bda4 Merged-In: I662df6cb287361b135e2c596abe946ddeb03bda4 (cherry picked from commit 04989073225435ffdbd04f795dcc99c269fa35d5) Merged-In: I662df6cb287361b135e2c596abe946ddeb03bda4 --- .../homepage/SettingsHomepageActivity.java | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index 4726059455e..073ce6ae3a0 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -29,6 +29,9 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.Bundle; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import android.util.ArraySet; import android.util.FeatureFlagUtils; @@ -356,20 +359,19 @@ private void launchDeepLinkIntentToRight() { return; } - if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), - getPackageName())) { - ActivityInfo targetActivityInfo = null; - try { - targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, - /* flags= */ 0); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Failed to get target ActivityInfo: " + e); - finish(); - return; - } + ActivityInfo targetActivityInfo = null; + try { + targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, + /* flags= */ 0); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Failed to get target ActivityInfo: " + e); + finish(); + return; + } + if (!hasPrivilegedAccess(targetActivityInfo)) { if (!targetActivityInfo.exported) { - Log.e(TAG, "Must not launch an unexported Actvity for deep link"); + Log.e(TAG, "Target Activity is not exported"); finish(); return; } @@ -416,6 +418,46 @@ private void launchDeepLinkIntentToRight() { startActivity(targetIntent); } + // Check if calling app has privileged access to launch Activity of activityInfo. + private boolean hasPrivilegedAccess(ActivityInfo activityInfo) { + if (TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), + getPackageName())) { + return true; + } + + int callingUid = -1; + try { + callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken()); + } catch (RemoteException re) { + Log.e(TAG, "Not able to get callingUid: " + re); + return false; + } + + int targetUid = -1; + try { + targetUid = getPackageManager().getApplicationInfo(activityInfo.packageName, + /* flags= */ 0).uid; + } catch (PackageManager.NameNotFoundException nnfe) { + Log.e(TAG, "Not able to get targetUid: " + nnfe); + return false; + } + + // When activityInfo.exported is false, Activity still can be launched if applications have + // the same user ID. + if (UserHandle.isSameApp(callingUid, targetUid)) { + return true; + } + + // When activityInfo.exported is false, Activity still can be launched if calling app has + // root or system privilege. + int callingAppId = UserHandle.getAppId(callingUid); + if (callingAppId == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID) { + return true; + } + + return false; + } + @VisibleForTesting boolean isCallingAppPermitted(String permission) { return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( From 645e563889ad020b96369e117fc22ec881c1cac0 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 14 Dec 2022 11:08:53 +0800 Subject: [PATCH 4/9] Check Uri permission for FLAG_GRANT_READ/WRITE_URI_PERMISSION To improve security, calling app must be granted Uri permission if it sets FLAG_GRANT_READ/WRITE_URI_PERMISSION in the Intent of ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY. Bug: 250589026 Test: manual Change-Id: I48f88c662b843212b1066369badff84cf98935a8 Merged-In: I48f88c662b843212b1066369badff84cf98935a8 (cherry picked from commit 0f7f913281fff39d533b4ae325ba2fd11f0ae204) Merged-In: I48f88c662b843212b1066369badff84cf98935a8 --- .../homepage/SettingsHomepageActivity.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index 073ce6ae3a0..0311ea3fbe9 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -369,7 +369,16 @@ private void launchDeepLinkIntentToRight() { return; } - if (!hasPrivilegedAccess(targetActivityInfo)) { + int callingUid = -1; + try { + callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken()); + } catch (RemoteException re) { + Log.e(TAG, "Not able to get callingUid: " + re); + finish(); + return; + } + + if (!hasPrivilegedAccess(callingUid, targetActivityInfo)) { if (!targetActivityInfo.exported) { Log.e(TAG, "Target Activity is not exported"); finish(); @@ -400,6 +409,19 @@ private void launchDeepLinkIntentToRight() { targetIntent.setData(intent.getParcelableExtra( SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA)); + // Only allow FLAG_GRANT_READ/WRITE_URI_PERMISSION if calling app has the permission to + // access specified Uri. + int uriPermissionFlags = targetIntent.getFlags() + & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + if (targetIntent.getData() != null + && uriPermissionFlags != 0 + && checkUriPermission(targetIntent.getData(), /* pid= */ -1, callingUid, + uriPermissionFlags) == PackageManager.PERMISSION_DENIED) { + Log.e(TAG, "Calling app must have the permission to access Uri and grant permission"); + finish(); + return; + } + // Set 2-pane pair rule for the deep link page. ActivityEmbeddingRulesController.registerTwoPanePairRule(this, new ComponentName(getApplicationContext(), getClass()), @@ -419,20 +441,12 @@ private void launchDeepLinkIntentToRight() { } // Check if calling app has privileged access to launch Activity of activityInfo. - private boolean hasPrivilegedAccess(ActivityInfo activityInfo) { + private boolean hasPrivilegedAccess(int callingUid, ActivityInfo activityInfo) { if (TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), getPackageName())) { return true; } - int callingUid = -1; - try { - callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken()); - } catch (RemoteException re) { - Log.e(TAG, "Not able to get callingUid: " + re); - return false; - } - int targetUid = -1; try { targetUid = getPackageManager().getApplicationInfo(activityInfo.packageName, From 82a4095b053b83b22e5da5ea7eab94b330f4f3d2 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Thu, 28 Jul 2022 19:42:27 +0800 Subject: [PATCH 5/9] Only primary user is allowed to control secure nfc Bug: 238298970 Test: manual Merged-In: I945490ef1e62af479a732c9a260ed94bdd8bc313 Change-Id: I945490ef1e62af479a732c9a260ed94bdd8bc313 (cherry picked from commit 0e57ff90cdae3575c243d21d490e2b6384d33397) Merged-In: I945490ef1e62af479a732c9a260ed94bdd8bc313 --- src/com/android/settings/nfc/SecureNfcEnabler.java | 2 +- src/com/android/settings/nfc/SecureNfcPreferenceController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/nfc/SecureNfcEnabler.java b/src/com/android/settings/nfc/SecureNfcEnabler.java index f31a382a571..ad5c4ab7e83 100644 --- a/src/com/android/settings/nfc/SecureNfcEnabler.java +++ b/src/com/android/settings/nfc/SecureNfcEnabler.java @@ -61,7 +61,7 @@ protected void handleNfcStateChanged(int newState) { } private boolean isToggleable() { - if (mUserManager.isGuestUser()) { + if (!mUserManager.isPrimaryUser()) { return false; } return true; diff --git a/src/com/android/settings/nfc/SecureNfcPreferenceController.java b/src/com/android/settings/nfc/SecureNfcPreferenceController.java index cf43ec30ded..460eca3c142 100644 --- a/src/com/android/settings/nfc/SecureNfcPreferenceController.java +++ b/src/com/android/settings/nfc/SecureNfcPreferenceController.java @@ -109,7 +109,7 @@ public void onPause() { } private boolean isToggleable() { - if (mUserManager.isGuestUser()) { + if (!mUserManager.isPrimaryUser()) { return false; } return true; From 2f942be928224e930544dfc547dc4a3e8b3208a3 Mon Sep 17 00:00:00 2001 From: Valentin Iftime Date: Mon, 6 Feb 2023 15:11:28 +0100 Subject: [PATCH 6/9] [DO NOT MERGE] Enforce INTERACT_ACROSS_USERS_FULL permission for NotificationAccessDetails When using EXTRA_USER_HANDLE, check for INTERACT_ACROSS_USERS_FULL permission on calling package. Bug: 259385017 Test: 1. Build a test app that creates and starts an intent to NOTIFICATION_LISTENER_DETAIL_SETTINGS while setting the intent extra android.intent.extra.user_handle to UserHandle(secondaryUserId). 2. Create and switch to a secondary user Settings > System > Multiple users > Allow multiple users > Add user > Switch to New user 3. Open Settings > Notifications > Device & app notifications and choose an app from the list (uses android.permission.BIND_NOTIFICATION_LISTENER_SERVICE). Enable Device & app notifications for selected app and disable all attributed permissions. 4. Switch back to the Owner user. 5. Get the userId of the secondary user: adb shell pm list users. 6. Open the test app and enter the userId for the secondary user and the component name that uses android.permission.BIND_NOTIFICATION_LISTENER_SERVICE. 8. In the settings window that open, enable all 4 sub-options. 9. Switch to the secondary user and note that the all sub-options for the app are disabled. Change-Id: I875b9f2fc32c252acdcf8374a14067836e0f1ac6 (cherry picked from commit on googleplex-android-review.googlesource.com host: 9a7bd79ca3ba7918e78e88b9638524887473d16c) Merged-In: I875b9f2fc32c252acdcf8374a14067836e0f1ac6 --- .../NotificationAccessDetails.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java index da25f17c138..6532413b610 100644 --- a/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java +++ b/src/com/android/settings/applications/specialaccess/notificationaccess/NotificationAccessDetails.java @@ -16,8 +16,11 @@ package com.android.settings.applications.specialaccess.notificationaccess; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME; +import android.Manifest; import android.app.Activity; import android.app.NotificationManager; import android.app.settings.SettingsEnums; @@ -39,6 +42,7 @@ import android.provider.Settings; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; +import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -53,6 +57,7 @@ import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.notification.NotificationBackend; +import com.android.settings.password.PasswordUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; @@ -208,8 +213,12 @@ protected void retrieveAppEntry() { } } if (intent != null && intent.hasExtra(Intent.EXTRA_USER_HANDLE)) { - mUserId = ((UserHandle) intent.getParcelableExtra( - Intent.EXTRA_USER_HANDLE)).getIdentifier(); + if (hasInteractAcrossUsersPermission()) { + mUserId = ((UserHandle) intent.getParcelableExtra( + Intent.EXTRA_USER_HANDLE)).getIdentifier(); + } else { + finish(); + } } else { mUserId = UserHandle.myUserId(); } @@ -224,6 +233,26 @@ protected void retrieveAppEntry() { } } + private boolean hasInteractAcrossUsersPermission() { + final String callingPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + + if (TextUtils.isEmpty(callingPackageName)) { + Log.w(TAG, "Not able to get calling package name for permission check"); + return false; + } + + if (getContext().getPackageManager().checkPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingPackageName) + != PERMISSION_GRANTED) { + Log.w(TAG, "Package " + callingPackageName + " does not have required permission " + + Manifest.permission.INTERACT_ACROSS_USERS_FULL); + return false; + } + + return true; + } + // Dialogs only have access to the parent fragment, not the controller, so pass the information // along to keep business logic out of this file public void disable(final ComponentName cn) { From 8074aca4a3c854dd4d8a9e8f9e062490ee4468e9 Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Tue, 7 Mar 2023 10:36:41 -0800 Subject: [PATCH 7/9] Convert argument to intent in AddAccountSettings. Bug: 265798353 Test: manual (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c7e8052b527434ed8660e3babdab718f7f3cd7da) Merged-In: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a Change-Id: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a --- src/com/android/settings/accounts/AddAccountSettings.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/accounts/AddAccountSettings.java b/src/com/android/settings/accounts/AddAccountSettings.java index 81db4df3290..85e942b1990 100644 --- a/src/com/android/settings/accounts/AddAccountSettings.java +++ b/src/com/android/settings/accounts/AddAccountSettings.java @@ -103,7 +103,8 @@ public void run(AccountManagerFuture future) { intent.putExtras(addAccountOptions) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivityForResultAsUser(intent, ADD_ACCOUNT_REQUEST, mUserHandle); + startActivityForResultAsUser( + new Intent(intent), ADD_ACCOUNT_REQUEST, mUserHandle); } else { setResult(RESULT_OK); if (mPendingIntent != null) { From a2ec2b5d4872d44ffbac4a45725129b6b9e66613 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Tue, 7 Mar 2023 15:44:29 -0500 Subject: [PATCH 8/9] Don't show NLSes with excessively long component names Test: install test app with long CN Test: ServiceListingTest Bug: 260570119 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:52a102cc2a408657230c757054e6979e1c76d6fb) Merged-In: I3ffd02f6cf6bf282e7fc264fd070ed3add4d8571 Change-Id: I3ffd02f6cf6bf282e7fc264fd070ed3add4d8571 --- .../settings/notification/NotificationAccessSettings.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java index 10954a185e1..d94498e68f7 100644 --- a/src/com/android/settings/notification/NotificationAccessSettings.java +++ b/src/com/android/settings/notification/NotificationAccessSettings.java @@ -62,6 +62,7 @@ public class NotificationAccessSettings extends EmptyTextSettings { private static final String TAG = "NotifAccessSettings"; private static final String ALLOWED_KEY = "allowed"; private static final String NOT_ALLOWED_KEY = "not_allowed"; + private static final int MAX_CN_LENGTH = 500; private static final ManagedServiceSettings.Config CONFIG = new ManagedServiceSettings.Config.Builder() @@ -98,6 +99,12 @@ public void onCreate(Bundle icicle) { .setNoun(CONFIG.noun) .setSetting(CONFIG.setting) .setTag(CONFIG.tag) + .setValidator(info -> { + if (info.getComponentName().flattenToString().length() > MAX_CN_LENGTH) { + return false; + } + return true; + }) .build(); mServiceListing.addCallback(this::updateList); From c5a654b69f1fa0e414d6c154fd978c631c335fc1 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 25 Apr 2023 12:30:03 -0400 Subject: [PATCH 9/9] Fix: Bluetooth and Wifi scanning location MainSwitch page policy transparency. When DISALLOW_CONFIG_LOCATION is set, make location service's MainSwitchPreference pages for wifi scanning and bluetooth scanning unavailable too, so that intent direct access is disabled. screenshot: http://shortn/_kkK3BMTSh1 Bug: 277333746 Bug: 277333781 Test: atest SettingsRoboTests, on device (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7591fff234886e79c5d0210a2cf3282a69de9be9) Merged-In: I52f9a11b1dd78a5e5dbb1bbde3cda7381c87ae39 Change-Id: I52f9a11b1dd78a5e5dbb1bbde3cda7381c87ae39 --- .../BluetoothScanningMainSwitchPreferenceController.java | 7 ++++++- .../WifiScanningMainSwitchPreferenceController.java | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java b/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java index b491ec953a2..78e31848acb 100644 --- a/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java +++ b/src/com/android/settings/location/BluetoothScanningMainSwitchPreferenceController.java @@ -18,6 +18,7 @@ import android.content.Context; import android.provider.Settings; import android.widget.Switch; +import android.os.UserManager; import androidx.preference.PreferenceScreen; @@ -33,9 +34,11 @@ public class BluetoothScanningMainSwitchPreferenceController extends TogglePrefe implements OnMainSwitchChangeListener { private static final String KEY_BLUETOOTH_SCANNING_SWITCH = "bluetooth_always_scanning_switch"; + private final UserManager mUserManager; public BluetoothScanningMainSwitchPreferenceController(Context context) { super(context, KEY_BLUETOOTH_SCANNING_SWITCH); + mUserManager = UserManager.get(context); } @Override @@ -49,7 +52,9 @@ public void displayPreference(PreferenceScreen screen) { @Override public int getAvailabilityStatus() { return mContext.getResources().getBoolean(R.bool.config_show_location_scanning) - ? AVAILABLE + ? (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_LOCATION) + ? DISABLED_DEPENDENT_SETTING + : AVAILABLE) : UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java b/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java index 546f1e1e399..e22b0a08026 100644 --- a/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java +++ b/src/com/android/settings/location/WifiScanningMainSwitchPreferenceController.java @@ -18,6 +18,7 @@ import android.content.Context; import android.net.wifi.WifiManager; import android.widget.Switch; +import android.os.UserManager; import androidx.preference.PreferenceScreen; @@ -34,10 +35,12 @@ public class WifiScanningMainSwitchPreferenceController extends TogglePreference private static final String KEY_WIFI_SCANNING_SWITCH = "wifi_always_scanning_switch"; private final WifiManager mWifiManager; + private final UserManager mUserManager; public WifiScanningMainSwitchPreferenceController(Context context) { super(context, KEY_WIFI_SCANNING_SWITCH); mWifiManager = context.getSystemService(WifiManager.class); + mUserManager = UserManager.get(context); } @Override @@ -52,7 +55,9 @@ public void displayPreference(PreferenceScreen screen) { @Override public int getAvailabilityStatus() { return mContext.getResources().getBoolean(R.bool.config_show_location_scanning) - ? AVAILABLE + ? (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_LOCATION) + ? DISABLED_DEPENDENT_SETTING + : AVAILABLE) : UNSUPPORTED_ON_DEVICE; }