/* * Copyright (C) 2012 Louis Fazen * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.alphabetbloc.accessadmin.activities; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.preference.PreferenceManager; import android.telephony.TelephonyManager; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.alphabetbloc.accessadmin.R; import com.alphabetbloc.accessadmin.data.Constants; import com.alphabetbloc.accessadmin.data.EncryptedPreferences; import com.alphabetbloc.accessadmin.data.Policy; import com.alphabetbloc.accessadmin.data.StringGenerator; import com.alphabetbloc.accessadmin.receivers.DeviceAdmin; /** * Activity that steps through the process of enabling the Device Policy, * setting up a password that follows the policy, and establishing a provider ID * for AccessMRS in a secure way. Uses full screen view and airplane mode to * prevent leaving activity via a call or SMS and interrupting the activity via * notifications bar. Also leads the user to setup an account on the device if * they wish. * * @author Louis Fazen (louis.fazen@gmail.com) * */ public class InitialSetupActivity extends DeviceHoldActivity { // private static final String TAG = "InitialSetUpService"; private static final int START = 0; private static final int SET_ADMIN = 1; private static final int SET_PWD = 2; private static final int SETUP_ACCESS_MRS = 3; private static final String TAG = InitialSetupActivity.class.getSimpleName(); private int mStep; private Context mContext; private TextView mInstructionText; private TextView mStepText; private Button mButton; private int mRequestCode; private int mResultCode; private Policy mPolicy; @Override protected void onCreate(Bundle savedInstanceState) { Log.v(TAG, "InitialSetupActivity is called"); mContext = this; mPolicy = new Policy(mContext); startAirplaneMode(); initializeSIM(); createUniqueDeviceAdminCode(); saveDefaultDeviceAdminPwd(); saveDefaultReportingLine(); initializeView(); super.onCreate(savedInstanceState); } private void initializeView() { this.requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.initial_setup); mInstructionText = (TextView) findViewById(R.id.instruction); mButton = (Button) findViewById(R.id.next_button); mStepText = (TextView) findViewById(R.id.step); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { switch (mStep) { case SET_ADMIN: activateDeviceAdmin(); break; case SET_PWD: setPassword(); break; case SETUP_ACCESS_MRS: setupAccessMRS(); break; default: break; } } }); mRequestCode = START; mResultCode = RESULT_OK; } @Override protected void onResume() { super.onResume(); if (mResultCode == RESULT_OK) stepForward(); else stepBack(); } private void stepForward() { switch (mRequestCode) { case START: mInstructionText.setText(R.string.initial_instructions); mStep = SET_ADMIN; mStepText.setVisibility(View.GONE); mButton.setText(R.string.start); break; case SET_ADMIN: mPolicy.initializeDefaultPolicy(); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext); settings.edit().putBoolean(Constants.NEW_INSTALL, false).commit(); mInstructionText.setText(R.string.pwd_instructions); mButton.setText(R.string.set_pwd); mStep = SET_PWD; mStepText.setText(String.valueOf(SET_PWD)); mStepText.setVisibility(View.VISIBLE); break; case SET_PWD: if (mPolicy.isDeviceSecured()) { stopAirplaneMode(); mInstructionText.setText(R.string.access_mrs_instructions); mButton.setText(R.string.setup_access_mrs); mStep = SETUP_ACCESS_MRS; mStepText.setText(String.valueOf(SETUP_ACCESS_MRS)); // SharedPreferences prefs = new EncryptedPreferences(this, this.getSharedPreferences(Constants.ENCRYPTED_PREFS, Context.MODE_PRIVATE)); // String uniqueId = prefs.getString(Constants.UNIQUE_DEVICE_ID, null); // if (uniqueId != null) { // Intent i = new Intent(mContext, DeviceAdminService.class); // i.putExtra(Constants.DEVICE_ADMIN_WORK, Constants.SEND_SMS); // i.putExtra(Constants.SMS_MESSAGE, "AdminCode=" + uniqueId); // WakefulIntentService.sendWakefulWork(mContext, i); // } } else { mInstructionText.setText(R.string.setup_error); mStep = SET_ADMIN; mStepText.setVisibility(View.GONE); mButton.setText(R.string.start); } break; default: break; } } private void stepBack() { switch (mRequestCode) { case SET_ADMIN: mInstructionText.setText(R.string.admin_requirement); mButton.setText(R.string.set_admin); mStep = SET_ADMIN; mStepText.setText(String.valueOf(SET_ADMIN)); mStepText.setVisibility(View.VISIBLE); break; case SET_PWD: mInstructionText.setText(R.string.pwd_requirement); mButton.setText(R.string.set_pwd); mStep = SET_PWD; mStepText.setText(String.valueOf(SET_PWD)); break; default: break; } } private void initializeSIM() { // Setup the SIM information (this will act as the registered SIM code // for the device) TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); String line = tm.getLine1Number(); String serial = tm.getSimSerialNumber(); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext); settings.edit().putString(Constants.SIM_SERIAL, serial).commit(); settings.edit().putString(Constants.SIM_LINE, line).commit(); } /** * Creates a unique device code that must be used to do Device Admin work * via SMS. */ private void createUniqueDeviceAdminCode() { // not secure, just more secure. // could be more secure if the user supplied the encryption key, but // that may be unecessary, given still have root priv String rAlphaNum = (new StringGenerator(15)).getRandomAlphaNumericString(); final SharedPreferences prefs = new EncryptedPreferences(this, this.getSharedPreferences(Constants.ENCRYPTED_PREFS, Context.MODE_PRIVATE)); prefs.edit().putString(Constants.UNIQUE_DEVICE_ID, rAlphaNum).commit(); } private void saveDefaultDeviceAdminPwd() { // could always use this default with getString(), but put in here so as // to have check for null final SharedPreferences prefs = new EncryptedPreferences(this, this.getSharedPreferences(Constants.ENCRYPTED_PREFS, Context.MODE_PRIVATE)); prefs.edit().putString(Constants.ADMIN_PASSWORD, Constants.DEFAULT_ADMIN_PASSWORD).commit(); } private void saveDefaultReportingLine() { // could always use this default with getString(), but put in here so as // to have check for null final SharedPreferences prefs = new EncryptedPreferences(this, this.getSharedPreferences(Constants.ENCRYPTED_PREFS, Context.MODE_PRIVATE)); prefs.edit().putString(Constants.SMS_REPLY_LINE, Constants.DEFAULT_SMS_REPLY_LINE).commit(); } private void activateDeviceAdmin() { Intent initAdmin = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); ComponentName deviceAdmin = new ComponentName(InitialSetupActivity.this, DeviceAdmin.class); initAdmin.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceAdmin); initAdmin.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Please set up a device administrator to ensure the security of this device."); startActivityForResult(initAdmin, SET_ADMIN); } private void setPassword() { Intent i = new Intent(mContext, SetUserPassword.class); i.putExtra(SetUserPassword.INITIAL_SETUP, true); startActivityForResult(i, SET_PWD); } private void setupAccessMRS() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); prefs.edit().putBoolean(Constants.SHOW_MENU, true).commit(); if (isAccessMRSInstalled()) { Intent i = new Intent(); i.setComponent(new ComponentName("com.alphabetbloc.accessmrs", "com.alphabetbloc.accessmrs.ui.admin.LauncherActivity")); i.putExtra("device_admin_setup", true); startActivityForResult(i, SETUP_ACCESS_MRS); } else { Toast.makeText(this, "AccessMRS is not Installed. Please install AccessMRS.", Toast.LENGTH_LONG).show(); } finish(); } private boolean isAccessMRSInstalled() { try { getPackageManager().getPackageInfo("com.alphabetbloc.accessmrs", PackageManager.GET_META_DATA); } catch (NameNotFoundException e) { Log.v(TAG, "AccessMRS is not installed, so skipping setup."); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mRequestCode = requestCode; mResultCode = resultCode; } // /Override which buttons to allow through DeviceHold by not consuming // TouchEvent @Override public boolean onTouch(View v, MotionEvent event) { if (v.equals(mButton)) { return false; } return true; } }