Home | History | Annotate | Download | only in system
      1 /*
      2  * Copyright (C) 2014 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.tv.settings.system;
     18 
     19 import com.android.tv.settings.ActionBehavior;
     20 import com.android.tv.settings.ActionKey;
     21 import com.android.tv.settings.BaseSettingsActivity;
     22 import com.android.tv.settings.R;
     23 import com.android.tv.settings.dialog.old.Action;
     24 import com.android.tv.settings.dialog.old.ActionAdapter;
     25 
     26 import android.app.ActivityManagerNative;
     27 import android.content.Intent;
     28 import android.content.pm.PackageManager;
     29 import android.os.Bundle;
     30 import android.os.RemoteException;
     31 import android.os.UserHandle;
     32 import android.provider.Settings;
     33 import android.text.TextUtils;
     34 import android.util.Log;
     35 import android.view.inputmethod.InputMethodInfo;
     36 import android.view.inputmethod.InputMethodManager;
     37 
     38 import java.util.ArrayList;
     39 import java.util.List;
     40 
     41 public class KeyboardActivity extends BaseSettingsActivity implements ActionAdapter.Listener {
     42 
     43     private static final String TAG = "KeyboardActivity";
     44     private static final boolean DEBUG = false;
     45 
     46     private static final String INPUT_METHOD_SEPARATOR = ":";
     47     private InputMethodManager mInputMan;
     48 
     49     @Override
     50     public void onCreate(Bundle savedInstanceState) {
     51         mInputMan = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
     52         // enable all available input methods
     53         enableAllInputMethods();
     54 
     55         super.onCreate(savedInstanceState);
     56     }
     57 
     58     @Override
     59     public void onActionClicked(Action action) {
     60         /*
     61          * For list preferences
     62          */
     63         String key = action.getKey();
     64         switch ((ActionType) mState) {
     65             case KEYBOARD_OVERVIEW_CURRENT_KEYBOARD:
     66                 setInputMethod(key);
     67                 goBack();
     68                 return;
     69             default:
     70                 break;
     71         }
     72 
     73         /*
     74          * For regular states
     75          */
     76         ActionKey<ActionType, ActionBehavior> actionKey = new ActionKey<ActionType, ActionBehavior>(
     77                 ActionType.class, ActionBehavior.class, action.getKey());
     78         final ActionType type = actionKey.getType();
     79         switch (type) {
     80             case KEYBOARD_OVERVIEW_CONFIGURE:
     81                 InputMethodInfo currentInputMethodInfo = getCurrentInputMethodInfo();
     82                 if (currentInputMethodInfo != null &&
     83                         currentInputMethodInfo.getSettingsActivity() != null) {
     84                     startActivity(getInputMethodSettingsIntent(currentInputMethodInfo));
     85                 }
     86                 return;
     87             default:
     88         }
     89 
     90         final ActionBehavior behavior = actionKey.getBehavior();
     91         if (behavior == null) {
     92             return;
     93         }
     94         switch (behavior) {
     95             case INIT:
     96                 setState(type, true);
     97                 break;
     98             case ON:
     99                 setProperty(true);
    100                 break;
    101             case OFF:
    102                 setProperty(false);
    103                 break;
    104             default:
    105         }
    106     }
    107 
    108     @Override
    109     protected Object getInitialState() {
    110         return ActionType.KEYBOARD_OVERVIEW;
    111     }
    112 
    113     @Override
    114     protected void refreshActionList() {
    115         mActions.clear();
    116         InputMethodInfo currentInputMethodInfo = getCurrentInputMethodInfo();
    117         switch ((ActionType) mState) {
    118             case KEYBOARD_OVERVIEW:
    119                 String name = getDefaultInputMethodName();
    120                 mActions.add(ActionType.KEYBOARD_OVERVIEW_CURRENT_KEYBOARD
    121                         .toAction(mResources, TextUtils.isEmpty(name) ? "" : name));
    122 
    123                 if (currentInputMethodInfo != null
    124                         && currentInputMethodInfo.getSettingsActivity() != null) {
    125                     mActions.add(ActionType.KEYBOARD_OVERVIEW_CONFIGURE.toAction(mResources));
    126                 }
    127                 break;
    128             case KEYBOARD_OVERVIEW_CURRENT_KEYBOARD:
    129                 mActions = Action.createActionsFromArrays(getInputMethodIds(),
    130                         getInputMethodNames());
    131                 for (Action action : mActions) {
    132                     action.setChecked(currentInputMethodInfo != null &&
    133                             action.getKey().equals(currentInputMethodInfo.getId()));
    134                 }
    135                 break;
    136             default:
    137                 break;
    138         }
    139     }
    140 
    141     @Override
    142     protected void updateView() {
    143         refreshActionList();
    144         switch ((ActionType) mState) {
    145             case KEYBOARD_OVERVIEW:
    146                 setView(R.string.system_keyboard, R.string.settings_app_name, 0,
    147                         R.drawable.ic_settings_keyboard);
    148                 break;
    149             case KEYBOARD_OVERVIEW_CURRENT_KEYBOARD:
    150                 setView(R.string.title_current_keyboard, R.string.system_keyboard, 0,
    151                         R.drawable.ic_settings_keyboard);
    152                 break;
    153             default:
    154                 break;
    155         }
    156     }
    157 
    158     @Override
    159     protected void setProperty(boolean enable) {
    160     }
    161 
    162     private String getDefaultInputMethodId() {
    163         return Settings.Secure.getString(getContentResolver(),
    164                 Settings.Secure.DEFAULT_INPUT_METHOD);
    165     }
    166 
    167     private String getDefaultInputMethodName() {
    168         String defaultInputMethodInfo = getDefaultInputMethodId();
    169 
    170         List<InputMethodInfo> enabledInputMethodInfos = new ArrayList<InputMethodInfo>(
    171                 mInputMan.getEnabledInputMethodList());
    172         for (InputMethodInfo info : enabledInputMethodInfos) {
    173             if (defaultInputMethodInfo.equals(info.getId())) {
    174                 return info.loadLabel(getPackageManager()).toString();
    175             }
    176         }
    177         return null;
    178     }
    179 
    180     private InputMethodInfo getCurrentInputMethodInfo() {
    181         String defaultInputMethodInfo = getDefaultInputMethodId();
    182 
    183         List<InputMethodInfo> enabledInputMethodInfos = new ArrayList<InputMethodInfo>(
    184                 mInputMan.getEnabledInputMethodList());
    185         for (InputMethodInfo info : enabledInputMethodInfos) {
    186             if (defaultInputMethodInfo.equals(info.getId())) {
    187                 return info;
    188             }
    189         }
    190         return null;
    191     }
    192 
    193     private String[] getInputMethodNames() {
    194         List<InputMethodInfo> enabledInputMethodInfos = new ArrayList<InputMethodInfo>(
    195                 mInputMan.getEnabledInputMethodList());
    196         int totalInputMethods = enabledInputMethodInfos.size();
    197         String[] inputMethodNames = new String[totalInputMethods];
    198         for (int i = 0; i < totalInputMethods; i++) {
    199             inputMethodNames[i] = enabledInputMethodInfos.get(i)
    200                     .loadLabel(getPackageManager()).toString();
    201         }
    202         return inputMethodNames;
    203     }
    204 
    205     private String[] getInputMethodIds() {
    206         List<InputMethodInfo> enabledInputMethodInfos = new ArrayList<InputMethodInfo>(
    207                 mInputMan.getEnabledInputMethodList());
    208         int totalInputMethods = enabledInputMethodInfos.size();
    209         String[] inputMethodIds = new String[totalInputMethods];
    210         for (int i = 0; i < totalInputMethods; i++) {
    211             inputMethodIds[i] = enabledInputMethodInfos.get(i).getId();
    212         }
    213         return inputMethodIds;
    214     }
    215 
    216     private void setInputMethod(String imid) {
    217         if (imid == null) {
    218             throw new IllegalArgumentException("Unknown id: " + imid);
    219         }
    220 
    221         int userId;
    222         try {
    223             userId = ActivityManagerNative.getDefault().getCurrentUser().id;
    224             Settings.Secure.putStringForUser(getContentResolver(),
    225                     Settings.Secure.DEFAULT_INPUT_METHOD, imid, userId);
    226 
    227             if (ActivityManagerNative.isSystemReady()) {
    228                 Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
    229                 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
    230                 intent.putExtra("input_method_id", imid);
    231                 sendBroadcastAsUser(intent, UserHandle.CURRENT);
    232             }
    233         } catch (RemoteException e) {
    234             Log.d(TAG, "set default input method remote exception");
    235         }
    236     }
    237 
    238     private void enableAllInputMethods() {
    239         List<InputMethodInfo> allInputMethodInfos =
    240                 new ArrayList<InputMethodInfo>(mInputMan.getInputMethodList());
    241         boolean needAppendSeparator = false;
    242         StringBuilder builder = new StringBuilder();
    243         for (InputMethodInfo imi : allInputMethodInfos) {
    244             if (needAppendSeparator) {
    245                 builder.append(INPUT_METHOD_SEPARATOR);
    246             } else {
    247                 needAppendSeparator = true;
    248             }
    249             builder.append(imi.getId());
    250         }
    251         Settings.Secure.putString(getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS,
    252                 builder.toString());
    253     }
    254 
    255     private Intent getInputMethodSettingsIntent(InputMethodInfo imi) {
    256         final PackageManager pm = getPackageManager();
    257         final CharSequence label = imi.loadLabel(pm);// IME settings
    258         final Intent intent;
    259         final String settingsActivity = imi.getSettingsActivity();
    260         if (!TextUtils.isEmpty(settingsActivity)) {
    261             intent = new Intent(Intent.ACTION_MAIN);
    262             intent.setClassName(imi.getPackageName(), settingsActivity);
    263         } else {
    264             intent = null;
    265         }
    266         return intent;
    267     }
    268 }
    269