Home | History | Annotate | Download | only in deviceadmin
      1 /*
      2  * Copyright (C) 2011 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.example.training.deviceadmin;
     18 
     19 import android.app.Activity;
     20 import android.app.admin.DevicePolicyManager;
     21 import android.content.Intent;
     22 import android.content.SharedPreferences;
     23 import android.os.Bundle;
     24 import android.view.View;
     25 import android.widget.AdapterView;
     26 import android.widget.ArrayAdapter;
     27 import android.widget.Button;
     28 import android.widget.EditText;
     29 import android.widget.LinearLayout;
     30 import android.widget.Spinner;
     31 import android.widget.TextView;
     32 
     33 /**
     34  * Main Activity for the sample application.
     35  *
     36  * The Activity maintains and presents 2 different
     37  * screens to the user -- a screen for configuring device administration policy and another screen
     38  * for viewing configured policy.  When it is detected that the screen-lock password satisfies
     39  * the password strength required by the policy, the user is sent to an Activity containing
     40  * protected content.
     41  */
     42 public class PolicySetupActivity extends Activity {
     43     private static final int REQ_ACTIVATE_DEVICE_ADMIN = 10;
     44     private static final String SCREEN_ID_KEY = "LAYOUT_ID";
     45 
     46     private static final String APP_PREF = "APP_PREF";
     47     private static final int UNKNOWN_SCREEN_ID = -1;
     48 
     49     // UI controls in policy setup screen.
     50     private Spinner mPasswordQualityInputField;
     51     private EditText mPasswordLengthInputField;
     52     private EditText mPasswordMinUppercaseInputField;
     53 
     54     private Policy mPolicy;
     55     private int mCurrentScreenId;
     56 
     57     @Override
     58     public void onCreate(Bundle savedInstanceState) {
     59         super.onCreate(savedInstanceState);
     60         mPolicy = new Policy(this);
     61     }
     62 
     63     @Override
     64     protected void onResume() {
     65         super.onResume();
     66 
     67         SharedPreferences prefs = getSharedPreferences(APP_PREF, MODE_PRIVATE);
     68         final int savedScreenId = prefs.getInt(SCREEN_ID_KEY, UNKNOWN_SCREEN_ID);
     69         if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) {
     70             setScreenContent(R.layout.activity_policy_setup);
     71         } else {
     72             setScreenContent(savedScreenId);
     73         }
     74     }
     75 
     76     private void setScreenContent(final int screenId) {
     77         mCurrentScreenId = screenId;
     78         setContentView(mCurrentScreenId);
     79         getSharedPreferences(APP_PREF, MODE_PRIVATE).edit().putInt(
     80                 SCREEN_ID_KEY, mCurrentScreenId).commit();
     81         switch (mCurrentScreenId) {
     82         case R.layout.activity_policy_setup:
     83             initPolicySetupScreen();
     84             initNavigation();
     85             break;
     86         case R.layout.activity_view_policy:
     87             initViewPolicyScreen();
     88             initNavigation();
     89             break;
     90         }
     91     }
     92 
     93     @Override
     94     protected void onPause() {
     95         super.onPause();
     96         if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy();
     97     }
     98 
     99     @Override
    100     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    101         if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN && resultCode == RESULT_OK) {
    102             // User just activated the application as a device administrator.
    103             setScreenContent(mCurrentScreenId);
    104         } else {
    105             super.onActivityResult(requestCode, resultCode, data);
    106         }
    107     }
    108 
    109     @Override
    110     public void onBackPressed() {
    111         if (mCurrentScreenId == R.layout.activity_view_policy) {
    112             setScreenContent(R.layout.activity_policy_setup);
    113             return;
    114         }
    115         super.onBackPressed();
    116     }
    117 
    118     // Initialize policy set up screen.
    119     private void initPolicySetupScreen() {
    120         mPasswordQualityInputField = (Spinner) findViewById(R.id.policy_password_quality);
    121         mPasswordLengthInputField = (EditText) findViewById(R.id.policy_password_length);
    122         mPasswordMinUppercaseInputField = (EditText) findViewById(R.id.policy_password_uppercase);
    123         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
    124                 R.array.password_types, android.R.layout.simple_spinner_item);
    125         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    126         mPasswordQualityInputField.setAdapter(adapter);
    127         mPasswordQualityInputField.setOnItemSelectedListener(
    128                 new AdapterView.OnItemSelectedListener() {
    129             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    130                 LinearLayout passwordMinUppercaseView =
    131                         (LinearLayout) findViewById(R.id.password_uppercase_view);
    132                 // The minimum number of upper case field is only applicable for password
    133                 // qualities: alpha, alphanumeric, or complex.
    134                 if (pos > 2)
    135                     passwordMinUppercaseView.setVisibility(View.VISIBLE);
    136                 else
    137                     passwordMinUppercaseView.setVisibility(View.GONE);
    138             }
    139 
    140             public void onNothingSelected(AdapterView<?> parent) {}
    141         });
    142 
    143         // Read previously saved policy and populate on the UI.
    144         mPolicy.readFromLocal();
    145         mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality());
    146         if (mPolicy.getPasswordLength() > 0) {
    147             mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength()));
    148         } else {
    149             mPasswordLengthInputField.setText("");
    150         }
    151 
    152         if (mPolicy.getPasswordMinUpperCase() > 0) {
    153             mPasswordMinUppercaseInputField.setText(
    154                     String.valueOf(mPolicy.getPasswordMinUpperCase()));
    155         } else {
    156             mPasswordMinUppercaseInputField.setText("");
    157         }
    158     }
    159 
    160     // Initialize policy viewing screen.
    161     private void initViewPolicyScreen() {
    162         TextView passwordQualityView = (TextView) findViewById(R.id.policy_password_quality);
    163         TextView passwordLengthView = (TextView) findViewById(R.id.policy_password_length);
    164 
    165         // Read previously saved policy and populate on the UI.
    166         mPolicy.readFromLocal();
    167         int passwordQualitySelection = mPolicy.getPasswordQuality();
    168         passwordQualityView.setText(
    169                 getResources().getStringArray(R.array.password_types)[passwordQualitySelection]);
    170         passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength()));
    171         if (passwordQualitySelection > 2) {
    172             LinearLayout passwordMinUppercaseView =
    173                     (LinearLayout) findViewById(R.id.password_uppercase_view);
    174             passwordMinUppercaseView.setVisibility(View.VISIBLE);
    175             ((TextView) findViewById(R.id.policy_password_uppercase)).setText(
    176                     String.valueOf(mPolicy.getPasswordMinUpperCase()));
    177         }
    178     }
    179 
    180     // Set up navigation message and action button.
    181     private void initNavigation() {
    182         if (!mPolicy.isAdminActive()) {
    183             // Activates device administrator.
    184             setupNavigation(R.string.setup_message_activate,
    185                     R.string.setup_action_activate,
    186                     mActivateButtonListener);
    187         } else if (mCurrentScreenId == R.layout.activity_policy_setup) {
    188             setupNavigation(R.string.setup_message_set_policy,
    189                     R.string.setup_action_set_policy,
    190                     new View.OnClickListener() {
    191                         public void onClick(View view) {
    192                             writePolicy();
    193                             mPolicy.configurePolicy();
    194                             setScreenContent(R.layout.activity_view_policy);
    195                         }
    196                     });
    197         }
    198         else if (!mPolicy.isActivePasswordSufficient()) {
    199             // Launches password set-up screen in Settings.
    200             setupNavigation(R.string.setup_message_enforce_policy,
    201                     R.string.setup_action_enforce_policy,
    202                     mEnforcePolicyListener);
    203         } else {
    204             // Grants access to secure content.
    205             setupNavigation(R.string.setup_message_go_secured,
    206                     R.string.setup_action_go_secured,
    207                     new View.OnClickListener() {
    208                         public void onClick(View view) {
    209                             startActivity(new Intent(view.getContext(), SecureActivity.class));
    210                         }
    211                     });
    212         }
    213     }
    214 
    215     private View.OnClickListener mActivateButtonListener = new View.OnClickListener() {
    216         @Override
    217         public void onClick(View v) {
    218             // First, persist the policy.  Then, launch intent to trigger the system screen
    219             // requesting user to confirm the activation of the device administrator.
    220             writePolicy();
    221             Intent activateDeviceAdminIntent =
    222                 new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    223             activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
    224                     mPolicy.getPolicyAdmin());
    225             // It is good practice to include the optional explanation text to explain to
    226             // user why the application is requesting to be a device administrator.  The system
    227             // will display this message on the activation screen.
    228             activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
    229                     getResources().getString(R.string.device_admin_activation_message));
    230             startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN);
    231         }
    232     };
    233 
    234     private View.OnClickListener mEnforcePolicyListener = new View.OnClickListener() {
    235         @Override
    236         public void onClick(View v) {
    237             writePolicy();
    238             // The device administration API does not "fix" the password if it is
    239             // determined that the current password does not conform to what is requested
    240             // by the policy.  The caller is responsible for triggering the password set up
    241             // screen via the below intent.
    242             Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
    243             startActivity(intent);
    244         }
    245     };
    246 
    247     // Setup action button text and listener.
    248     private void setupNavigation(int messageResId, int buttonTextResId,
    249             View.OnClickListener listener) {
    250         TextView setupMessage = (TextView) findViewById(R.id.setup_message);
    251         setupMessage.setText(messageResId);
    252         Button actionBtn = (Button) findViewById(R.id.setup_action_btn);
    253         actionBtn.setText(buttonTextResId);
    254         actionBtn.setOnClickListener(listener);
    255     }
    256 
    257     // Save policy to shared preferences.
    258     private void writePolicy() {
    259         int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId();
    260 
    261         int passwordLength = 0;
    262         try {
    263             passwordLength = Integer.valueOf(mPasswordLengthInputField.getText().toString());
    264         } catch (NumberFormatException nfe) {}  // Defaults to 0.
    265 
    266         int passwordMinUppercase = 0;
    267         try {
    268             passwordMinUppercase =
    269                     Integer.valueOf(mPasswordMinUppercaseInputField.getText().toString());
    270         } catch (NumberFormatException nfe) {}  // Defaults to 0.
    271 
    272         mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase);
    273     }
    274 }
    275 
    276