diff options
author | 2024-01-18 12:14:22 -0800 | |
---|---|---|
committer | 2024-01-24 17:36:37 -0800 | |
commit | 506904759615bef94dceb9e672432f5c33efb1af (patch) | |
tree | 44a10e9e534b121c845e1709ffb00b174f9b04f2 /framework-s/java | |
parent | b354559c5103d24c4669617e603d020581c9e1d9 (diff) |
[ECM] Create EnhancedConfirmationService
This change:
1. Defines EnhancedConfirmationService, a new SystemService
2. Defines IEnhancedConfirmationManager, a new binder interface
implemented within EnhancedConfirmationService
3. Injects EnhancedConfirmationService into EnhancedConfirmationManager
4. Moves the bulk of EnhancedConfirmationManager's logic into
EnhancedConfirmationService
Bug: 321053639
Test: atest CtsPermissionUiTestCases:android.permissionui.cts.EnhancedConfirmationManagerTest
Change-Id: Ib6fbf4dde07391314bfd2a64f22bab79a6cebd23
Diffstat (limited to 'framework-s/java')
3 files changed, 71 insertions, 108 deletions
diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java b/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java index b4c18573a..1a42f7ee2 100644 --- a/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java @@ -45,6 +45,7 @@ public class EnhancedConfirmationFrameworkInitializer { public static void registerServiceWrappers() { SystemServiceRegistry.registerContextAwareService(Context.ECM_ENHANCED_CONFIRMATION_SERVICE, EnhancedConfirmationManager.class, - (context) -> new EnhancedConfirmationManager(context)); + (context, serviceBinder) -> new EnhancedConfirmationManager(context, + IEnhancedConfirmationManager.Stub.asInterface(serviceBinder))); } } diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java index 4f1edb092..fa745a52f 100644 --- a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java @@ -25,17 +25,13 @@ import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.InstallSourceInfo; -import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; -import android.os.UserHandle; +import android.os.RemoteException; import android.permission.flags.Flags; import android.provider.Settings; import android.util.ArraySet; -import android.util.Log; import androidx.annotation.NonNull; @@ -217,20 +213,18 @@ public final class EnhancedConfirmationManager { } private final @NonNull Context mContext; - private final String mAttributionTag; - private final @NonNull UserHandle mUser; - private final AppOpsManager mAppOpsManager; private final PackageManager mPackageManager; + private final @NonNull IEnhancedConfirmationManager mService; + /** * @hide */ - public EnhancedConfirmationManager(@NonNull Context context) { + public EnhancedConfirmationManager(@NonNull Context context, + @NonNull IEnhancedConfirmationManager service) { mContext = context; - mAttributionTag = context.getAttributionTag(); - mUser = context.getUser(); - mAppOpsManager = context.getSystemService(AppOpsManager.class); mPackageManager = context.getPackageManager(); + mService = service; } /** @@ -247,7 +241,14 @@ public final class EnhancedConfirmationManager { */ public boolean isRestricted(@NonNull String packageName, @NonNull String settingIdentifier) throws NameNotFoundException { - return isSettingEcmProtected(settingIdentifier) && isPackageEcmGuarded(packageName); + try { + return mService.isRestricted(packageName, settingIdentifier, + mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -261,10 +262,13 @@ public final class EnhancedConfirmationManager { * @throws NameNotFoundException if the provided package was not found */ public void clearRestriction(@NonNull String packageName) throws NameNotFoundException { - if (!isClearRestrictionAllowed(packageName)) { - throw new IllegalStateException("Clear restriction attempted but not allowed"); + try { + mService.clearRestriction(packageName, mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } - setAppEcmState(packageName, EcmState.ECM_STATE_NOT_GUARDED); } /** @@ -281,8 +285,14 @@ public final class EnhancedConfirmationManager { */ public boolean isClearRestrictionAllowed(@NonNull String packageName) throws NameNotFoundException { - int state = getAppEcmState(packageName); - return state == EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED; + try { + return mService.isClearRestrictionAllowed(packageName, + mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -293,13 +303,16 @@ public final class EnhancedConfirmationManager { * * @param packageName package name of the application which should be considered acknowledged * @throws NameNotFoundException if the provided package was not found - * * @hide */ public void setClearRestrictionAllowed(@NonNull String packageName) throws NameNotFoundException { - if (isPackageEcmGuarded(packageName)) { - setAppEcmState(packageName, EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED); + try { + mService.setClearRestrictionAllowed(packageName, mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -321,92 +334,8 @@ public final class EnhancedConfirmationManager { return PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE); } - private boolean isPackageEcmGuarded(@NonNull String packageName) throws NameNotFoundException { - // If this is a trusted installer or a pre-installed app, it is not ECM guarded - if (isAppTrustedInstaller(packageName) || isPackagePreinstalled(packageName)) { - return false; - } - - // If the package already has an explicitly-set state, use that - @EcmState int ecmState = getAppEcmState(packageName); - if (ecmState == EcmState.ECM_STATE_GUARDED - || ecmState == EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED) { - return true; - } - if (ecmState == EcmState.ECM_STATE_NOT_GUARDED) { - return false; - } - - // Otherwise, lazily decide whether the app is considered guarded. - InstallSourceInfo installSource; - try { - installSource = mPackageManager.getInstallSourceInfo(packageName); - } catch (NameNotFoundException e) { - Log.w(LOG_TAG, "Package not found: " + packageName); - return false; - } - - // These install sources are always considered dangerous. - // PackageInstallers that are trusted can use these as a signal that the - // packages they've installed aren't as trusted as themselves. - int packageSource = installSource.getPackageSource(); - if (packageSource == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE - || packageSource == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) { - return true; - } - - // ECM doesn't consider a transitive chain of trust for install sources. - // If this package hasn't been explicitly handled by this point - // then it is exempt from ECM if the immediate parent is a trusted installer - boolean installedFromTrustedInstaller = installSource.getInstallingPackageName() != null - && isAppTrustedInstaller(installSource.getInstallingPackageName()); - return !installedFromTrustedInstaller; - } - - /** - * A "trusted installer" is any app with the INSTALL_PACKAGES permission. - */ - private boolean isAppTrustedInstaller(@NonNull String packageName) - throws NameNotFoundException { - int uid = getPackageUid(packageName); - // TODO(b/310654834): Support allow-list for OEM installer exemptions - return mContext.checkPermission(android.Manifest.permission.INSTALL_PACKAGES, 0, uid) - == PackageManager.PERMISSION_GRANTED; - } - - private boolean isPackagePreinstalled(@NonNull String packageName) { - ApplicationInfo applicationInfo; - try { - applicationInfo = mPackageManager.getApplicationInfoAsUser(packageName, 0, mUser); - } catch (NameNotFoundException e) { - Log.w(LOG_TAG, "Package not found: " + packageName); - return false; - } - return ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); - } - - private void setAppEcmState(@NonNull String packageName, @EcmState int ecmState) - throws NameNotFoundException { - mAppOpsManager.setMode(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, - getPackageUid(packageName), packageName, ecmState); - } - - private @EcmState int getAppEcmState(@NonNull String packageName) throws NameNotFoundException { - return mAppOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, - getPackageUid(packageName), packageName, mAttributionTag, /* message */ - null); - } - - private boolean isSettingEcmProtected(@NonNull String settingIdentifier) { - if (PROTECTED_SETTINGS.contains(settingIdentifier)) { - return true; - } - // TODO(b/310654818): If this is a permission, coerce it into a PermissionGroup. - // TODO(b/310218979): Add role selections as protected settings - return false; - } - private int getPackageUid(String packageName) throws NameNotFoundException { - return mPackageManager.getApplicationInfoAsUser(packageName, /* flags */ 0, mUser).uid; + return mPackageManager.getApplicationInfoAsUser(packageName, /* flags */ 0, + mContext.getUser()).uid; } } diff --git a/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl new file mode 100644 index 000000000..5149daa49 --- /dev/null +++ b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 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 android.app.ecm; + +import android.os.RemoteCallback; + +/** + * @hide + */ +interface IEnhancedConfirmationManager { + + boolean isRestricted(in String packageName, in String settingIdentifier, int userId); + + void clearRestriction(in String packageName, int userId); + + boolean isClearRestrictionAllowed(in String packageName, int userId); + + void setClearRestrictionAllowed(in String packageName, int userId); +} |