diff options
3 files changed, 88 insertions, 4 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 0a6827cde3d3..d13137d4a716 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1124,9 +1124,24 @@ public class AppOpsManager { /** @hide */ public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE; + /** + * Phone call is using microphone + * + * @hide + */ + // TODO: Add as AppProtoEnums + public static final int OP_PHONE_CALL_MICROPHONE = 100; + /** + * Phone call is using camera + * + * @hide + */ + // TODO: Add as AppProtoEnums + public static final int OP_PHONE_CALL_CAMERA = 101; + /** @hide */ @UnsupportedAppUsage - public static final int _NUM_OP = 100; + public static final int _NUM_OP = 102; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1444,6 +1459,19 @@ public class AppOpsManager { */ public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; + /** + * Phone call is using microphone + * + * @hide + */ + public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone"; + /** + * Phone call is using camera + * + * @hide + */ + public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera"; + /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ @@ -1633,6 +1661,8 @@ public class AppOpsManager { OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE + OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE + OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA }; /** @@ -1739,6 +1769,8 @@ public class AppOpsManager { OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, OPSTR_NO_ISOLATED_STORAGE, + OPSTR_PHONE_CALL_MICROPHONE, + OPSTR_PHONE_CALL_CAMERA, }; /** @@ -1846,6 +1878,8 @@ public class AppOpsManager { "AUTO_REVOKE_PERMISSIONS_IF_UNUSED", "AUTO_REVOKE_MANAGED_BY_INSTALLER", "NO_ISOLATED_STORAGE", + "PHONE_CALL_MICROPHONE", + "PHONE_CALL_CAMERA", }; /** @@ -1954,6 +1988,8 @@ public class AppOpsManager { null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER null, // no permission for OP_NO_ISOLATED_STORAGE + null, // no permission for OP_PHONE_CALL_MICROPHONE + null, // no permission for OP_PHONE_CALL_CAMERA }; /** @@ -2062,6 +2098,8 @@ public class AppOpsManager { null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // NO_ISOLATED_STORAGE + null, // PHONE_CALL_MICROPHONE + null, // PHONE_CALL_MICROPHONE }; /** @@ -2169,6 +2207,8 @@ public class AppOpsManager { null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // NO_ISOLATED_STORAGE + null, // PHONE_CALL_MICROPHONE + null, // PHONE_CALL_CAMERA }; /** @@ -2275,6 +2315,8 @@ public class AppOpsManager { AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE + AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE + AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA }; /** @@ -2385,6 +2427,8 @@ public class AppOpsManager { false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED false, // AUTO_REVOKE_MANAGED_BY_INSTALLER true, // NO_ISOLATED_STORAGE + false, // PHONE_CALL_MICROPHONE + false, // PHONE_CALL_CAMERA }; /** diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 01841249f4ac..64b35caeeef2 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -19,6 +19,7 @@ package com.android.systemui.appops; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; +import android.location.LocationManager; import android.media.AudioManager; import android.media.AudioRecordingConfiguration; import android.os.Handler; @@ -66,6 +67,13 @@ public class AppOpsControllerImpl implements AppOpsController, private final AppOpsManager mAppOps; private final AudioManager mAudioManager; + private final LocationManager mLocationManager; + + // mLocationProviderPackages are cached and updated only occasionally + private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000; + private long mLastLocationProviderPackageUpdate; + private List<String> mLocationProviderPackages; + private H mBGHandler; private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>(); private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>(); @@ -82,8 +90,10 @@ public class AppOpsControllerImpl implements AppOpsController, protected static final int[] OPS = new int[] { AppOpsManager.OP_CAMERA, + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION }; @@ -104,6 +114,7 @@ public class AppOpsControllerImpl implements AppOpsController, mCallbacksByCode.put(OPS[i], new ArraySet<>()); } mAudioManager = audioManager; + mLocationManager = context.getSystemService(LocationManager.class); dumpManager.registerDumpable(TAG, this); } @@ -287,6 +298,26 @@ public class AppOpsControllerImpl implements AppOpsController, return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); } + /** + * Checks if a package is the current location provider. + * + * <p>Data is cached to avoid too many calls into system server + * + * @param packageName The package that might be the location provider + * + * @return {@code true} iff the package is the location provider. + */ + private boolean isLocationProvider(String packageName) { + long now = System.currentTimeMillis(); + + if (mLastLocationProviderPackageUpdate + LOCATION_PROVIDER_UPDATE_FREQUENCY_MS < now) { + mLastLocationProviderPackageUpdate = now; + mLocationProviderPackages = mLocationManager.getProviderPackages( + LocationManager.FUSED_PROVIDER); + } + + return mLocationProviderPackages.contains(packageName); + } /** * Does the app-op, uid and package name, refer to an operation that should be shown to the @@ -302,7 +333,13 @@ public class AppOpsControllerImpl implements AppOpsController, // does not correspond to a platform permission // which may be user sensitive, so for now always show it to the user. if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW - || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION) { + || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION + || appOpCode == AppOpsManager.OP_PHONE_CALL_CAMERA + || appOpCode == AppOpsManager.OP_PHONE_CALL_MICROPHONE) { + return true; + } + + if (appOpCode == AppOpsManager.OP_CAMERA && isLocationProvider(packageName)) { return true; } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index 2be69c10a77b..59118bf3534e 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -57,7 +57,8 @@ class PrivacyItemController @Inject constructor( @VisibleForTesting internal companion object { val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, - AppOpsManager.OP_RECORD_AUDIO) + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_PHONE_CALL_MICROPHONE) val OPS_LOCATION = intArrayOf( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION) @@ -248,9 +249,11 @@ class PrivacyItemController @Inject constructor( private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { val type: PrivacyType = when (appOpItem.code) { + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA - AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE else -> return null } |