Merge changes from topic "phone-call-indicators" into rvc-qpr-dev

* changes:
  Cache location provider pkg name
  Special case location provider camera accesses and show them as indicators
  Treat phone call mic/camera similar to other mic/camera app-ops
  Add app-ops for camera/mic use during phone call
This commit is contained in:
Philip P. Moltmann
2020-08-20 19:30:31 +00:00
committed by Android (Google) Code Review
3 changed files with 88 additions and 4 deletions

View File

@@ -1124,9 +1124,24 @@ public class AppOpsManager {
/** @hide */ /** @hide */
public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE; 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 */ /** @hide */
@UnsupportedAppUsage @UnsupportedAppUsage
public static final int _NUM_OP = 100; public static final int _NUM_OP = 102;
/** Access to coarse location information. */ /** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; 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"; 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 */ /** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ /** 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_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE 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_PERMISSIONS_IF_UNUSED,
OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
OPSTR_NO_ISOLATED_STORAGE, 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_PERMISSIONS_IF_UNUSED",
"AUTO_REVOKE_MANAGED_BY_INSTALLER", "AUTO_REVOKE_MANAGED_BY_INSTALLER",
"NO_ISOLATED_STORAGE", "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_PERMISSIONS_IF_UNUSED
null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // no permission for OP_NO_ISOLATED_STORAGE 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_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // NO_ISOLATED_STORAGE 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_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
null, // NO_ISOLATED_STORAGE 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_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE 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_PERMISSIONS_IF_UNUSED
false, // AUTO_REVOKE_MANAGED_BY_INSTALLER false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
true, // NO_ISOLATED_STORAGE true, // NO_ISOLATED_STORAGE
false, // PHONE_CALL_MICROPHONE
false, // PHONE_CALL_CAMERA
}; };
/** /**

View File

@@ -19,6 +19,7 @@ package com.android.systemui.appops;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.AudioRecordingConfiguration; import android.media.AudioRecordingConfiguration;
import android.os.Handler; import android.os.Handler;
@@ -66,6 +67,13 @@ public class AppOpsControllerImpl implements AppOpsController,
private final AppOpsManager mAppOps; private final AppOpsManager mAppOps;
private final AudioManager mAudioManager; 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 H mBGHandler;
private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>(); private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>(); 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[] { protected static final int[] OPS = new int[] {
AppOpsManager.OP_CAMERA, AppOpsManager.OP_CAMERA,
AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_RECORD_AUDIO,
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION AppOpsManager.OP_FINE_LOCATION
}; };
@@ -104,6 +114,7 @@ public class AppOpsControllerImpl implements AppOpsController,
mCallbacksByCode.put(OPS[i], new ArraySet<>()); mCallbacksByCode.put(OPS[i], new ArraySet<>());
} }
mAudioManager = audioManager; mAudioManager = audioManager;
mLocationManager = context.getSystemService(LocationManager.class);
dumpManager.registerDumpable(TAG, this); dumpManager.registerDumpable(TAG, this);
} }
@@ -287,6 +298,26 @@ public class AppOpsControllerImpl implements AppOpsController,
return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); 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 * 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 // does not correspond to a platform permission
// which may be user sensitive, so for now always show it to the user. // which may be user sensitive, so for now always show it to the user.
if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW 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; return true;
} }

View File

@@ -57,7 +57,8 @@ class PrivacyItemController @Inject constructor(
@VisibleForTesting @VisibleForTesting
internal companion object { internal companion object {
val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, 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( val OPS_LOCATION = intArrayOf(
AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION) AppOpsManager.OP_FINE_LOCATION)
@@ -248,9 +249,11 @@ class PrivacyItemController @Inject constructor(
private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
val type: PrivacyType = when (appOpItem.code) { val type: PrivacyType = when (appOpItem.code) {
AppOpsManager.OP_PHONE_CALL_CAMERA,
AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_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_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
else -> return null else -> return null
} }