Home | History | Annotate | Download | only in setup
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.email.activity.setup;
     18 
     19 import com.android.email.R;
     20 import com.android.email.SecurityPolicy;
     21 import com.android.email.provider.EmailContent.Account;
     22 import com.android.email.provider.EmailContent.HostAuth;
     23 
     24 import android.app.Activity;
     25 import android.app.admin.DevicePolicyManager;
     26 import android.content.Context;
     27 import android.content.Intent;
     28 import android.os.Bundle;
     29 
     30 /**
     31  * Psuedo-activity (no UI) to bootstrap the user up to a higher desired security level.  This
     32  * bootstrap requires the following steps.
     33  *
     34  * 1.  Confirm the account of interest has any security policies defined - exit early if not
     35  * 2.  If not actively administrating the device, ask Device Policy Manager to start that
     36  * 3.  When we are actively administrating, check current policies and see if they're sufficient
     37  * 4.  If not, set policies
     38  * 5.  If necessary, request for user to update device password
     39  */
     40 public class AccountSecurity extends Activity {
     41 
     42     private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity.setup.ACCOUNT_ID";
     43 
     44     private static final int REQUEST_ENABLE = 1;
     45 
     46     /**
     47      * Used for generating intent for this activity (which is intended to be launched
     48      * from a notification.)
     49      *
     50      * @param context Calling context for building the intent
     51      * @param accountId The account of interest
     52      * @return an Intent which can be used to view that account
     53      */
     54     public static Intent actionUpdateSecurityIntent(Context context, long accountId) {
     55         Intent intent = new Intent(context, AccountSecurity.class);
     56         intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
     57         return intent;
     58     }
     59 
     60     @Override
     61     public void onCreate(Bundle savedInstanceState) {
     62         super.onCreate(savedInstanceState);
     63 
     64         Intent i = getIntent();
     65         long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
     66         SecurityPolicy security = SecurityPolicy.getInstance(this);
     67         security.clearNotification(accountId);
     68         if (accountId != -1) {
     69             // TODO: spin up a thread to do this in the background, because of DB ops
     70             Account account = Account.restoreAccountWithId(this, accountId);
     71             if (account != null) {
     72                 if (account.mSecurityFlags != 0) {
     73                     // This account wants to control security
     74                     if (!security.isActiveAdmin()) {
     75                         // retrieve name of server for the format string
     76                         HostAuth hostAuth =
     77                                 HostAuth.restoreHostAuthWithId(this, account.mHostAuthKeyRecv);
     78                         if (hostAuth != null) {
     79                             // try to become active - must happen here in activity, to get result
     80                             Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
     81                             intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
     82                                     security.getAdminComponent());
     83                             intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
     84                                 this.getString(R.string.account_security_policy_explanation_fmt,
     85                                         hostAuth.mAddress));
     86                             startActivityForResult(intent, REQUEST_ENABLE);
     87                             // keep this activity on stack to process result
     88                             return;
     89                         }
     90                     } else {
     91                         // already active - try to set actual policies, finish, and return
     92                         setActivePolicies();
     93                     }
     94                 }
     95             }
     96         }
     97         finish();
     98     }
     99 
    100     /**
    101      * Handle the eventual result of the user allowing us to become an active device admin
    102      */
    103     @Override
    104     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    105         switch (requestCode) {
    106             case REQUEST_ENABLE:
    107                 if (resultCode == Activity.RESULT_OK) {
    108                     // now active - try to set actual policies
    109                     setActivePolicies();
    110                 } else {
    111                     // failed - repost notification, and exit
    112                     final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
    113                     if (accountId != -1) {
    114                         new Thread() {
    115                             @Override
    116                             public void run() {
    117                                 SecurityPolicy.getInstance(AccountSecurity.this)
    118                                         .policiesRequired(accountId);
    119                             }
    120                         }.start();
    121                     }
    122                 }
    123         }
    124         finish();
    125         super.onActivityResult(requestCode, resultCode, data);
    126     }
    127 
    128     /**
    129      * Now that we are connected as an active device admin, try to set the device to the
    130      * correct security level, and ask for a password if necessary.
    131      */
    132     private void setActivePolicies() {
    133         SecurityPolicy sp = SecurityPolicy.getInstance(this);
    134         // check current security level - if sufficient, we're done!
    135         if (sp.isActive(null)) {
    136             sp.clearAccountHoldFlags();
    137             return;
    138         }
    139         // set current security level
    140         sp.setActivePolicies();
    141         // check current security level - if sufficient, we're done!
    142         if (sp.isActive(null)) {
    143             sp.clearAccountHoldFlags();
    144             return;
    145         }
    146         // if not sufficient, launch the activity to have the user set a new password.
    147         Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
    148         startActivity(intent);
    149     }
    150 
    151 }
    152