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