1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.tablet; 18 19 import android.content.Context; 20 import android.os.IBinder; 21 import android.provider.Settings; 22 import android.util.AttributeSet; 23 import android.view.inputmethod.InputMethodInfo; 24 import android.view.inputmethod.InputMethodManager; 25 import android.view.inputmethod.InputMethodSubtype; 26 import android.view.View; 27 import android.widget.ImageView; 28 29 import com.android.systemui.R; 30 31 import java.util.List; 32 33 public class InputMethodButton extends ImageView { 34 35 private static final String TAG = "StatusBar/InputMethodButton"; 36 private static final boolean DEBUG = false; 37 38 // These values are defined in Settings application. 39 private static final int ID_IME_BUTTON_VISIBILITY_AUTO = 0; 40 private static final int ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW = 1; 41 private static final int ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE = 2; 42 43 // other services we wish to talk to 44 private final InputMethodManager mImm; 45 private final int mId; 46 private ImageView mIcon; 47 private IBinder mToken; 48 private boolean mShowButton = false; 49 private boolean mScreenLocked = false; 50 private boolean mHardKeyboardAvailable; 51 52 // Please refer to InputMethodManagerService.TAG_TRY_SUPPRESSING_IME_SWITCHER 53 private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher"; 54 55 public InputMethodButton(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 58 // Resource Id of the input method button. This id is defined in status_bar.xml 59 mId = getId(); 60 // IME hookup 61 mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 62 } 63 64 @Override 65 protected void onAttachedToWindow() { 66 mIcon = (ImageView) findViewById(mId); 67 68 refreshStatusIcon(); 69 } 70 71 // Refer to InputMethodManagerService.needsToShowImeSwitchOngoingNotification() 72 private boolean needsToShowIMEButtonWhenVisibilityAuto() { 73 List<InputMethodInfo> imis = mImm.getEnabledInputMethodList(); 74 final int N = imis.size(); 75 if (N > 2) return true; 76 if (N < 1) return false; 77 int nonAuxCount = 0; 78 int auxCount = 0; 79 InputMethodSubtype nonAuxSubtype = null; 80 InputMethodSubtype auxSubtype = null; 81 for(int i = 0; i < N; ++i) { 82 final InputMethodInfo imi = imis.get(i); 83 final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList( 84 imi, true); 85 final int subtypeCount = subtypes.size(); 86 if (subtypeCount == 0) { 87 ++nonAuxCount; 88 } else { 89 for (int j = 0; j < subtypeCount; ++j) { 90 final InputMethodSubtype subtype = subtypes.get(j); 91 if (!subtype.isAuxiliary()) { 92 ++nonAuxCount; 93 nonAuxSubtype = subtype; 94 } else { 95 ++auxCount; 96 auxSubtype = subtype; 97 } 98 } 99 } 100 } 101 if (nonAuxCount > 1 || auxCount > 1) { 102 return true; 103 } else if (nonAuxCount == 1 && auxCount == 1) { 104 if (nonAuxSubtype != null && auxSubtype != null 105 && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale()) 106 || auxSubtype.overridesImplicitlyEnabledSubtype() 107 || nonAuxSubtype.overridesImplicitlyEnabledSubtype()) 108 && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) { 109 return false; 110 } 111 return true; 112 } 113 return false; 114 } 115 116 private boolean needsToShowIMEButton() { 117 if (!mShowButton || mScreenLocked) return false; 118 119 if (mHardKeyboardAvailable) { 120 return true; 121 } 122 123 final int visibility = loadInputMethodSelectorVisibility(); 124 switch (visibility) { 125 case ID_IME_BUTTON_VISIBILITY_AUTO: 126 return needsToShowIMEButtonWhenVisibilityAuto(); 127 case ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW: 128 return true; 129 case ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE: 130 return false; 131 } 132 return false; 133 } 134 135 private void refreshStatusIcon() { 136 if (mIcon == null) { 137 return; 138 } 139 if (!needsToShowIMEButton()) { 140 setVisibility(View.GONE); 141 return; 142 } else { 143 setVisibility(View.VISIBLE); 144 } 145 mIcon.setImageResource(R.drawable.ic_sysbar_ime); 146 } 147 148 private int loadInputMethodSelectorVisibility() { 149 return Settings.Secure.getInt(getContext().getContentResolver(), 150 Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, ID_IME_BUTTON_VISIBILITY_AUTO); 151 } 152 153 public void setIconImage(int resId) { 154 if (mIcon != null) { 155 mIcon.setImageResource(resId); 156 } 157 } 158 159 public void setImeWindowStatus(IBinder token, boolean showButton) { 160 mToken = token; 161 mShowButton = showButton; 162 refreshStatusIcon(); 163 } 164 165 public void setHardKeyboardStatus(boolean available) { 166 if (mHardKeyboardAvailable != available) { 167 mHardKeyboardAvailable = available; 168 refreshStatusIcon(); 169 } 170 } 171 172 public void setScreenLocked(boolean locked) { 173 mScreenLocked = locked; 174 refreshStatusIcon(); 175 } 176 } 177