Misc fixes to CryptKeeper
- use standard IME, but force it into ASCII if it's the default IME - provide an IME switcher if there are multiple IME's, in case the ASCII-capable one is a different one - make the IME shown by default Bug: 5004456 Bug: 4698473 Change-Id: Id40a164cfe599bfdb67b81f60d4ab8a52208de88
This commit is contained in:
@@ -1148,7 +1148,8 @@
|
|||||||
android:immersive="true"
|
android:immersive="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@android:style/Theme.Holo.NoActionBar"
|
android:theme="@android:style/Theme.Holo.NoActionBar"
|
||||||
android:windowSoftInputMode="stateAlwaysHidden">
|
android:configChanges="mcc|mnc|keyboard|keyboardHidden|uiMode"
|
||||||
|
android:windowSoftInputMode="stateVisible|adjustResize">
|
||||||
<intent-filter android:priority="10">
|
<intent-filter android:priority="10">
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.HOME" />
|
<category android:name="android.intent.category.HOME" />
|
||||||
|
BIN
res/drawable-hdpi/ic_lockscreen_ime.png
Normal file
BIN
res/drawable-hdpi/ic_lockscreen_ime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 202 B |
BIN
res/drawable-mdpi/ic_lockscreen_ime.png
Normal file
BIN
res/drawable-mdpi/ic_lockscreen_ime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 157 B |
BIN
res/drawable-xhdpi/ic_lockscreen_ime.png
Normal file
BIN
res/drawable-xhdpi/ic_lockscreen_ime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 217 B |
62
res/layout-land/crypt_keeper_password_entry.xml
Normal file
62
res/layout-land/crypt_keeper_password_entry.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2011, 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_status" />
|
||||||
|
|
||||||
|
<!-- 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_margin="16dip"
|
||||||
|
style="@*android:style/Widget.Button.Transparent"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawablePadding="6dip"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginLeft="8dip"
|
||||||
|
android:layout_marginRight="8dip"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
<include layout="@layout/crypt_keeper_password_field" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
@@ -46,18 +46,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Password entry field -->
|
<!-- Password entry field -->
|
||||||
<view
|
<LinearLayout
|
||||||
class="com.android.settings.CryptKeeper$CryptEditText"
|
|
||||||
android:id="@+id/passwordEntry"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="320dip"
|
android:layout_width="320dip"
|
||||||
android:layout_toRightOf="@+id/passwordLabel"
|
android:layout_toRightOf="@+id/passwordLabel"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:singleLine="true"
|
android:orientation="horizontal"
|
||||||
android:inputType="textPassword"
|
>
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
<include layout="@layout/crypt_keeper_password_field" />
|
||||||
android:editable="false"
|
</LinearLayout>
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/status"
|
<TextView android:id="@+id/status"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@@ -45,18 +45,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Password entry field -->
|
<!-- Password entry field -->
|
||||||
<view
|
<LinearLayout
|
||||||
class="com.android.settings.CryptKeeper$CryptEditText"
|
|
||||||
android:id="@+id/passwordEntry"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="320dip"
|
android:layout_width="320dip"
|
||||||
android:layout_toRightOf="@+id/passwordLabel"
|
android:layout_toRightOf="@+id/passwordLabel"
|
||||||
android:layout_marginTop="26dip"
|
android:layout_marginTop="26dip"
|
||||||
android:singleLine="true"
|
android:orientation="horizontal"
|
||||||
android:inputType="textPassword"
|
>
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
<include layout="@layout/crypt_keeper_password_field" />
|
||||||
android:editable="false"
|
</LinearLayout>
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/status"
|
<TextView android:id="@+id/status"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -72,13 +69,4 @@
|
|||||||
/>
|
/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:background="#00000000"
|
|
||||||
android:keyBackground="@*android:drawable/btn_keyboard_key_fulltrans"
|
|
||||||
android:visibility="visible"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@@ -22,25 +22,17 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
>
|
>
|
||||||
<LinearLayout
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
>
|
|
||||||
<include layout="@layout/crypt_keeper_status" />
|
<include layout="@layout/crypt_keeper_status" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<EditText android:id="@+id/passwordEntry"
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginLeft="8dip"
|
android:layout_marginLeft="8dip"
|
||||||
android:layout_marginRight="8dip"
|
android:layout_marginRight="8dip"
|
||||||
android:singleLine="true"
|
android:orientation="horizontal"
|
||||||
android:inputType="textPassword"
|
>
|
||||||
android:textSize="18sp"
|
<include layout="@layout/crypt_keeper_password_field" />
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
</LinearLayout>
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Emergency call button.
|
<!-- Emergency call button.
|
||||||
Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
|
Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
|
||||||
|
44
res/layout/crypt_keeper_password_field.xml
Normal file
44
res/layout/crypt_keeper_password_field.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2011, 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="textPassword"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
|
||||||
|
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:padding="8dip"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
</merge>
|
@@ -32,7 +32,6 @@
|
|||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_marginTop="8dip"
|
android:layout_marginTop="8dip"
|
||||||
android:layout_marginBottom="8dip"
|
android:layout_marginBottom="8dip"
|
||||||
android:layout_marginLeft="-10dip"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
|
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
|
||||||
|
@@ -22,8 +22,6 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.inputmethodservice.KeyboardView;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -36,22 +34,22 @@ import android.os.SystemProperties;
|
|||||||
import android.os.storage.IMountService;
|
import android.os.storage.IMountService;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.internal.telephony.ITelephony;
|
import com.android.internal.telephony.ITelephony;
|
||||||
import com.android.internal.widget.PasswordEntryKeyboardHelper;
|
|
||||||
import com.android.internal.widget.PasswordEntryKeyboardView;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings screens to show the UI flows for encrypting/decrypting the device.
|
* Settings screens to show the UI flows for encrypting/decrypting the device.
|
||||||
@@ -112,37 +110,6 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a custom EditText to prevent the input method from showing.
|
|
||||||
public static class CryptEditText extends EditText {
|
|
||||||
InputMethodManager imm;
|
|
||||||
|
|
||||||
public CryptEditText(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
imm = ((InputMethodManager) getContext().
|
|
||||||
getSystemService(Context.INPUT_METHOD_SERVICE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
|
|
||||||
super.onFocusChanged(focused, direction, previouslyFocusedRect);
|
|
||||||
|
|
||||||
if (focused && imm != null && imm.isActive(this)) {
|
|
||||||
imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
boolean handled = super.onTouchEvent(event);
|
|
||||||
|
|
||||||
if (imm != null && imm.isActive(this)) {
|
|
||||||
imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DecryptTask extends AsyncTask<String, Void, Integer> {
|
private class DecryptTask extends AsyncTask<String, Void, Integer> {
|
||||||
@Override
|
@Override
|
||||||
protected Integer doInBackground(String... params) {
|
protected Integer doInBackground(String... params) {
|
||||||
@@ -387,18 +354,79 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
|||||||
private void passwordEntryInit() {
|
private void passwordEntryInit() {
|
||||||
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
|
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
|
||||||
mPasswordEntry.setOnEditorActionListener(this);
|
mPasswordEntry.setOnEditorActionListener(this);
|
||||||
|
mPasswordEntry.requestFocus();
|
||||||
|
|
||||||
KeyboardView keyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
|
View imeSwitcher = findViewById(R.id.switch_ime_button);
|
||||||
|
final InputMethodManager imm = (InputMethodManager) getSystemService(
|
||||||
if (keyboardView != null) {
|
Context.INPUT_METHOD_SERVICE);
|
||||||
PasswordEntryKeyboardHelper keyboardHelper = new PasswordEntryKeyboardHelper(this,
|
if (imeSwitcher != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
|
||||||
keyboardView, mPasswordEntry, false);
|
imeSwitcher.setVisibility(View.VISIBLE);
|
||||||
keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
|
imeSwitcher.setOnClickListener(new OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
imm.showInputMethodPicker();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Asynchronously throw up the IME, since there are issues with requesting it to be shown
|
||||||
|
// immediately.
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
imm.showSoftInputUnchecked(0, null);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
|
||||||
updateEmergencyCallButtonState();
|
updateEmergencyCallButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method adapted from com.android.inputmethod.latin.Utils
|
||||||
|
*
|
||||||
|
* @param imm The input method manager
|
||||||
|
* @param shouldIncludeAuxiliarySubtypes
|
||||||
|
* @return true if we have multiple IMEs to choose from
|
||||||
|
*/
|
||||||
|
private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
|
||||||
|
final boolean shouldIncludeAuxiliarySubtypes) {
|
||||||
|
final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
|
||||||
|
|
||||||
|
// Number of the filtered IMEs
|
||||||
|
int filteredImisCount = 0;
|
||||||
|
|
||||||
|
for (InputMethodInfo imi : enabledImis) {
|
||||||
|
// We can return true immediately after we find two or more filtered IMEs.
|
||||||
|
if (filteredImisCount > 1) return true;
|
||||||
|
final List<InputMethodSubtype> subtypes =
|
||||||
|
imm.getEnabledInputMethodSubtypeList(imi, true);
|
||||||
|
// IMEs that have no subtypes should be counted.
|
||||||
|
if (subtypes.isEmpty()) {
|
||||||
|
++filteredImisCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int auxCount = 0;
|
||||||
|
for (InputMethodSubtype subtype : subtypes) {
|
||||||
|
if (subtype.isAuxiliary()) {
|
||||||
|
++auxCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int nonAuxCount = subtypes.size() - auxCount;
|
||||||
|
|
||||||
|
// IMEs that have one or more non-auxiliary subtypes should be counted.
|
||||||
|
// If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
|
||||||
|
// subtypes should be counted as well.
|
||||||
|
if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
|
||||||
|
++filteredImisCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredImisCount > 1
|
||||||
|
// imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
|
||||||
|
// input method subtype (The current IME should be LatinIME.)
|
||||||
|
|| imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
private IMountService getMountService() {
|
private IMountService getMountService() {
|
||||||
IBinder service = ServiceManager.getService("mount");
|
IBinder service = ServiceManager.getService("mount");
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
|
Reference in New Issue
Block a user