New device policy to disable camera.
This introduces a new policy that a DeviceAdmin can use to disable _all_ cameras on the device. A separate CL will be made on the media side to watch this policy bit and act accordingly. Bug: 4185303 Change-Id: I700cfc4a8317bb74087ccae39346d74467fc58b2
This commit is contained in:
@@ -3577,6 +3577,7 @@ package android.app.admin {
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator CREATOR;
|
||||
field public static final int USES_ENCRYPTED_STORAGE = 7; // 0x7
|
||||
field public static final int USES_POLICY_DISABLE_CAMERA = 8; // 0x8
|
||||
field public static final int USES_POLICY_EXPIRE_PASSWORD = 6; // 0x6
|
||||
field public static final int USES_POLICY_FORCE_LOCK = 3; // 0x3
|
||||
field public static final int USES_POLICY_LIMIT_PASSWORD = 0; // 0x0
|
||||
@@ -3610,6 +3611,7 @@ package android.app.admin {
|
||||
|
||||
public class DevicePolicyManager {
|
||||
method public java.util.List<android.content.ComponentName> getActiveAdmins();
|
||||
method public boolean getCameraDisabled(android.content.ComponentName);
|
||||
method public int getCurrentFailedPasswordAttempts();
|
||||
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
|
||||
method public long getMaximumTimeToLock(android.content.ComponentName);
|
||||
@@ -3633,6 +3635,7 @@ package android.app.admin {
|
||||
method public void lockNow();
|
||||
method public void removeActiveAdmin(android.content.ComponentName);
|
||||
method public boolean resetPassword(java.lang.String, int);
|
||||
method public void setCameraDisabled(android.content.ComponentName, boolean);
|
||||
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
|
||||
method public void setMaximumTimeToLock(android.content.ComponentName, long);
|
||||
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
|
||||
|
||||
@@ -130,6 +130,14 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
*/
|
||||
public static final int USES_ENCRYPTED_STORAGE = 7;
|
||||
|
||||
/**
|
||||
* A type of policy that this device admin can use: disables use of all device cameras.
|
||||
*
|
||||
* <p>To control this policy, the device admin must have a "disable-camera"
|
||||
* tag in the "uses-policies" section of its meta-data.
|
||||
*/
|
||||
public static final int USES_POLICY_DISABLE_CAMERA = 8;
|
||||
|
||||
/** @hide */
|
||||
public static class PolicyInfo {
|
||||
public final int ident;
|
||||
@@ -174,6 +182,9 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage",
|
||||
com.android.internal.R.string.policylab_encryptedStorage,
|
||||
com.android.internal.R.string.policydesc_encryptedStorage));
|
||||
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_DISABLE_CAMERA, "disable-camera",
|
||||
com.android.internal.R.string.policylab_disableCamera,
|
||||
com.android.internal.R.string.policydesc_disableCamera));
|
||||
|
||||
for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
|
||||
PolicyInfo pi = sPoliciesDisplayOrder.get(i);
|
||||
@@ -365,7 +376,8 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
* {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
|
||||
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
|
||||
* {@link #USES_POLICY_WIPE_DATA},
|
||||
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE}.
|
||||
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE},
|
||||
* {@link #USES_POLICY_DISABLE_CAMERA}.
|
||||
*/
|
||||
public boolean usesPolicy(int policyIdent) {
|
||||
return (mUsesPolicies & (1<<policyIdent)) != 0;
|
||||
|
||||
@@ -1227,6 +1227,45 @@ public class DevicePolicyManager {
|
||||
return ENCRYPTION_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to disable all cameras
|
||||
* on the device. After setting this, no applications will be able to access any cameras
|
||||
* on the device.
|
||||
*
|
||||
* <p>The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
|
||||
* @param disabled Whether or not the camera should be disabled.
|
||||
*/
|
||||
public void setCameraDisabled(ComponentName admin, boolean disabled) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setCameraDisabled(admin, disabled);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not the device's cameras have been disabled either by the current
|
||||
* admin, if specified, or all admins.
|
||||
* @param admin The name of the admin component to check, or null to check if any admins
|
||||
* have disabled the camera
|
||||
*/
|
||||
public boolean getCameraDisabled(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getCameraDisabled(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -79,6 +79,9 @@ interface IDevicePolicyManager {
|
||||
boolean getStorageEncryption(in ComponentName who);
|
||||
int getStorageEncryptionStatus();
|
||||
|
||||
void setCameraDisabled(in ComponentName who, boolean disabled);
|
||||
boolean getCameraDisabled(in ComponentName who);
|
||||
|
||||
void setActiveAdmin(in ComponentName policyReceiver, boolean refreshing);
|
||||
boolean isAdminActive(in ComponentName policyReceiver);
|
||||
List<ComponentName> getActiveAdmins();
|
||||
|
||||
@@ -1479,6 +1479,10 @@
|
||||
<!-- Description of policy access to require encrypted storage [CHAR LIMIT=110]-->
|
||||
<string name="policydesc_encryptedStorage">Require that stored application data be encrypted
|
||||
</string>
|
||||
<!-- Title of policy access to disable all device cameras [CHAR LIMIT=30]-->
|
||||
<string name="policylab_disableCamera">Disable cameras</string>
|
||||
<!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]-->
|
||||
<string name="policydesc_disableCamera">Prevent use of all device cameras</string>
|
||||
|
||||
<!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
|
||||
<!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->
|
||||
|
||||
@@ -172,6 +172,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
|
||||
|
||||
boolean encryptionRequested = false;
|
||||
boolean disableCamera = false;
|
||||
|
||||
// TODO: review implementation decisions with frameworks team
|
||||
boolean specifiesGlobalProxy = false;
|
||||
@@ -274,6 +275,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
out.attribute(null, "value", Boolean.toString(encryptionRequested));
|
||||
out.endTag(null, "encryption-requested");
|
||||
}
|
||||
if (disableCamera) {
|
||||
out.startTag(null, "disable-camera");
|
||||
out.attribute(null, "value", Boolean.toString(disableCamera));
|
||||
out.endTag(null, "disable-camera");
|
||||
}
|
||||
}
|
||||
|
||||
void readFromXml(XmlPullParser parser)
|
||||
@@ -339,6 +345,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
} else if ("encryption-requested".equals(tag)) {
|
||||
encryptionRequested = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("disable-camera".equals(tag)) {
|
||||
disableCamera = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else {
|
||||
Slog.w(TAG, "Unknown admin tag: " + tag);
|
||||
}
|
||||
@@ -393,6 +402,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
pw.print(prefix); pw.print("encryptionRequested=");
|
||||
pw.println(encryptionRequested);
|
||||
pw.print(prefix); pw.print("disableCamera=");
|
||||
pw.println(disableCamera);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +435,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
if (removed) {
|
||||
validatePasswordOwnerLocked();
|
||||
syncDeviceCapabilitiesLocked();
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
@@ -578,6 +590,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
mAdminList.remove(admin);
|
||||
mAdminMap.remove(adminReceiver);
|
||||
validatePasswordOwnerLocked();
|
||||
syncDeviceCapabilitiesLocked();
|
||||
if (doProxyCleanup) {
|
||||
resetGlobalProxy();
|
||||
}
|
||||
@@ -801,6 +814,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
|
||||
validatePasswordOwnerLocked();
|
||||
syncDeviceCapabilitiesLocked();
|
||||
|
||||
long timeMs = getMaximumTimeToLock(null);
|
||||
if (timeMs <= 0) {
|
||||
@@ -844,6 +858,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes down policy information to the system for any policies related to general device
|
||||
* capabilities that need to be enforced by lower level services (e.g. Camera services).
|
||||
*/
|
||||
void syncDeviceCapabilitiesLocked() {
|
||||
// Ensure the status of the camera is synced down to the system. Interested native services
|
||||
// should monitor this value and act accordingly.
|
||||
boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false);
|
||||
boolean cameraDisabled = getCameraDisabled(null);
|
||||
if (cameraDisabled != systemState) {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
String value = cameraDisabled ? "1" : "0";
|
||||
Slog.v(TAG, "Change in camera state ["
|
||||
+ SYSTEM_PROP_DISABLE_CAMERA + "] = " + value);
|
||||
SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void systemReady() {
|
||||
synchronized (this) {
|
||||
loadSettingsLocked();
|
||||
@@ -1982,6 +2018,53 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
private void setEncryptionRequested(boolean encrypt) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The system property used to share the state of the camera. The native camera service
|
||||
* is expected to read this property and act accordingly.
|
||||
*/
|
||||
public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
|
||||
|
||||
/**
|
||||
* Disables all device cameras according to the specified admin.
|
||||
*/
|
||||
public void setCameraDisabled(ComponentName who, boolean disabled) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
|
||||
if (ap.disableCamera != disabled) {
|
||||
ap.disableCamera = disabled;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
syncDeviceCapabilitiesLocked();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not all device cameras are disabled for a given admin, or disabled for any
|
||||
* active admins.
|
||||
*/
|
||||
public boolean getCameraDisabled(ComponentName who) {
|
||||
synchronized (this) {
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return (admin != null) ? admin.disableCamera : false;
|
||||
}
|
||||
|
||||
// Determine whether or not the device camera is disabled for any active admins.
|
||||
final int N = mAdminList.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (admin.disableCamera) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
|
||||
|
||||
Reference in New Issue
Block a user