• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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