1 /* 2 * Copyright (C) 2014 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.tv.settings.users; 18 19 import android.app.Fragment; 20 import android.app.admin.DevicePolicyManager; 21 import android.content.Context; 22 import android.content.pm.UserInfo; 23 import android.os.Bundle; 24 import android.os.UserHandle; 25 import android.os.UserManager; 26 import android.preference.PreferenceManager; 27 28 import com.android.tv.settings.dialog.PinDialogFragment; 29 30 public class RestrictedProfilePinDialogFragment extends PinDialogFragment { 31 32 public interface Callback extends ResultListener { 33 /** 34 * Save the PIN password for the profile 35 * @param pin Password to save 36 * @param originalPin Previously saved password, or null if no password was previously set 37 * @param quality Password quality, see {@link DevicePolicyManager} 38 */ 39 void saveLockPassword(String pin, String originalPin, int quality); 40 41 /** 42 * Clear the PIN password 43 * @param oldPin Current PIN password (required) 44 */ 45 void clearLockPassword(String oldPin); 46 47 /** 48 * Check the PIN password for the specified userID 49 * @param password Password to check 50 * @param userId ID to check against 51 * @return {@code True} if password is correct 52 */ 53 boolean checkPassword(String password, int userId); 54 55 /** 56 * Query if there is a password set 57 * @return {@code True} if password is set 58 */ 59 boolean hasLockscreenSecurity(); 60 } 61 62 private static final String PREF_DISABLE_PIN_UNTIL = 63 "RestrictedProfileActivity$RestrictedProfilePinDialogFragment.disable_pin_until"; 64 65 public static RestrictedProfilePinDialogFragment newInstance(@PinDialogType int type) { 66 RestrictedProfilePinDialogFragment fragment = new RestrictedProfilePinDialogFragment(); 67 final Bundle b = new Bundle(1); 68 b.putInt(PinDialogFragment.ARG_TYPE, type); 69 fragment.setArguments(b); 70 return fragment; 71 } 72 73 /** 74 * Returns the time until we should disable the PIN dialog (because the user input wrong 75 * PINs repeatedly). 76 */ 77 public static long getDisablePinUntil(Context context) { 78 return PreferenceManager.getDefaultSharedPreferences(context).getLong( 79 PREF_DISABLE_PIN_UNTIL, 0); 80 } 81 82 /** 83 * Saves the time until we should disable the PIN dialog (because the user input wrong PINs 84 * repeatedly). 85 */ 86 public static void setDisablePinUntil(Context context, long timeMillis) { 87 PreferenceManager.getDefaultSharedPreferences(context).edit().putLong( 88 PREF_DISABLE_PIN_UNTIL, timeMillis).apply(); 89 } 90 91 @Override 92 public long getPinDisabledUntil() { 93 return getDisablePinUntil(getActivity()); 94 } 95 96 @Override 97 public void setPinDisabledUntil(long retryDisableTimeout) { 98 setDisablePinUntil(getActivity(), retryDisableTimeout); 99 } 100 101 @Override 102 public void setPin(String pin, String originalPin) { 103 Callback callback = null; 104 105 Fragment f = getTargetFragment(); 106 if (f instanceof Callback) { 107 callback = (Callback) f; 108 } 109 110 if (callback == null && getActivity() instanceof Callback) { 111 callback = (Callback) getActivity(); 112 } 113 114 if (callback != null) { 115 callback.saveLockPassword(pin, originalPin, 116 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); 117 } 118 } 119 120 @Override 121 public void deletePin(String oldPin) { 122 Callback callback = null; 123 124 Fragment f = getTargetFragment(); 125 if (f instanceof Callback) { 126 callback = (Callback) f; 127 } 128 129 if (callback == null && getActivity() instanceof Callback) { 130 callback = (Callback) getActivity(); 131 } 132 133 if (callback != null) { 134 callback.clearLockPassword(oldPin); 135 } 136 } 137 138 @Override 139 public boolean isPinCorrect(String pin) { 140 Callback callback = null; 141 142 Fragment f = getTargetFragment(); 143 if (f instanceof Callback) { 144 callback = (Callback) f; 145 } 146 147 if (callback == null && getActivity() instanceof Callback) { 148 callback = (Callback) getActivity(); 149 } 150 151 if (callback != null) { 152 UserInfo myUserInfo = UserManager.get(getActivity()).getUserInfo(UserHandle.myUserId()); 153 // UserInfo.restrictedProfileParentId may not be set if the restricted profile was 154 // created on Android M devices. 155 return myUserInfo != null && callback.checkPassword(pin, 156 myUserInfo.restrictedProfileParentId == UserHandle.USER_NULL 157 ? UserHandle.USER_OWNER : myUserInfo.restrictedProfileParentId); 158 } 159 return false; 160 } 161 162 @Override 163 public boolean isPinSet() { 164 Callback callback = null; 165 166 Fragment f = getTargetFragment(); 167 if (f instanceof Callback) { 168 callback = (Callback) f; 169 } 170 171 if (callback == null && getActivity() instanceof Callback) { 172 callback = (Callback) getActivity(); 173 } 174 175 if (callback != null) { 176 UserInfo myUserInfo = UserManager.get(getActivity()).getUserInfo(UserHandle.myUserId()); 177 return (myUserInfo != null && myUserInfo.isRestricted()) || 178 callback.hasLockscreenSecurity(); 179 } else { 180 throw new IllegalStateException("Can't call isPinSet when not attached"); 181 } 182 } 183 } 184