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 onCreate(Bundle savedInstanceState)58 public void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 mPolicy = new Policy(this); 61 } 62 63 @Override onResume()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 setScreenContent(final int screenId)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 onPause()94 protected void onPause() { 95 super.onPause(); 96 if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy(); 97 } 98 99 @Override onActivityResult(int requestCode, int resultCode, Intent data)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 onBackPressed()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. initPolicySetupScreen()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. initViewPolicyScreen()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. initNavigation()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. setupNavigation(int messageResId, int buttonTextResId, View.OnClickListener 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. writePolicy()258 private void writePolicy() { 259 int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId(); 260 261 int passwordLength = 0; 262 try { 263 passwordLength = Integer.parseInt(mPasswordLengthInputField.getText().toString()); 264 } catch (NumberFormatException nfe) {} // Defaults to 0. 265 266 int passwordMinUppercase = 0; 267 try { 268 passwordMinUppercase = 269 Integer.parseInt(mPasswordMinUppercaseInputField.getText().toString()); 270 } catch (NumberFormatException nfe) {} // Defaults to 0. 271 272 mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase); 273 } 274 } 275 276