Merge "Disallow usb access to camera and mic devices if global privacy toggle is active" into sc-dev

This commit is contained in:
Philip Junker
2021-08-13 13:49:37 +00:00
committed by Android (Google) Code Review

View File

@@ -25,12 +25,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.hardware.SensorPrivacyManager.Sensors;
import android.hardware.SensorPrivacyManagerInternal;
import android.hardware.usb.AccessoryFilter;
import android.hardware.usb.DeviceFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Binder;
@@ -52,9 +52,9 @@ import android.util.TypedXmlSerializer;
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -64,7 +64,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* UsbUserPermissionManager manages usb device or accessory access permissions.
@@ -110,19 +109,20 @@ class UsbUserPermissionManager {
*/
@GuardedBy("mLock")
private boolean mIsCopyPermissionsScheduled;
private final SensorPrivacyManagerInternal mSensorPrivacyMgrInternal;
UsbUserPermissionManager(@NonNull Context context,
@NonNull UsbUserSettingsManager usbUserSettingsManager) {
mContext = context;
mUser = context.getUser();
mUsbUserSettingsManager = usbUserSettingsManager;
mSensorPrivacyMgrInternal = LocalServices.getService(SensorPrivacyManagerInternal.class);
mDisablePermissionDialogs = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableUsbPermissionDialogs);
mPermissionsFile = new AtomicFile(new File(
Environment.getUserSystemDirectory(mUser.getIdentifier()),
"usb_permissions.xml"), "usb-permissions");
synchronized (mLock) {
readPermissionsLocked();
}
@@ -195,11 +195,27 @@ class UsbUserPermissionManager {
*/
boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName, int pid,
int uid) {
if (isCameraDevicePresent(device)) {
if (!isCameraPermissionGranted(packageName, pid, uid)) {
if (device.getHasVideoCapture()) {
boolean isCameraPrivacyEnabled = mSensorPrivacyMgrInternal.isSensorPrivacyEnabled(
UserHandle.getUserId(uid), Sensors.CAMERA);
if (DEBUG) {
Slog.d(TAG, "isCameraPrivacyEnabled: " + isCameraPrivacyEnabled);
}
if (isCameraPrivacyEnabled || !isCameraPermissionGranted(packageName, pid, uid)) {
return false;
}
}
// Only check for microphone privacy and not RECORD_AUDIO permission, because access to usb
// camera device with audio recording capabilities may still be granted with a warning
if (device.getHasAudioCapture() && mSensorPrivacyMgrInternal.isSensorPrivacyEnabled(
UserHandle.getUserId(uid), Sensors.MICROPHONE)) {
if (DEBUG) {
Slog.d(TAG,
"Access to device with audio recording capabilities denied because "
+ "microphone privacy is enabled.");
}
return false;
}
synchronized (mLock) {
if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
return true;
@@ -698,7 +714,10 @@ class UsbUserPermissionManager {
}
return;
}
if (isCameraDevicePresent(device)) {
// If the app doesn't have camera permission do not request permission to the USB device.
// Note that if the USB camera also has a microphone, a warning will be shown to the user if
// the app doesn't have RECORD_AUDIO permission.
if (device.getHasVideoCapture()) {
if (!isCameraPermissionGranted(packageName, pid, uid)) {
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
@@ -733,27 +752,4 @@ class UsbUserPermissionManager {
requestPermissionDialog(null, accessory,
mUsbUserSettingsManager.canBeDefault(accessory, packageName), packageName, pi, uid);
}
/**
* Check whether a particular device or any of its interfaces
* is of class VIDEO.
*
* @param device The device that needs to get scanned
* @return True in case a VIDEO device or interface is present,
* False otherwise.
*/
private boolean isCameraDevicePresent(UsbDevice device) {
if (device.getDeviceClass() == UsbConstants.USB_CLASS_VIDEO) {
return true;
}
for (int i = 0; i < device.getInterfaceCount(); i++) {
UsbInterface iface = device.getInterface(i);
if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_VIDEO) {
return true;
}
}
return false;
}
}