182beadfa067b1e286fa604f8d7960d769411c954satok/* 282beadfa067b1e286fa604f8d7960d769411c954satok * Copyright (C) 2011 The Android Open Source Project 382beadfa067b1e286fa604f8d7960d769411c954satok * 482beadfa067b1e286fa604f8d7960d769411c954satok * Licensed under the Apache License, Version 2.0 (the "License"); 582beadfa067b1e286fa604f8d7960d769411c954satok * you may not use this file except in compliance with the License. 682beadfa067b1e286fa604f8d7960d769411c954satok * You may obtain a copy of the License at 782beadfa067b1e286fa604f8d7960d769411c954satok * 882beadfa067b1e286fa604f8d7960d769411c954satok * http://www.apache.org/licenses/LICENSE-2.0 982beadfa067b1e286fa604f8d7960d769411c954satok * 1082beadfa067b1e286fa604f8d7960d769411c954satok * Unless required by applicable law or agreed to in writing, software 1182beadfa067b1e286fa604f8d7960d769411c954satok * distributed under the License is distributed on an "AS IS" BASIS, 1282beadfa067b1e286fa604f8d7960d769411c954satok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382beadfa067b1e286fa604f8d7960d769411c954satok * See the License for the specific language governing permissions and 1482beadfa067b1e286fa604f8d7960d769411c954satok * limitations under the License. 1582beadfa067b1e286fa604f8d7960d769411c954satok */ 1682beadfa067b1e286fa604f8d7960d769411c954satok 1782beadfa067b1e286fa604f8d7960d769411c954satokpackage com.android.systemui.statusbar.tablet; 1882beadfa067b1e286fa604f8d7960d769411c954satok 191c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaokaimport com.android.systemui.R; 201c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka 210ee6613d09eff218211c2624774b12981699bfd2satokimport android.content.BroadcastReceiver; 2282beadfa067b1e286fa604f8d7960d769411c954satokimport android.content.Context; 2382beadfa067b1e286fa604f8d7960d769411c954satokimport android.content.Intent; 240ee6613d09eff218211c2624774b12981699bfd2satokimport android.content.IntentFilter; 2582beadfa067b1e286fa604f8d7960d769411c954satokimport android.content.pm.PackageManager; 2682beadfa067b1e286fa604f8d7960d769411c954satokimport android.graphics.drawable.Drawable; 2782beadfa067b1e286fa604f8d7960d769411c954satokimport android.os.IBinder; 2882beadfa067b1e286fa604f8d7960d769411c954satokimport android.provider.Settings; 2982beadfa067b1e286fa604f8d7960d769411c954satokimport android.text.TextUtils; 3082beadfa067b1e286fa604f8d7960d769411c954satokimport android.util.AttributeSet; 3182beadfa067b1e286fa604f8d7960d769411c954satokimport android.util.Log; 3282beadfa067b1e286fa604f8d7960d769411c954satokimport android.util.Pair; 336179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganovimport android.view.MotionEvent; 3482beadfa067b1e286fa604f8d7960d769411c954satokimport android.view.View; 3582beadfa067b1e286fa604f8d7960d769411c954satokimport android.view.inputmethod.InputMethodInfo; 3682beadfa067b1e286fa604f8d7960d769411c954satokimport android.view.inputmethod.InputMethodManager; 3782beadfa067b1e286fa604f8d7960d769411c954satokimport android.view.inputmethod.InputMethodSubtype; 3882beadfa067b1e286fa604f8d7960d769411c954satokimport android.widget.ImageView; 3982beadfa067b1e286fa604f8d7960d769411c954satokimport android.widget.LinearLayout; 4082beadfa067b1e286fa604f8d7960d769411c954satokimport android.widget.RadioButton; 412992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brownimport android.widget.Switch; 4282beadfa067b1e286fa604f8d7960d769411c954satokimport android.widget.TextView; 4382beadfa067b1e286fa604f8d7960d769411c954satok 447dc93a1df7731672b321b78316afff2104dcf239satokimport java.util.Comparator; 4582beadfa067b1e286fa604f8d7960d769411c954satokimport java.util.HashMap; 4682beadfa067b1e286fa604f8d7960d769411c954satokimport java.util.List; 477dc93a1df7731672b321b78316afff2104dcf239satokimport java.util.Map; 4882beadfa067b1e286fa604f8d7960d769411c954satokimport java.util.Set; 497dc93a1df7731672b321b78316afff2104dcf239satokimport java.util.TreeMap; 5082beadfa067b1e286fa604f8d7960d769411c954satok 51e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaokapublic class InputMethodsPanel extends LinearLayout implements StatusBarPanel, 52e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka View.OnClickListener { 5382beadfa067b1e286fa604f8d7960d769411c954satok private static final boolean DEBUG = TabletStatusBar.DEBUG; 5482beadfa067b1e286fa604f8d7960d769411c954satok private static final String TAG = "InputMethodsPanel"; 5582beadfa067b1e286fa604f8d7960d769411c954satok 560ee6613d09eff218211c2624774b12981699bfd2satok private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 570ee6613d09eff218211c2624774b12981699bfd2satok @Override 580ee6613d09eff218211c2624774b12981699bfd2satok public void onReceive(Context context, Intent intent) { 590ee6613d09eff218211c2624774b12981699bfd2satok onPackageChanged(); 600ee6613d09eff218211c2624774b12981699bfd2satok } 610ee6613d09eff218211c2624774b12981699bfd2satok }; 620ee6613d09eff218211c2624774b12981699bfd2satok 6382beadfa067b1e286fa604f8d7960d769411c954satok private final InputMethodManager mImm; 640ee6613d09eff218211c2624774b12981699bfd2satok private final IntentFilter mIntentFilter = new IntentFilter(); 650ee6613d09eff218211c2624774b12981699bfd2satok private final HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>> mRadioViewAndImiMap = 660ee6613d09eff218211c2624774b12981699bfd2satok new HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>>(); 677dc93a1df7731672b321b78316afff2104dcf239satok private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> 6882beadfa067b1e286fa604f8d7960d769411c954satok mEnabledInputMethodAndSubtypesCache = 697dc93a1df7731672b321b78316afff2104dcf239satok new TreeMap<InputMethodInfo, List<InputMethodSubtype>>( 707dc93a1df7731672b321b78316afff2104dcf239satok new InputMethodComparator()); 7182beadfa067b1e286fa604f8d7960d769411c954satok 720ee6613d09eff218211c2624774b12981699bfd2satok private boolean mAttached = false; 730ee6613d09eff218211c2624774b12981699bfd2satok private boolean mPackageChanged = false; 7482beadfa067b1e286fa604f8d7960d769411c954satok private Context mContext; 7582beadfa067b1e286fa604f8d7960d769411c954satok private IBinder mToken; 76913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok private InputMethodButton mInputMethodSwitchButton; 7782beadfa067b1e286fa604f8d7960d769411c954satok private LinearLayout mInputMethodMenuList; 782992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private boolean mHardKeyboardAvailable; 792992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private boolean mHardKeyboardEnabled; 802992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private OnHardKeyboardEnabledChangeListener mHardKeyboardEnabledChangeListener; 812992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private LinearLayout mHardKeyboardSection; 822992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private Switch mHardKeyboardSwitch; 83913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok private PackageManager mPackageManager; 8482beadfa067b1e286fa604f8d7960d769411c954satok private String mEnabledInputMethodAndSubtypesCacheStr; 85cf5f6d107a50f8b859158adc00254df72a1aec7esatok private String mLastSystemLocaleString; 8682beadfa067b1e286fa604f8d7960d769411c954satok private View mConfigureImeShortcut; 8782beadfa067b1e286fa604f8d7960d769411c954satok 887dc93a1df7731672b321b78316afff2104dcf239satok private class InputMethodComparator implements Comparator<InputMethodInfo> { 89e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka @Override 907dc93a1df7731672b321b78316afff2104dcf239satok public int compare(InputMethodInfo imi1, InputMethodInfo imi2) { 917dc93a1df7731672b321b78316afff2104dcf239satok if (imi2 == null) return 0; 927dc93a1df7731672b321b78316afff2104dcf239satok if (imi1 == null) return 1; 93761eb3762f3602dd1859905ee4ba80f0ef6aec56Ken Wakasa if (mPackageManager == null) { 94761eb3762f3602dd1859905ee4ba80f0ef6aec56Ken Wakasa return imi1.getId().compareTo(imi2.getId()); 957dc93a1df7731672b321b78316afff2104dcf239satok } 96761eb3762f3602dd1859905ee4ba80f0ef6aec56Ken Wakasa CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId(); 97761eb3762f3602dd1859905ee4ba80f0ef6aec56Ken Wakasa CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId(); 98761eb3762f3602dd1859905ee4ba80f0ef6aec56Ken Wakasa return imiId1.toString().compareTo(imiId2.toString()); 997dc93a1df7731672b321b78316afff2104dcf239satok } 1007dc93a1df7731672b321b78316afff2104dcf239satok } 1017dc93a1df7731672b321b78316afff2104dcf239satok 10282beadfa067b1e286fa604f8d7960d769411c954satok public InputMethodsPanel(Context context, AttributeSet attrs) { 10382beadfa067b1e286fa604f8d7960d769411c954satok this(context, attrs, 0); 10482beadfa067b1e286fa604f8d7960d769411c954satok } 10582beadfa067b1e286fa604f8d7960d769411c954satok 10682beadfa067b1e286fa604f8d7960d769411c954satok public InputMethodsPanel(Context context, AttributeSet attrs, int defStyle) { 10782beadfa067b1e286fa604f8d7960d769411c954satok super(context, attrs, defStyle); 10882beadfa067b1e286fa604f8d7960d769411c954satok mContext = context; 10982beadfa067b1e286fa604f8d7960d769411c954satok mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 1100ee6613d09eff218211c2624774b12981699bfd2satok mIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); 1110ee6613d09eff218211c2624774b12981699bfd2satok mIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 1120ee6613d09eff218211c2624774b12981699bfd2satok mIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1130ee6613d09eff218211c2624774b12981699bfd2satok mIntentFilter.addDataScheme("package"); 1140ee6613d09eff218211c2624774b12981699bfd2satok } 1150ee6613d09eff218211c2624774b12981699bfd2satok 1162992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void setHardKeyboardEnabledChangeListener( 1172992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown OnHardKeyboardEnabledChangeListener listener) { 1182992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardEnabledChangeListener = listener; 1192992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 1202992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 1210ee6613d09eff218211c2624774b12981699bfd2satok @Override 1220ee6613d09eff218211c2624774b12981699bfd2satok protected void onDetachedFromWindow() { 1230ee6613d09eff218211c2624774b12981699bfd2satok super.onDetachedFromWindow(); 1240ee6613d09eff218211c2624774b12981699bfd2satok if (mAttached) { 1250ee6613d09eff218211c2624774b12981699bfd2satok getContext().unregisterReceiver(mBroadcastReceiver); 1260ee6613d09eff218211c2624774b12981699bfd2satok mAttached = false; 1270ee6613d09eff218211c2624774b12981699bfd2satok } 1280ee6613d09eff218211c2624774b12981699bfd2satok } 1290ee6613d09eff218211c2624774b12981699bfd2satok 1300ee6613d09eff218211c2624774b12981699bfd2satok @Override 1310ee6613d09eff218211c2624774b12981699bfd2satok protected void onAttachedToWindow() { 1320ee6613d09eff218211c2624774b12981699bfd2satok super.onAttachedToWindow(); 1330ee6613d09eff218211c2624774b12981699bfd2satok if (!mAttached) { 1340ee6613d09eff218211c2624774b12981699bfd2satok getContext().registerReceiver(mBroadcastReceiver, mIntentFilter); 1350ee6613d09eff218211c2624774b12981699bfd2satok mAttached = true; 1360ee6613d09eff218211c2624774b12981699bfd2satok } 13782beadfa067b1e286fa604f8d7960d769411c954satok } 13882beadfa067b1e286fa604f8d7960d769411c954satok 13982beadfa067b1e286fa604f8d7960d769411c954satok @Override 14082beadfa067b1e286fa604f8d7960d769411c954satok public void onFinishInflate() { 14182beadfa067b1e286fa604f8d7960d769411c954satok mInputMethodMenuList = (LinearLayout) findViewById(R.id.input_method_menu_list); 1422992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardSection = (LinearLayout) findViewById(R.id.hard_keyboard_section); 1432992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardSwitch = (Switch) findViewById(R.id.hard_keyboard_switch); 1441c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka mConfigureImeShortcut = findViewById(R.id.ime_settings_shortcut); 14582beadfa067b1e286fa604f8d7960d769411c954satok mConfigureImeShortcut.setOnClickListener(this); 14682beadfa067b1e286fa604f8d7960d769411c954satok // TODO: If configurations for IME are not changed, do not update 14782beadfa067b1e286fa604f8d7960d769411c954satok // by checking onConfigurationChanged. 14882beadfa067b1e286fa604f8d7960d769411c954satok updateUiElements(); 14982beadfa067b1e286fa604f8d7960d769411c954satok } 15082beadfa067b1e286fa604f8d7960d769411c954satok 15182beadfa067b1e286fa604f8d7960d769411c954satok @Override 15282beadfa067b1e286fa604f8d7960d769411c954satok public boolean isInContentArea(int x, int y) { 15382beadfa067b1e286fa604f8d7960d769411c954satok return false; 15482beadfa067b1e286fa604f8d7960d769411c954satok } 15582beadfa067b1e286fa604f8d7960d769411c954satok 15682beadfa067b1e286fa604f8d7960d769411c954satok @Override 15782beadfa067b1e286fa604f8d7960d769411c954satok public void onClick(View view) { 15882beadfa067b1e286fa604f8d7960d769411c954satok if (view == mConfigureImeShortcut) { 15982beadfa067b1e286fa604f8d7960d769411c954satok showConfigureInputMethods(); 160e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka closePanel(true); 1611c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka } 1621c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka } 1631c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka 1646179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov @Override 1656179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov public boolean dispatchHoverEvent(MotionEvent event) { 1666179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov // Ignore hover events outside of this panel bounds since such events 1676179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov // generate spurious accessibility events with the panel content when 1686179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov // tapping outside of it, thus confusing the user. 1696179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov final int x = (int) event.getX(); 1706179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov final int y = (int) event.getY(); 1716179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { 1726179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov return super.dispatchHoverEvent(event); 1736179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov } 1746179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov return true; 1756179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov } 1766179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov 177e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka private void updateHardKeyboardEnabled() { 178e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka if (mHardKeyboardAvailable) { 179e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka final boolean checked = mHardKeyboardSwitch.isChecked(); 1801c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka if (mHardKeyboardEnabled != checked) { 1811c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka mHardKeyboardEnabled = checked; 1821c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka if (mHardKeyboardEnabledChangeListener != null) 1831c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka mHardKeyboardEnabledChangeListener.onHardKeyboardEnabledChange(checked); 1841c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka } 18582beadfa067b1e286fa604f8d7960d769411c954satok } 18682beadfa067b1e286fa604f8d7960d769411c954satok } 18782beadfa067b1e286fa604f8d7960d769411c954satok 188e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka public void openPanel() { 189e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka setVisibility(View.VISIBLE); 190e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka updateUiElements(); 191e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka if (mInputMethodSwitchButton != null) { 192e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime_pressed); 193e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka } 194e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka } 195e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka 196e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka public void closePanel(boolean closeKeyboard) { 19782beadfa067b1e286fa604f8d7960d769411c954satok setVisibility(View.GONE); 198e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka if (mInputMethodSwitchButton != null) { 199e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime); 200e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka } 20182beadfa067b1e286fa604f8d7960d769411c954satok if (closeKeyboard) { 20282beadfa067b1e286fa604f8d7960d769411c954satok mImm.hideSoftInputFromWindow(getWindowToken(), 0); 20382beadfa067b1e286fa604f8d7960d769411c954satok } 20482beadfa067b1e286fa604f8d7960d769411c954satok } 20582beadfa067b1e286fa604f8d7960d769411c954satok 20682beadfa067b1e286fa604f8d7960d769411c954satok private void startActivity(Intent intent) { 20782beadfa067b1e286fa604f8d7960d769411c954satok mContext.startActivity(intent); 20882beadfa067b1e286fa604f8d7960d769411c954satok } 20982beadfa067b1e286fa604f8d7960d769411c954satok 21082beadfa067b1e286fa604f8d7960d769411c954satok private void showConfigureInputMethods() { 21182beadfa067b1e286fa604f8d7960d769411c954satok Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS); 21282beadfa067b1e286fa604f8d7960d769411c954satok intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 21382beadfa067b1e286fa604f8d7960d769411c954satok | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 21482beadfa067b1e286fa604f8d7960d769411c954satok | Intent.FLAG_ACTIVITY_CLEAR_TOP); 21582beadfa067b1e286fa604f8d7960d769411c954satok startActivity(intent); 21682beadfa067b1e286fa604f8d7960d769411c954satok } 21782beadfa067b1e286fa604f8d7960d769411c954satok 21882beadfa067b1e286fa604f8d7960d769411c954satok private View createInputMethodItem( 21982beadfa067b1e286fa604f8d7960d769411c954satok final InputMethodInfo imi, final InputMethodSubtype subtype) { 220e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa final CharSequence subtypeName; 221e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa if (subtype == null || subtype.overridesImplicitlyEnabledSubtype()) { 222e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa subtypeName = null; 223e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa } else { 224e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa subtypeName = getSubtypeName(imi, subtype); 225e00633e49a7136e14da8ce9938cf6a3333f28498Ken Wakasa } 226bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final CharSequence imiName = getIMIName(imi); 227bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final Drawable icon = getSubtypeIcon(imi, subtype); 2284a066c5c77109431f50806fc29179d28f1472871Daniel Sandler final View view = View.inflate(mContext, R.layout.system_bar_input_methods_item, null); 229bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final ImageView subtypeIcon = (ImageView)view.findViewById(R.id.item_icon); 230bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final TextView itemTitle = (TextView)view.findViewById(R.id.item_title); 231bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final TextView itemSubtitle = (TextView)view.findViewById(R.id.item_subtitle); 232bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final ImageView settingsIcon = (ImageView)view.findViewById(R.id.item_settings_icon); 233bbf0b66edef9f3fe537dbf16fed6bd2e6651d9cfKen Wakasa final View subtypeView = view.findViewById(R.id.item_subtype); 23482beadfa067b1e286fa604f8d7960d769411c954satok if (subtypeName == null) { 23582beadfa067b1e286fa604f8d7960d769411c954satok itemTitle.setText(imiName); 23682beadfa067b1e286fa604f8d7960d769411c954satok itemSubtitle.setVisibility(View.GONE); 23782beadfa067b1e286fa604f8d7960d769411c954satok } else { 23882beadfa067b1e286fa604f8d7960d769411c954satok itemTitle.setText(subtypeName); 23982beadfa067b1e286fa604f8d7960d769411c954satok itemSubtitle.setVisibility(View.VISIBLE); 24082beadfa067b1e286fa604f8d7960d769411c954satok itemSubtitle.setText(imiName); 24182beadfa067b1e286fa604f8d7960d769411c954satok } 24282beadfa067b1e286fa604f8d7960d769411c954satok subtypeIcon.setImageDrawable(icon); 2436179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov subtypeIcon.setContentDescription(itemTitle.getText()); 24482beadfa067b1e286fa604f8d7960d769411c954satok final String settingsActivity = imi.getSettingsActivity(); 24582beadfa067b1e286fa604f8d7960d769411c954satok if (!TextUtils.isEmpty(settingsActivity)) { 24682beadfa067b1e286fa604f8d7960d769411c954satok settingsIcon.setOnClickListener(new View.OnClickListener() { 24782beadfa067b1e286fa604f8d7960d769411c954satok @Override 24882beadfa067b1e286fa604f8d7960d769411c954satok public void onClick(View arg0) { 24982beadfa067b1e286fa604f8d7960d769411c954satok Intent intent = new Intent(Intent.ACTION_MAIN); 25082beadfa067b1e286fa604f8d7960d769411c954satok intent.setClassName(imi.getPackageName(), settingsActivity); 25182beadfa067b1e286fa604f8d7960d769411c954satok intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 25282beadfa067b1e286fa604f8d7960d769411c954satok | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 25382beadfa067b1e286fa604f8d7960d769411c954satok | Intent.FLAG_ACTIVITY_CLEAR_TOP); 25482beadfa067b1e286fa604f8d7960d769411c954satok startActivity(intent); 255e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka closePanel(true); 25682beadfa067b1e286fa604f8d7960d769411c954satok } 25782beadfa067b1e286fa604f8d7960d769411c954satok }); 25882beadfa067b1e286fa604f8d7960d769411c954satok } else { 25982beadfa067b1e286fa604f8d7960d769411c954satok // Do not show the settings icon if the IME does not have a settings preference 26082beadfa067b1e286fa604f8d7960d769411c954satok view.findViewById(R.id.item_vertical_separator).setVisibility(View.GONE); 26182beadfa067b1e286fa604f8d7960d769411c954satok settingsIcon.setVisibility(View.GONE); 26282beadfa067b1e286fa604f8d7960d769411c954satok } 26382beadfa067b1e286fa604f8d7960d769411c954satok mRadioViewAndImiMap.put( 26482beadfa067b1e286fa604f8d7960d769411c954satok subtypeView, new Pair<InputMethodInfo, InputMethodSubtype> (imi, subtype)); 26582beadfa067b1e286fa604f8d7960d769411c954satok subtypeView.setOnClickListener(new View.OnClickListener() { 26682beadfa067b1e286fa604f8d7960d769411c954satok @Override 2671c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka public void onClick(View v) { 26882beadfa067b1e286fa604f8d7960d769411c954satok Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype = 2691c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka updateRadioButtonsByView(v); 270e385f0c771e5338200486bdca82088ad6f3a9c97Tadashi G. Takaoka closePanel(false); 27182beadfa067b1e286fa604f8d7960d769411c954satok setInputMethodAndSubtype(imiAndSubtype.first, imiAndSubtype.second); 27282beadfa067b1e286fa604f8d7960d769411c954satok } 27382beadfa067b1e286fa604f8d7960d769411c954satok }); 27482beadfa067b1e286fa604f8d7960d769411c954satok return view; 27582beadfa067b1e286fa604f8d7960d769411c954satok } 27682beadfa067b1e286fa604f8d7960d769411c954satok 27782beadfa067b1e286fa604f8d7960d769411c954satok private void updateUiElements() { 2782992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown updateHardKeyboardSection(); 2792992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 28082beadfa067b1e286fa604f8d7960d769411c954satok // TODO: Reuse subtype views. 28182beadfa067b1e286fa604f8d7960d769411c954satok mInputMethodMenuList.removeAllViews(); 28282beadfa067b1e286fa604f8d7960d769411c954satok mRadioViewAndImiMap.clear(); 283913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok mPackageManager = mContext.getPackageManager(); 284913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok 2857dc93a1df7731672b321b78316afff2104dcf239satok Map<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs = 2867dc93a1df7731672b321b78316afff2104dcf239satok getEnabledInputMethodAndSubtypeList(); 28782beadfa067b1e286fa604f8d7960d769411c954satok Set<InputMethodInfo> cachedImiSet = enabledIMIs.keySet(); 28882beadfa067b1e286fa604f8d7960d769411c954satok for (InputMethodInfo imi: cachedImiSet) { 28982beadfa067b1e286fa604f8d7960d769411c954satok List<InputMethodSubtype> subtypes = enabledIMIs.get(imi); 29082beadfa067b1e286fa604f8d7960d769411c954satok if (subtypes == null || subtypes.size() == 0) { 29182beadfa067b1e286fa604f8d7960d769411c954satok mInputMethodMenuList.addView( 29282beadfa067b1e286fa604f8d7960d769411c954satok createInputMethodItem(imi, null)); 29382beadfa067b1e286fa604f8d7960d769411c954satok continue; 29482beadfa067b1e286fa604f8d7960d769411c954satok } 29582beadfa067b1e286fa604f8d7960d769411c954satok for (InputMethodSubtype subtype: subtypes) { 29682beadfa067b1e286fa604f8d7960d769411c954satok mInputMethodMenuList.addView(createInputMethodItem(imi, subtype)); 29782beadfa067b1e286fa604f8d7960d769411c954satok } 29882beadfa067b1e286fa604f8d7960d769411c954satok } 29982beadfa067b1e286fa604f8d7960d769411c954satok updateRadioButtons(); 30082beadfa067b1e286fa604f8d7960d769411c954satok } 30182beadfa067b1e286fa604f8d7960d769411c954satok 302913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok public void setImeToken(IBinder token) { 30382beadfa067b1e286fa604f8d7960d769411c954satok mToken = token; 30482beadfa067b1e286fa604f8d7960d769411c954satok } 30582beadfa067b1e286fa604f8d7960d769411c954satok 306913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok public void setImeSwitchButton(InputMethodButton imb) { 307913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok mInputMethodSwitchButton = imb; 308913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok } 309913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok 31082beadfa067b1e286fa604f8d7960d769411c954satok private void setInputMethodAndSubtype(InputMethodInfo imi, InputMethodSubtype subtype) { 31182beadfa067b1e286fa604f8d7960d769411c954satok if (mToken != null) { 31282beadfa067b1e286fa604f8d7960d769411c954satok mImm.setInputMethodAndSubtype(mToken, imi.getId(), subtype); 31382beadfa067b1e286fa604f8d7960d769411c954satok } else { 31482beadfa067b1e286fa604f8d7960d769411c954satok Log.w(TAG, "IME Token is not set yet."); 31582beadfa067b1e286fa604f8d7960d769411c954satok } 31682beadfa067b1e286fa604f8d7960d769411c954satok } 31782beadfa067b1e286fa604f8d7960d769411c954satok 3182992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void setHardKeyboardStatus(boolean available, boolean enabled) { 3192992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown if (mHardKeyboardAvailable != available || mHardKeyboardEnabled != enabled) { 3202992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardAvailable = available; 3212992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardEnabled = enabled; 3222992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown updateHardKeyboardSection(); 3232992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3242992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3252992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 3262992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown private void updateHardKeyboardSection() { 3272992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown if (mHardKeyboardAvailable) { 3282992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardSection.setVisibility(View.VISIBLE); 3291c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka if (mHardKeyboardSwitch.isChecked() != mHardKeyboardEnabled) { 3301c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka mHardKeyboardSwitch.setChecked(mHardKeyboardEnabled); 33101038492ff0317f0d3cff54d8a7ee36bb31ff175satok updateHardKeyboardEnabled(); 3321c9debfb18acae293dff5ce02bb200d2a6b04ba9Tadashi G. Takaoka } 3332992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } else { 3342992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown mHardKeyboardSection.setVisibility(View.GONE); 3352992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3362992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 3372992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 33882beadfa067b1e286fa604f8d7960d769411c954satok // Turn on the selected radio button when the user chooses the item 33982beadfa067b1e286fa604f8d7960d769411c954satok private Pair<InputMethodInfo, InputMethodSubtype> updateRadioButtonsByView(View selectedView) { 34082beadfa067b1e286fa604f8d7960d769411c954satok Pair<InputMethodInfo, InputMethodSubtype> selectedImiAndSubtype = null; 34182beadfa067b1e286fa604f8d7960d769411c954satok if (mRadioViewAndImiMap.containsKey(selectedView)) { 34282beadfa067b1e286fa604f8d7960d769411c954satok for (View radioView: mRadioViewAndImiMap.keySet()) { 34382beadfa067b1e286fa604f8d7960d769411c954satok RadioButton subtypeRadioButton = 34482beadfa067b1e286fa604f8d7960d769411c954satok (RadioButton) radioView.findViewById(R.id.item_radio); 34582beadfa067b1e286fa604f8d7960d769411c954satok if (subtypeRadioButton == null) { 34682beadfa067b1e286fa604f8d7960d769411c954satok Log.w(TAG, "RadioButton was not found in the selected subtype view"); 34782beadfa067b1e286fa604f8d7960d769411c954satok return null; 34882beadfa067b1e286fa604f8d7960d769411c954satok } 34982beadfa067b1e286fa604f8d7960d769411c954satok if (radioView == selectedView) { 35082beadfa067b1e286fa604f8d7960d769411c954satok Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype = 35182beadfa067b1e286fa604f8d7960d769411c954satok mRadioViewAndImiMap.get(radioView); 35282beadfa067b1e286fa604f8d7960d769411c954satok selectedImiAndSubtype = imiAndSubtype; 35382beadfa067b1e286fa604f8d7960d769411c954satok subtypeRadioButton.setChecked(true); 35482beadfa067b1e286fa604f8d7960d769411c954satok } else { 35582beadfa067b1e286fa604f8d7960d769411c954satok subtypeRadioButton.setChecked(false); 35682beadfa067b1e286fa604f8d7960d769411c954satok } 35782beadfa067b1e286fa604f8d7960d769411c954satok } 35882beadfa067b1e286fa604f8d7960d769411c954satok } 35982beadfa067b1e286fa604f8d7960d769411c954satok return selectedImiAndSubtype; 36082beadfa067b1e286fa604f8d7960d769411c954satok } 36182beadfa067b1e286fa604f8d7960d769411c954satok 36282beadfa067b1e286fa604f8d7960d769411c954satok private void updateRadioButtons() { 36382beadfa067b1e286fa604f8d7960d769411c954satok updateRadioButtonsByImiAndSubtype( 36482beadfa067b1e286fa604f8d7960d769411c954satok getCurrentInputMethodInfo(), mImm.getCurrentInputMethodSubtype()); 36582beadfa067b1e286fa604f8d7960d769411c954satok } 36682beadfa067b1e286fa604f8d7960d769411c954satok 36782beadfa067b1e286fa604f8d7960d769411c954satok // Turn on the selected radio button at startup 36882beadfa067b1e286fa604f8d7960d769411c954satok private void updateRadioButtonsByImiAndSubtype( 36982beadfa067b1e286fa604f8d7960d769411c954satok InputMethodInfo imi, InputMethodSubtype subtype) { 370f6cafb63753a26440cb3ad2e5124370aef650015satok if (imi == null) return; 37182beadfa067b1e286fa604f8d7960d769411c954satok if (DEBUG) { 37282beadfa067b1e286fa604f8d7960d769411c954satok Log.d(TAG, "Update radio buttons by " + imi.getId() + ", " + subtype); 37382beadfa067b1e286fa604f8d7960d769411c954satok } 37482beadfa067b1e286fa604f8d7960d769411c954satok for (View radioView: mRadioViewAndImiMap.keySet()) { 37582beadfa067b1e286fa604f8d7960d769411c954satok RadioButton subtypeRadioButton = 37682beadfa067b1e286fa604f8d7960d769411c954satok (RadioButton) radioView.findViewById(R.id.item_radio); 37782beadfa067b1e286fa604f8d7960d769411c954satok if (subtypeRadioButton == null) { 37882beadfa067b1e286fa604f8d7960d769411c954satok Log.w(TAG, "RadioButton was not found in the selected subtype view"); 37982beadfa067b1e286fa604f8d7960d769411c954satok return; 38082beadfa067b1e286fa604f8d7960d769411c954satok } 38182beadfa067b1e286fa604f8d7960d769411c954satok Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype = 382f6cafb63753a26440cb3ad2e5124370aef650015satok mRadioViewAndImiMap.get(radioView); 38382beadfa067b1e286fa604f8d7960d769411c954satok if (imiAndSubtype.first.getId().equals(imi.getId()) 38482beadfa067b1e286fa604f8d7960d769411c954satok && (imiAndSubtype.second == null || imiAndSubtype.second.equals(subtype))) { 38582beadfa067b1e286fa604f8d7960d769411c954satok subtypeRadioButton.setChecked(true); 38682beadfa067b1e286fa604f8d7960d769411c954satok } else { 38782beadfa067b1e286fa604f8d7960d769411c954satok subtypeRadioButton.setChecked(false); 38882beadfa067b1e286fa604f8d7960d769411c954satok } 38982beadfa067b1e286fa604f8d7960d769411c954satok } 39082beadfa067b1e286fa604f8d7960d769411c954satok } 39182beadfa067b1e286fa604f8d7960d769411c954satok 3927dc93a1df7731672b321b78316afff2104dcf239satok private TreeMap<InputMethodInfo, List<InputMethodSubtype>> 39382beadfa067b1e286fa604f8d7960d769411c954satok getEnabledInputMethodAndSubtypeList() { 39482beadfa067b1e286fa604f8d7960d769411c954satok String newEnabledIMIs = Settings.Secure.getString( 39582beadfa067b1e286fa604f8d7960d769411c954satok mContext.getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS); 396cf5f6d107a50f8b859158adc00254df72a1aec7esatok String currentSystemLocaleString = 397cf5f6d107a50f8b859158adc00254df72a1aec7esatok mContext.getResources().getConfiguration().locale.toString(); 398cf5f6d107a50f8b859158adc00254df72a1aec7esatok if (!TextUtils.equals(mEnabledInputMethodAndSubtypesCacheStr, newEnabledIMIs) 399cf5f6d107a50f8b859158adc00254df72a1aec7esatok || !TextUtils.equals(mLastSystemLocaleString, currentSystemLocaleString) 4000ee6613d09eff218211c2624774b12981699bfd2satok || mPackageChanged) { 40182beadfa067b1e286fa604f8d7960d769411c954satok mEnabledInputMethodAndSubtypesCache.clear(); 40282beadfa067b1e286fa604f8d7960d769411c954satok final List<InputMethodInfo> imis = mImm.getEnabledInputMethodList(); 40382beadfa067b1e286fa604f8d7960d769411c954satok for (InputMethodInfo imi: imis) { 40482beadfa067b1e286fa604f8d7960d769411c954satok mEnabledInputMethodAndSubtypesCache.put(imi, 40582beadfa067b1e286fa604f8d7960d769411c954satok mImm.getEnabledInputMethodSubtypeList(imi, true)); 40682beadfa067b1e286fa604f8d7960d769411c954satok } 40782beadfa067b1e286fa604f8d7960d769411c954satok mEnabledInputMethodAndSubtypesCacheStr = newEnabledIMIs; 4080ee6613d09eff218211c2624774b12981699bfd2satok mPackageChanged = false; 409cf5f6d107a50f8b859158adc00254df72a1aec7esatok mLastSystemLocaleString = currentSystemLocaleString; 41082beadfa067b1e286fa604f8d7960d769411c954satok } 41182beadfa067b1e286fa604f8d7960d769411c954satok return mEnabledInputMethodAndSubtypesCache; 41282beadfa067b1e286fa604f8d7960d769411c954satok } 41382beadfa067b1e286fa604f8d7960d769411c954satok 41482beadfa067b1e286fa604f8d7960d769411c954satok private InputMethodInfo getCurrentInputMethodInfo() { 41582beadfa067b1e286fa604f8d7960d769411c954satok String curInputMethodId = Settings.Secure.getString(getContext() 41682beadfa067b1e286fa604f8d7960d769411c954satok .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 41782beadfa067b1e286fa604f8d7960d769411c954satok Set<InputMethodInfo> cachedImiSet = mEnabledInputMethodAndSubtypesCache.keySet(); 41882beadfa067b1e286fa604f8d7960d769411c954satok // 1. Search IMI in cache 41982beadfa067b1e286fa604f8d7960d769411c954satok for (InputMethodInfo imi: cachedImiSet) { 42082beadfa067b1e286fa604f8d7960d769411c954satok if (imi.getId().equals(curInputMethodId)) { 42182beadfa067b1e286fa604f8d7960d769411c954satok return imi; 42282beadfa067b1e286fa604f8d7960d769411c954satok } 42382beadfa067b1e286fa604f8d7960d769411c954satok } 42482beadfa067b1e286fa604f8d7960d769411c954satok // 2. Get current enabled IMEs and search IMI 42582beadfa067b1e286fa604f8d7960d769411c954satok cachedImiSet = getEnabledInputMethodAndSubtypeList().keySet(); 42682beadfa067b1e286fa604f8d7960d769411c954satok for (InputMethodInfo imi: cachedImiSet) { 42782beadfa067b1e286fa604f8d7960d769411c954satok if (imi.getId().equals(curInputMethodId)) { 42882beadfa067b1e286fa604f8d7960d769411c954satok return imi; 42982beadfa067b1e286fa604f8d7960d769411c954satok } 43082beadfa067b1e286fa604f8d7960d769411c954satok } 43182beadfa067b1e286fa604f8d7960d769411c954satok return null; 43282beadfa067b1e286fa604f8d7960d769411c954satok } 43382beadfa067b1e286fa604f8d7960d769411c954satok 43482beadfa067b1e286fa604f8d7960d769411c954satok private CharSequence getIMIName(InputMethodInfo imi) { 43582beadfa067b1e286fa604f8d7960d769411c954satok if (imi == null) return null; 436209cf04353ceb67d9ba95ffbdfd36af0515bb2basatok return imi.loadLabel(mPackageManager); 43782beadfa067b1e286fa604f8d7960d769411c954satok } 43882beadfa067b1e286fa604f8d7960d769411c954satok 43982beadfa067b1e286fa604f8d7960d769411c954satok private CharSequence getSubtypeName(InputMethodInfo imi, InputMethodSubtype subtype) { 44082beadfa067b1e286fa604f8d7960d769411c954satok if (imi == null || subtype == null) return null; 441913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok if (DEBUG) { 442913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok Log.d(TAG, "Get text from: " + imi.getPackageName() + subtype.getNameResId() 443913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok + imi.getServiceInfo().applicationInfo); 444913f42d26a32621ad7dd52c52b8d150eedf4f8fesatok } 4454f31353cb3b00c77c9420ef27ec949fd570ede3bsatok return subtype.getDisplayName( 4464f31353cb3b00c77c9420ef27ec949fd570ede3bsatok mContext, imi.getPackageName(), imi.getServiceInfo().applicationInfo); 44782beadfa067b1e286fa604f8d7960d769411c954satok } 44882beadfa067b1e286fa604f8d7960d769411c954satok 44982beadfa067b1e286fa604f8d7960d769411c954satok private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) { 45082beadfa067b1e286fa604f8d7960d769411c954satok if (imi != null) { 45182beadfa067b1e286fa604f8d7960d769411c954satok if (DEBUG) { 45282beadfa067b1e286fa604f8d7960d769411c954satok Log.d(TAG, "Update icons of IME: " + imi.getPackageName()); 45382beadfa067b1e286fa604f8d7960d769411c954satok if (subtype != null) { 45482beadfa067b1e286fa604f8d7960d769411c954satok Log.d(TAG, "subtype =" + subtype.getLocale() + "," + subtype.getMode()); 45582beadfa067b1e286fa604f8d7960d769411c954satok } 45682beadfa067b1e286fa604f8d7960d769411c954satok } 45782beadfa067b1e286fa604f8d7960d769411c954satok if (subtype != null) { 45882beadfa067b1e286fa604f8d7960d769411c954satok return mPackageManager.getDrawable(imi.getPackageName(), subtype.getIconResId(), 45982beadfa067b1e286fa604f8d7960d769411c954satok imi.getServiceInfo().applicationInfo); 460586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa } else if (imi.getSubtypeCount() > 0) { 46182beadfa067b1e286fa604f8d7960d769411c954satok return mPackageManager.getDrawable(imi.getPackageName(), 462586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa imi.getSubtypeAt(0).getIconResId(), 46382beadfa067b1e286fa604f8d7960d769411c954satok imi.getServiceInfo().applicationInfo); 46482beadfa067b1e286fa604f8d7960d769411c954satok } else { 46582beadfa067b1e286fa604f8d7960d769411c954satok try { 46682beadfa067b1e286fa604f8d7960d769411c954satok return mPackageManager.getApplicationInfo( 46782beadfa067b1e286fa604f8d7960d769411c954satok imi.getPackageName(), 0).loadIcon(mPackageManager); 46882beadfa067b1e286fa604f8d7960d769411c954satok } catch (PackageManager.NameNotFoundException e) { 46982beadfa067b1e286fa604f8d7960d769411c954satok Log.w(TAG, "IME can't be found: " + imi.getPackageName()); 47082beadfa067b1e286fa604f8d7960d769411c954satok } 47182beadfa067b1e286fa604f8d7960d769411c954satok } 47282beadfa067b1e286fa604f8d7960d769411c954satok } 47382beadfa067b1e286fa604f8d7960d769411c954satok return null; 47482beadfa067b1e286fa604f8d7960d769411c954satok } 4750ee6613d09eff218211c2624774b12981699bfd2satok 4760ee6613d09eff218211c2624774b12981699bfd2satok private void onPackageChanged() { 4770ee6613d09eff218211c2624774b12981699bfd2satok if (DEBUG) { 4780ee6613d09eff218211c2624774b12981699bfd2satok Log.d(TAG, "onPackageChanged."); 4790ee6613d09eff218211c2624774b12981699bfd2satok } 4800ee6613d09eff218211c2624774b12981699bfd2satok mPackageChanged = true; 4810ee6613d09eff218211c2624774b12981699bfd2satok } 4822992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown 4832992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public interface OnHardKeyboardEnabledChangeListener { 4842992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown public void onHardKeyboardEnabledChange(boolean enabled); 4852992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown } 4866179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov 48782beadfa067b1e286fa604f8d7960d769411c954satok} 488