diff --git a/emailcommon/src/com/android/emailcommon/service/IPolicyService.aidl b/emailcommon/src/com/android/emailcommon/service/IPolicyService.aidl index c284292e0..2c2c9903a 100755 --- a/emailcommon/src/com/android/emailcommon/service/IPolicyService.aidl +++ b/emailcommon/src/com/android/emailcommon/service/IPolicyService.aidl @@ -25,4 +25,5 @@ interface IPolicyService { // New version void setAccountPolicy2(long accountId, in Policy policy, String securityKey, boolean notify); oneway void remoteWipe(); + boolean canDisableCamera(); } \ No newline at end of file diff --git a/emailcommon/src/com/android/emailcommon/service/PolicyServiceProxy.java b/emailcommon/src/com/android/emailcommon/service/PolicyServiceProxy.java index fcd916f25..c5dd6c180 100755 --- a/emailcommon/src/com/android/emailcommon/service/PolicyServiceProxy.java +++ b/emailcommon/src/com/android/emailcommon/service/PolicyServiceProxy.java @@ -85,6 +85,24 @@ public class PolicyServiceProxy extends ServiceProxy implements IPolicyService { waitForCompletion(); } + public boolean canDisableCamera() throws RemoteException { + setTask(new ProxyTask() { + @Override + public void run() throws RemoteException { + mReturn = mService.canDisableCamera(); + } + }, "canDisableCamera"); + waitForCompletion(); + if (mReturn == null) { + // This is not a great situation, but it's better to act like the policy isn't enforced + // rather than crash. + LogUtils.e(TAG, "PolicyService unavailable in canDisableCamera; assuming false"); + return false; + } else { + return (Boolean)mReturn; + } + } + @Override public void remoteWipe() throws RemoteException { setTask(new ProxyTask() { @@ -145,5 +163,13 @@ public class PolicyServiceProxy extends ServiceProxy implements IPolicyService { } throw new IllegalStateException("PolicyService transaction failed"); } + + public static boolean canDisableCamera(Context context) { + try { + return new PolicyServiceProxy(context).canDisableCamera(); + } catch (RemoteException e) { + } + return false; + } } diff --git a/provider_src/com/android/email/SecurityPolicy.java b/provider_src/com/android/email/SecurityPolicy.java index 58e77a22d..8418871d4 100644 --- a/provider_src/com/android/email/SecurityPolicy.java +++ b/provider_src/com/android/email/SecurityPolicy.java @@ -56,7 +56,7 @@ import java.util.ArrayList; * into and out of various security states. */ public class SecurityPolicy { - private static final String TAG = "Email/SecurityPolicy"; + private static final String TAG = "Email"; private static SecurityPolicy sInstance = null; private Context mContext; private DevicePolicyManager mDPM; @@ -438,7 +438,14 @@ public class SecurityPolicy { dpm.setPasswordMinimumNumeric(mAdminName, 0); dpm.setPasswordMinimumNonLetter(mAdminName, aggregatePolicy.mPasswordComplexChars); // Device capabilities - dpm.setCameraDisabled(mAdminName, aggregatePolicy.mDontAllowCamera); + try { + // If we are running in a managed policy, it is a securityException to even + // call setCameraDisabled(), if is disabled is false. We have to swallow + // the exception here. + dpm.setCameraDisabled(mAdminName, aggregatePolicy.mDontAllowCamera); + } catch (SecurityException e) { + LogUtils.d(TAG, "SecurityException in setCameraDisabled, nothing changed"); + } // encryption required dpm.setStorageEncryption(mAdminName, aggregatePolicy.mRequireEncryption); diff --git a/provider_src/com/android/email/service/PolicyService.java b/provider_src/com/android/email/service/PolicyService.java index c045fabab..ac0f8efb3 100644 --- a/provider_src/com/android/email/service/PolicyService.java +++ b/provider_src/com/android/email/service/PolicyService.java @@ -17,6 +17,8 @@ package com.android.email.service; import android.app.Service; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; @@ -82,6 +84,34 @@ public class PolicyService extends Service { throw e; } } + + public boolean canDisableCamera() { + // TODO: This is not a clean way to do this, but there is not currently + // any api that can answer the question "will disabling the camera work?" + // We need to answer this question here so that we can tell the server what + // policies we are able to support, and only apply them after it confirms that + // our partial support is acceptable. + DevicePolicyManager dpm = + (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); + final ComponentName adminName = new ComponentName(mContext, SecurityPolicy.PolicyAdmin.class); + final boolean cameraDisabled = dpm.getCameraDisabled(adminName); + if (cameraDisabled) { + // The camera is already disabled, by this admin. + // Apparently we can support disabling the camera. + return true; + } else { + try { + dpm.setCameraDisabled(adminName, true); + dpm.setCameraDisabled(adminName, false); + } catch (SecurityException e) { + // Apparently we cannot support disabling the camera. + LogUtils.w(LOG_TAG, "SecurityException checking camera disabling."); + return false; + } + } + return true; + } + }; @Override