1 /* 2 * Copyright (C) 2016 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.settings.password; 18 19 import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY; 20 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD; 21 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD; 22 import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY; 23 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; 24 25 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME; 26 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN; 27 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; 28 29 import android.app.Activity; 30 import android.app.admin.DevicePolicyManager; 31 import android.app.admin.DevicePolicyManager.PasswordComplexity; 32 import android.app.admin.PasswordMetrics; 33 import android.app.settings.SettingsEnums; 34 import android.content.ComponentName; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.os.Bundle; 38 import android.os.IBinder; 39 import android.util.Log; 40 41 import com.android.settings.Utils; 42 import com.android.settings.overlay.FeatureFactory; 43 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 44 45 import java.util.List; 46 47 /** 48 * Trampolines {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD} and 49 * {@link DevicePolicyManager#ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} intent to the appropriate UI 50 * activity for handling set new password. 51 */ 52 public class SetNewPasswordActivity extends Activity implements SetNewPasswordController.Ui { 53 private static final String TAG = "SetNewPasswordActivity"; 54 private String mNewPasswordAction; 55 private SetNewPasswordController mSetNewPasswordController; 56 57 /** 58 * From intent extra {@link DevicePolicyManager#EXTRA_PASSWORD_COMPLEXITY}. 59 * 60 * <p>This is used only if caller has the required permission and activity is launched by 61 * {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD}. 62 */ 63 private @PasswordComplexity int mRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE; 64 65 /** 66 * Label of the app which launches this activity. 67 * 68 * <p>Value would be {@code null} if launched from settings app. 69 */ 70 private String mCallerAppName = null; 71 72 @Override onCreate(Bundle savedState)73 protected void onCreate(Bundle savedState) { 74 super.onCreate(savedState); 75 76 mNewPasswordAction = getIntent().getAction(); 77 if (!ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction) 78 && !ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(mNewPasswordAction)) { 79 Log.e(TAG, "Unexpected action to launch this activity"); 80 finish(); 81 return; 82 } 83 84 logSetNewPasswordIntent(); 85 86 final IBinder activityToken = getActivityToken(); 87 mCallerAppName = (String) PasswordUtils.getCallingAppLabel(this, activityToken); 88 if (ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction) 89 && getIntent().hasExtra(EXTRA_PASSWORD_COMPLEXITY)) { 90 final boolean hasPermission = PasswordUtils.isCallingAppPermitted( 91 this, activityToken, REQUEST_PASSWORD_COMPLEXITY); 92 if (hasPermission) { 93 mRequestedMinComplexity = 94 PasswordMetrics.sanitizeComplexityLevel(getIntent() 95 .getIntExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE)); 96 } else { 97 PasswordUtils.crashCallingApplication(activityToken, 98 "Must have permission " 99 + REQUEST_PASSWORD_COMPLEXITY + " to use extra " 100 + EXTRA_PASSWORD_COMPLEXITY); 101 finish(); 102 return; 103 } 104 } 105 106 mSetNewPasswordController = SetNewPasswordController.create( 107 this, this, getIntent(), getActivityToken()); 108 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 109 } 110 111 @Override launchChooseLock(Bundle chooseLockFingerprintExtras)112 public void launchChooseLock(Bundle chooseLockFingerprintExtras) { 113 final boolean isInSetupWizard = !Utils.isDeviceProvisioned(this); 114 Intent intent = isInSetupWizard ? new Intent(this, SetupChooseLockGeneric.class) 115 : new Intent(this, ChooseLockGeneric.class); 116 intent.setAction(mNewPasswordAction); 117 intent.putExtras(chooseLockFingerprintExtras); 118 if (mCallerAppName != null) { 119 intent.putExtra(EXTRA_KEY_CALLER_APP_NAME, mCallerAppName); 120 } 121 if (mRequestedMinComplexity != PASSWORD_COMPLEXITY_NONE) { 122 intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, mRequestedMinComplexity); 123 } 124 if (isCallingAppAdmin()) { 125 intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true); 126 } 127 startActivity(intent); 128 finish(); 129 } 130 isCallingAppAdmin()131 private boolean isCallingAppAdmin() { 132 DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class); 133 String callingAppPackageName = PasswordUtils.getCallingAppPackageName(getActivityToken()); 134 List<ComponentName> admins = devicePolicyManager.getActiveAdmins(); 135 if (admins == null) { 136 return false; 137 } 138 for (ComponentName componentName : admins) { 139 if (componentName.getPackageName().equals(callingAppPackageName)) { 140 return true; 141 } 142 } 143 return false; 144 } 145 logSetNewPasswordIntent()146 private void logSetNewPasswordIntent() { 147 final String callingAppPackageName = 148 PasswordUtils.getCallingAppPackageName(getActivityToken()); 149 150 // use int min value to denote absence of EXTRA_PASSWORD_COMPLEXITY 151 final int extraPasswordComplexity = getIntent().hasExtra(EXTRA_PASSWORD_COMPLEXITY) 152 ? getIntent().getIntExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE) 153 : Integer.MIN_VALUE; 154 155 // this activity is launched by either ACTION_SET_NEW_PASSWORD or 156 // ACTION_SET_NEW_PARENT_PROFILE_PASSWORD 157 final int action = ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction) 158 ? SettingsEnums.ACTION_SET_NEW_PASSWORD 159 : SettingsEnums.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD; 160 161 final MetricsFeatureProvider metricsProvider = 162 FeatureFactory.getFactory(this).getMetricsFeatureProvider(); 163 metricsProvider.action( 164 metricsProvider.getAttribution(this), 165 action, 166 SettingsEnums.SET_NEW_PASSWORD_ACTIVITY, 167 callingAppPackageName, 168 extraPasswordComplexity); 169 } 170 } 171