Support default, pattern, pin and password encryption types
Use plumbing provided by dependant change to bring up correct dialog at boot time. Needs matching framework changes from https://googleplex-android-review.googlesource.com/#/c/412885/ Bug: 8769627 Change-Id: Ib04a2875e051a7cccca035fadb25978dfec22491
This commit is contained in:
49
res/layout/crypt_keeper_pattern_entry.xml
Normal file
49
res/layout/crypt_keeper_pattern_entry.xml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2014, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_status" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_pattern_field" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Emergency call button.
|
||||||
|
Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
|
||||||
|
<Button android:id="@+id/emergencyCallButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="16dip"
|
||||||
|
style="@*android:style/Widget.Button.Transparent"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawablePadding="6dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
38
res/layout/crypt_keeper_pattern_field.xml
Normal file
38
res/layout/crypt_keeper_pattern_field.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2014, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
|
||||||
|
switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/switch_ime_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_lockscreen_ime"
|
||||||
|
android:clickable="true"
|
||||||
|
android:contentDescription="@string/crypt_keeper_switch_input_method"
|
||||||
|
android:padding="8dip"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
</merge>
|
49
res/layout/crypt_keeper_pin_entry.xml
Normal file
49
res/layout/crypt_keeper_pin_entry.xml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2014, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_status" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_pin_field" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Emergency call button.
|
||||||
|
Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
|
||||||
|
<Button android:id="@+id/emergencyCallButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="16dip"
|
||||||
|
style="@*android:style/Widget.Button.Transparent"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawablePadding="6dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
44
res/layout/crypt_keeper_pin_field.xml
Normal file
44
res/layout/crypt_keeper_pin_field.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2014, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
|
||||||
|
switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<EditText android:id="@+id/passwordEntry"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:inputType="numberPassword"
|
||||||
|
android:imeOptions="flagForceAscii|actionDone"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/switch_ime_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_lockscreen_ime"
|
||||||
|
android:clickable="true"
|
||||||
|
android:contentDescription="@string/crypt_keeper_switch_input_method"
|
||||||
|
android:padding="8dip"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
</merge>
|
@@ -226,21 +226,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
private int upgradeQuality(int quality, MutableBoolean allowBiometric) {
|
private int upgradeQuality(int quality, MutableBoolean allowBiometric) {
|
||||||
quality = upgradeQualityForDPM(quality);
|
quality = upgradeQualityForDPM(quality);
|
||||||
quality = upgradeQualityForKeyStore(quality);
|
quality = upgradeQualityForKeyStore(quality);
|
||||||
int encryptionQuality = upgradeQualityForEncryption(quality);
|
|
||||||
if (encryptionQuality > quality) {
|
|
||||||
//The first case checks whether biometric is allowed, prior to the user making
|
|
||||||
//their selection from the list
|
|
||||||
if (allowBiometric != null) {
|
|
||||||
allowBiometric.value = quality <=
|
|
||||||
DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
|
|
||||||
} else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
|
|
||||||
//When the user has selected biometric we shouldn't change that due to
|
|
||||||
//encryption
|
|
||||||
return quality;
|
return quality;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return encryptionQuality;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int upgradeQualityForDPM(int quality) {
|
private int upgradeQualityForDPM(int quality) {
|
||||||
// Compare min allowed password quality
|
// Compare min allowed password quality
|
||||||
@@ -251,27 +238,6 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
return quality;
|
return quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix in "encryption minimums" to any given quality value. This prevents users
|
|
||||||
* from downgrading the pattern/pin/password to a level below the minimums.
|
|
||||||
*
|
|
||||||
* ASSUMPTION: Setting quality is sufficient (e.g. minimum lengths will be set
|
|
||||||
* appropriately.)
|
|
||||||
*/
|
|
||||||
private int upgradeQualityForEncryption(int quality) {
|
|
||||||
// Don't upgrade quality for secondary users. Encryption requirements don't apply.
|
|
||||||
if (!Process.myUserHandle().equals(UserHandle.OWNER)) return quality;
|
|
||||||
int encryptionStatus = mDPM.getStorageEncryptionStatus();
|
|
||||||
boolean encrypted = (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE)
|
|
||||||
|| (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING);
|
|
||||||
if (encrypted) {
|
|
||||||
if (quality < CryptKeeperSettings.MIN_PASSWORD_QUALITY) {
|
|
||||||
quality = CryptKeeperSettings.MIN_PASSWORD_QUALITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int upgradeQualityForKeyStore(int quality) {
|
private int upgradeQualityForKeyStore(int quality) {
|
||||||
if (!mKeyStore.isEmpty()) {
|
if (!mKeyStore.isEmpty()) {
|
||||||
if (quality < CredentialStorage.MIN_PASSWORD_QUALITY) {
|
if (quality < CredentialStorage.MIN_PASSWORD_QUALITY) {
|
||||||
|
@@ -34,6 +34,7 @@ import android.os.ServiceManager;
|
|||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.storage.IMountService;
|
import android.os.storage.IMountService;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
@@ -60,6 +61,9 @@ import com.android.internal.statusbar.StatusBarIcon;
|
|||||||
import com.android.internal.telephony.ITelephony;
|
import com.android.internal.telephony.ITelephony;
|
||||||
import com.android.internal.telephony.Phone;
|
import com.android.internal.telephony.Phone;
|
||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.internal.widget.LockPatternView;
|
||||||
|
import com.android.internal.widget.LockPatternView.Cell;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -113,6 +117,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
private int mCooldown;
|
private int mCooldown;
|
||||||
PowerManager.WakeLock mWakeLock;
|
PowerManager.WakeLock mWakeLock;
|
||||||
private EditText mPasswordEntry;
|
private EditText mPasswordEntry;
|
||||||
|
private LockPatternView mLockPatternView;
|
||||||
/** Number of calls to {@link #notifyUser()} to ignore before notifying. */
|
/** Number of calls to {@link #notifyUser()} to ignore before notifying. */
|
||||||
private int mNotificationCountdown = 0;
|
private int mNotificationCountdown = 0;
|
||||||
|
|
||||||
@@ -175,10 +180,12 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
final TextView status = (TextView) findViewById(R.id.status);
|
final TextView status = (TextView) findViewById(R.id.status);
|
||||||
status.setText(R.string.try_again);
|
status.setText(R.string.try_again);
|
||||||
// Reenable the password entry
|
// Reenable the password entry
|
||||||
|
if (mPasswordEntry != null) {
|
||||||
mPasswordEntry.setEnabled(true);
|
mPasswordEntry.setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ValidationTask extends AsyncTask<Void, Void, Boolean> {
|
private class ValidationTask extends AsyncTask<Void, Void, Boolean> {
|
||||||
@Override
|
@Override
|
||||||
@@ -354,7 +361,21 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
setContentView(R.layout.crypt_keeper_progress);
|
setContentView(R.layout.crypt_keeper_progress);
|
||||||
encryptionProgressInit();
|
encryptionProgressInit();
|
||||||
} else if (mValidationComplete || isDebugView(FORCE_VIEW_PASSWORD)) {
|
} else if (mValidationComplete || isDebugView(FORCE_VIEW_PASSWORD)) {
|
||||||
|
final IMountService service = getMountService();
|
||||||
|
int type = StorageManager.CRYPT_TYPE_PASSWORD;
|
||||||
|
try {
|
||||||
|
type = service.getPasswordType();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error while getting type - showing default dialog" + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == StorageManager.CRYPT_TYPE_PIN) {
|
||||||
|
setContentView(R.layout.crypt_keeper_pin_entry);
|
||||||
|
} else if (type == StorageManager.CRYPT_TYPE_PATTERN) {
|
||||||
|
setContentView(R.layout.crypt_keeper_pattern_entry);
|
||||||
|
} else {
|
||||||
setContentView(R.layout.crypt_keeper_password_entry);
|
setContentView(R.layout.crypt_keeper_password_entry);
|
||||||
|
}
|
||||||
passwordEntryInit();
|
passwordEntryInit();
|
||||||
} else if (!mValidationRequested) {
|
} else if (!mValidationRequested) {
|
||||||
// We're supposed to be encrypted, but no validation has been done.
|
// We're supposed to be encrypted, but no validation has been done.
|
||||||
@@ -503,14 +524,44 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =
|
||||||
|
new LockPatternView.OnPatternListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPatternStart() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPatternCleared() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
|
||||||
|
new DecryptTask().execute(LockPatternUtils.patternToString(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPatternCellAdded(List<Cell> pattern) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private void passwordEntryInit() {
|
private void passwordEntryInit() {
|
||||||
|
// Password/pin case
|
||||||
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
|
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
|
||||||
|
if (mPasswordEntry != null){
|
||||||
mPasswordEntry.setOnEditorActionListener(this);
|
mPasswordEntry.setOnEditorActionListener(this);
|
||||||
mPasswordEntry.requestFocus();
|
mPasswordEntry.requestFocus();
|
||||||
// Become quiet when the user interacts with the Edit text screen.
|
// Become quiet when the user interacts with the Edit text screen.
|
||||||
mPasswordEntry.setOnKeyListener(this);
|
mPasswordEntry.setOnKeyListener(this);
|
||||||
mPasswordEntry.setOnTouchListener(this);
|
mPasswordEntry.setOnTouchListener(this);
|
||||||
mPasswordEntry.addTextChangedListener(this);
|
mPasswordEntry.addTextChangedListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern case
|
||||||
|
mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
|
||||||
|
if (mLockPatternView != null) {
|
||||||
|
mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
|
||||||
|
}
|
||||||
|
|
||||||
// Disable the Emergency call button if the device has no voice telephone capability
|
// Disable the Emergency call button if the device has no voice telephone capability
|
||||||
final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
Reference in New Issue
Block a user