19ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank/* 29ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * Copyright (C) 2011 The Android Open Source Project 39ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * 49ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 59ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * you may not use this file except in compliance with the License. 69ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * You may obtain a copy of the License at 79ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * 89ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * http://www.apache.org/licenses/LICENSE-2.0 99ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * 109ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * Unless required by applicable law or agreed to in writing, software 119ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * distributed under the License is distributed on an "AS IS" BASIS, 129ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * See the License for the specific language governing permissions and 149ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank * limitations under the License. 159ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank */ 169ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 179ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankpackage com.android.email.service; 189ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 199ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport android.app.Service; 20ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdonimport android.app.admin.DevicePolicyManager; 21ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdonimport android.content.ComponentName; 229ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport android.content.Context; 239ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport android.content.Intent; 249ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport android.os.IBinder; 2534662f11b2ff38f05219415f3672a52a7af2338fTony Mantlerimport android.os.RemoteException; 269ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 27f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.email.SecurityPolicy; 28f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.provider.Policy; 29f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.emailcommon.service.IPolicyService; 3095bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrookimport com.android.mail.utils.LogTag; 3195bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrookimport com.android.mail.utils.LogUtils; 32f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank 339ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankpublic class PolicyService extends Service { 3495bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook private static final String LOG_TAG = LogTag.getLogTag(); 359ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 369ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank private SecurityPolicy mSecurityPolicy; 379ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank private Context mContext; 389ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 399ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank private final IPolicyService.Stub mBinder = new IPolicyService.Stub() { 409e521deb6bb525b33365cc2926cb2d0faa7095e2Scott Kennedy @Override 41aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public boolean isActive(Policy policy) { 4295bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook try { 4395bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook return mSecurityPolicy.isActive(policy); 4495bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } catch (RuntimeException e) { 4595bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // Catch, log and rethrow the exception, as otherwise when the exception is 4695bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // ultimately handled, the complete stack trace is losk 4795bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook LogUtils.e(LOG_TAG, e, "Exception thrown during call to SecurityPolicy#isActive"); 4895bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook throw e; 4995bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } 509ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank } 519ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 529e521deb6bb525b33365cc2926cb2d0faa7095e2Scott Kennedy @Override 539ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank public void setAccountHoldFlag(long accountId, boolean newState) { 549ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank SecurityPolicy.setAccountHoldFlag(mContext, accountId, newState); 559ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank } 569ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 579e521deb6bb525b33365cc2926cb2d0faa7095e2Scott Kennedy @Override 589ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank public void remoteWipe() { 5995bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook try { 6095bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook mSecurityPolicy.remoteWipe(); 6195bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } catch (RuntimeException e) { 6295bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // Catch, log and rethrow the exception, as otherwise when the exception is 6395bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // ultimately handled, the complete stack trace is losk 6495bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook LogUtils.e(LOG_TAG, e, "Exception thrown during call to SecurityPolicy#remoteWipe"); 6595bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook throw e; 6695bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } 679ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank } 689ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 699e521deb6bb525b33365cc2926cb2d0faa7095e2Scott Kennedy @Override 70f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank public void setAccountPolicy(long accountId, Policy policy, String securityKey) { 7134662f11b2ff38f05219415f3672a52a7af2338fTony Mantler setAccountPolicy2(accountId, policy, securityKey, true /* notify */); 7234662f11b2ff38f05219415f3672a52a7af2338fTony Mantler } 7334662f11b2ff38f05219415f3672a52a7af2338fTony Mantler 7434662f11b2ff38f05219415f3672a52a7af2338fTony Mantler @Override 7534662f11b2ff38f05219415f3672a52a7af2338fTony Mantler public void setAccountPolicy2(long accountId, Policy policy, String securityKey, 7634662f11b2ff38f05219415f3672a52a7af2338fTony Mantler boolean notify) { 7795bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook try { 7834662f11b2ff38f05219415f3672a52a7af2338fTony Mantler mSecurityPolicy.setAccountPolicy(accountId, policy, securityKey, notify); 7995bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } catch (RuntimeException e) { 8095bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // Catch, log and rethrow the exception, as otherwise when the exception is 8195bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook // ultimately handled, the complete stack trace is losk 8295bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook LogUtils.e(LOG_TAG, e, 8395bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook "Exception thrown from call to SecurityPolicy#setAccountPolicy"); 8495bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook throw e; 8595bb350f38d08beeabee68323b8514f3cbfd5db5Paul Westbrook } 869ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank } 87ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon 88ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon public boolean canDisableCamera() { 89ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // TODO: This is not a clean way to do this, but there is not currently 90ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // any api that can answer the question "will disabling the camera work?" 91ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // We need to answer this question here so that we can tell the server what 92ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // policies we are able to support, and only apply them after it confirms that 93ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // our partial support is acceptable. 94ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon DevicePolicyManager dpm = 95ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 96ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon final ComponentName adminName = new ComponentName(mContext, SecurityPolicy.PolicyAdmin.class); 97ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon final boolean cameraDisabled = dpm.getCameraDisabled(adminName); 98ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon if (cameraDisabled) { 99ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // The camera is already disabled, by this admin. 100ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // Apparently we can support disabling the camera. 101ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon return true; 102ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon } else { 103ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon try { 104ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon dpm.setCameraDisabled(adminName, true); 105ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon dpm.setCameraDisabled(adminName, false); 106ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon } catch (SecurityException e) { 107ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon // Apparently we cannot support disabling the camera. 108ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon LogUtils.w(LOG_TAG, "SecurityException checking camera disabling."); 109ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon return false; 110ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon } 111ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon } 112ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon return true; 113ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon } 114ce6916b32a98a568ceafb734d050801f4459a532Martin Hibdon 1159ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank }; 1169ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank 1179ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank @Override 1189ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank public IBinder onBind(Intent intent) { 1199ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank // When we bind this service, save the context and SecurityPolicy singleton 1209ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank mContext = this; 1219ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank mSecurityPolicy = SecurityPolicy.getInstance(this); 1229ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank return mBinder; 1239ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank } 1249ba506c4dd498150555f6c59aa758f7467bf9236Marc Blank}