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:
Ben Komalo
2011-05-09 16:05:33 -07:00
parent d3ee2fa184
commit 2447edd85b
6 changed files with 145 additions and 1 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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
*/

View File

@@ -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();

View File

@@ -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. -->

View File

@@ -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)