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