diff options
-rw-r--r-- | AndroidManifest.xml | 3 | ||||
-rw-r--r-- | res/drawable-hdpi/ic_lockscreen_ime.png | bin | 0 -> 202 bytes | |||
-rw-r--r-- | res/drawable-mdpi/ic_lockscreen_ime.png | bin | 0 -> 157 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/ic_lockscreen_ime.png | bin | 0 -> 217 bytes | |||
-rw-r--r-- | res/layout-land/crypt_keeper_password_entry.xml | 62 | ||||
-rw-r--r-- | res/layout-sw600dp-land/crypt_keeper_password_entry.xml | 13 | ||||
-rw-r--r-- | res/layout-sw600dp/crypt_keeper_password_entry.xml | 24 | ||||
-rw-r--r-- | res/layout/crypt_keeper_password_entry.xml | 48 | ||||
-rw-r--r-- | res/layout/crypt_keeper_password_field.xml | 44 | ||||
-rw-r--r-- | res/layout/crypt_keeper_status.xml | 1 | ||||
-rw-r--r-- | src/com/android/settings/CryptKeeper.java | 114 |
11 files changed, 210 insertions, 99 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index bd456e8..96fdcc9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1148,7 +1148,8 @@ android:immersive="true" android:launchMode="singleTop" 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"> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> diff --git a/res/drawable-hdpi/ic_lockscreen_ime.png b/res/drawable-hdpi/ic_lockscreen_ime.png Binary files differnew file mode 100644 index 0000000..29a7989 --- /dev/null +++ b/res/drawable-hdpi/ic_lockscreen_ime.png diff --git a/res/drawable-mdpi/ic_lockscreen_ime.png b/res/drawable-mdpi/ic_lockscreen_ime.png Binary files differnew file mode 100644 index 0000000..b27e059 --- /dev/null +++ b/res/drawable-mdpi/ic_lockscreen_ime.png diff --git a/res/drawable-xhdpi/ic_lockscreen_ime.png b/res/drawable-xhdpi/ic_lockscreen_ime.png Binary files differnew file mode 100644 index 0000000..a40ddeb --- /dev/null +++ b/res/drawable-xhdpi/ic_lockscreen_ime.png diff --git a/res/layout-land/crypt_keeper_password_entry.xml b/res/layout-land/crypt_keeper_password_entry.xml new file mode 100644 index 0000000..094434e --- /dev/null +++ b/res/layout-land/crypt_keeper_password_entry.xml @@ -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> diff --git a/res/layout-sw600dp-land/crypt_keeper_password_entry.xml b/res/layout-sw600dp-land/crypt_keeper_password_entry.xml index 9415fd1..8898b76 100644 --- a/res/layout-sw600dp-land/crypt_keeper_password_entry.xml +++ b/res/layout-sw600dp-land/crypt_keeper_password_entry.xml @@ -46,18 +46,15 @@ /> <!-- Password entry field --> - <view - class="com.android.settings.CryptKeeper$CryptEditText" - android:id="@+id/passwordEntry" + <LinearLayout android:layout_height="wrap_content" android:layout_width="320dip" android:layout_toRightOf="@+id/passwordLabel" android:layout_centerVertical="true" - android:singleLine="true" - android:inputType="textPassword" - android:textAppearance="?android:attr/textAppearanceMedium" - android:editable="false" - /> + android:orientation="horizontal" + > + <include layout="@layout/crypt_keeper_password_field" /> + </LinearLayout> <TextView android:id="@+id/status" android:layout_height="wrap_content" diff --git a/res/layout-sw600dp/crypt_keeper_password_entry.xml b/res/layout-sw600dp/crypt_keeper_password_entry.xml index 0610ec0..bc2b353 100644 --- a/res/layout-sw600dp/crypt_keeper_password_entry.xml +++ b/res/layout-sw600dp/crypt_keeper_password_entry.xml @@ -45,18 +45,15 @@ /> <!-- Password entry field --> - <view - class="com.android.settings.CryptKeeper$CryptEditText" - android:id="@+id/passwordEntry" + <LinearLayout android:layout_height="wrap_content" android:layout_width="320dip" android:layout_toRightOf="@+id/passwordLabel" android:layout_marginTop="26dip" - android:singleLine="true" - android:inputType="textPassword" - android:textAppearance="?android:attr/textAppearanceMedium" - android:editable="false" - /> + android:orientation="horizontal" + > + <include layout="@layout/crypt_keeper_password_field" /> + </LinearLayout> <TextView android:id="@+id/status" android:layout_height="wrap_content" @@ -72,13 +69,4 @@ /> </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>
\ No newline at end of file +</RelativeLayout> diff --git a/res/layout/crypt_keeper_password_entry.xml b/res/layout/crypt_keeper_password_entry.xml index a7799fc..1278327 100644 --- a/res/layout/crypt_keeper_password_entry.xml +++ b/res/layout/crypt_keeper_password_entry.xml @@ -22,36 +22,28 @@ 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:orientation="vertical" - android:gravity="center_vertical" - > - <include layout="@layout/crypt_keeper_status" /> - </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> - <EditText android:id="@+id/passwordEntry" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:layout_marginLeft="8dip" - android:layout_marginRight="8dip" - android:singleLine="true" - android:inputType="textPassword" - android:textSize="18sp" - android:textAppearance="?android:attr/textAppearanceMedium" + <!-- 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" /> - <!-- 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> diff --git a/res/layout/crypt_keeper_password_field.xml b/res/layout/crypt_keeper_password_field.xml new file mode 100644 index 0000000..17968e8 --- /dev/null +++ b/res/layout/crypt_keeper_password_field.xml @@ -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> diff --git a/res/layout/crypt_keeper_status.xml b/res/layout/crypt_keeper_status.xml index b830b57..59d2365 100644 --- a/res/layout/crypt_keeper_status.xml +++ b/res/layout/crypt_keeper_status.xml @@ -32,7 +32,6 @@ android:layout_alignParentLeft="true" android:layout_marginTop="8dip" android:layout_marginBottom="8dip" - android:layout_marginLeft="-10dip" > <!-- Because we can't have multi-tone fonts, we render two TextViews, one on diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java index 0552b68..0c8ce28 100644 --- a/src/com/android/settings/CryptKeeper.java +++ b/src/com/android/settings/CryptKeeper.java @@ -22,8 +22,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.graphics.Rect; -import android.inputmethodservice.KeyboardView; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; @@ -36,22 +34,22 @@ import android.os.SystemProperties; import android.os.storage.IMountService; import android.telephony.TelephonyManager; import android.text.TextUtils; -import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; 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. @@ -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> { @Override protected Integer doInBackground(String... params) { @@ -387,16 +354,77 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList private void passwordEntryInit() { mPasswordEntry = (EditText) findViewById(R.id.passwordEntry); mPasswordEntry.setOnEditorActionListener(this); + mPasswordEntry.requestFocus(); + + View imeSwitcher = findViewById(R.id.switch_ime_button); + final InputMethodManager imm = (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); + if (imeSwitcher != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) { + imeSwitcher.setVisibility(View.VISIBLE); + 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(); + } - KeyboardView keyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); + /** + * 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; + } - if (keyboardView != null) { - PasswordEntryKeyboardHelper keyboardHelper = new PasswordEntryKeyboardHelper(this, - keyboardView, mPasswordEntry, false); - keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); + 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; + } } - updateEmergencyCallButtonState(); + 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() { |