1176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler/*
2176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * Copyright (C) 2015 The Android Open Source Project
3176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler *
4176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
5176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * you may not use this file except in compliance with the License.
6176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * You may obtain a copy of the License at
7176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler *
8176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
9176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler *
10176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * Unless required by applicable law or agreed to in writing, software
11176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
12176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * See the License for the specific language governing permissions and
14176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler * limitations under the License
15176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler */
16176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
17176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerpackage com.android.tv.settings.system;
18176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
19176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.app.ActivityManagerNative;
20176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.content.Context;
21176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.content.Intent;
22176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.content.pm.PackageManager;
23176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.os.Bundle;
24176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.os.RemoteException;
25176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.os.UserHandle;
26176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.provider.Settings;
27176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.support.v17.preference.LeanbackPreferenceFragment;
28176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.support.v7.preference.ListPreference;
29176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.support.v7.preference.Preference;
30176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.support.v7.preference.PreferenceScreen;
31176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.text.TextUtils;
32176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.util.Log;
33176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.view.inputmethod.InputMethodInfo;
34176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport android.view.inputmethod.InputMethodManager;
35176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
36176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport com.android.tv.settings.R;
37176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
38176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport java.util.ArrayList;
39176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport java.util.Iterator;
40176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerimport java.util.List;
41176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
42176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantlerpublic class KeyboardFragment extends LeanbackPreferenceFragment {
43176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private static final String TAG = "KeyboardFragment";
44176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private static final String INPUT_METHOD_SEPARATOR = ":";
45176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private static final String KEY_CURRENT_KEYBOARD = "currentKeyboard";
46176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
47176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private InputMethodManager mInputMethodManager;
48176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
49176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    public static KeyboardFragment newInstance() {
50176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        return new KeyboardFragment();
51176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
52176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
53176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    @Override
54176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    public void onCreate(Bundle savedInstanceState) {
55176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        mInputMethodManager =
56176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
57176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
58176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        enableAllInputMethods();
59176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
60176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        super.onCreate(savedInstanceState);
61176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
62176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
63176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    @Override
64176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
65176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final Context preferenceContext = getPreferenceManager().getContext();
66176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final PackageManager packageManager = getActivity().getPackageManager();
67176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
68176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final PreferenceScreen screen =
69176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                getPreferenceManager().createPreferenceScreen(preferenceContext);
70176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        screen.setTitle(R.string.system_keyboard);
71176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
72176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        List<InputMethodInfo> enabledInputMethodInfos = getEnabledSystemInputMethodList();
73176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
74176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final List<CharSequence> entries = new ArrayList<>(enabledInputMethodInfos.size());
75176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final List<CharSequence> values = new ArrayList<>(enabledInputMethodInfos.size());
76176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
77176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        int defaultIndex = 0;
78176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final String defaultId = Settings.Secure.getString(getActivity().getContentResolver(),
79176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                Settings.Secure.DEFAULT_INPUT_METHOD);
80176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
81176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        for (final InputMethodInfo info : enabledInputMethodInfos) {
82176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            entries.add(info.loadLabel(packageManager));
83176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            final String id = info.getId();
84176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            values.add(id);
85176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            if (TextUtils.equals(id, defaultId)) {
86176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                defaultIndex = values.size() - 1;
87176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
88176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
89176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
90176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final ListPreference currentKeyboard = new ListPreference(preferenceContext);
91176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setPersistent(false);
92176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setTitle(R.string.title_current_keyboard);
93352ce7af0ee660ed55893bc7699d695fbdc776d3Tony Mantler        currentKeyboard.setDialogTitle(R.string.title_current_keyboard);
94176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setSummary("%s");
95176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setKey(KEY_CURRENT_KEYBOARD);
96176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setEntries(entries.toArray(new CharSequence[entries.size()]));
97176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setEntryValues(values.toArray(new CharSequence[values.size()]));
98176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setValueIndex(defaultIndex);
99176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        currentKeyboard.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
100176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            @Override
101176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            public boolean onPreferenceChange(Preference preference, Object newValue) {
102176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                setInputMethod((String) newValue);
103176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                return true;
104176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
105176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        });
106176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        screen.addPreference(currentKeyboard);
107176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
108176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        // Add per-IME settings
109176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        for (final InputMethodInfo info : enabledInputMethodInfos) {
110176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            final Intent settingsIntent = getInputMethodSettingsIntent(info);
111176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            if (settingsIntent == null) {
112176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                continue;
113176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
114176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            final Preference preference = new Preference(preferenceContext);
115176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            preference.setTitle(info.loadLabel(packageManager));
116176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            preference.setKey("keyboardSettings:" + info.getId());
117176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            preference.setIntent(settingsIntent);
118176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            screen.addPreference(preference);
119176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
120176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        setPreferenceScreen(screen);
121176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
122176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
123176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
124176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
125176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private void setInputMethod(String imid) {
126176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        if (imid == null) {
127176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            throw new IllegalArgumentException("Null ID");
128176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
129176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
130176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        int userId;
131176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        try {
132176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            userId = ActivityManagerNative.getDefault().getCurrentUser().id;
133176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            Settings.Secure.putStringForUser(getActivity().getContentResolver(),
134176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                    Settings.Secure.DEFAULT_INPUT_METHOD, imid, userId);
135176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
136176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            if (ActivityManagerNative.isSystemReady()) {
137176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
138176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
139176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                intent.putExtra("input_method_id", imid);
140176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                getActivity().sendBroadcastAsUser(intent, UserHandle.CURRENT);
141176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
142176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        } catch (RemoteException e) {
143176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            Log.d(TAG, "set default input method remote exception");
144176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
145176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
146176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
147176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private List<InputMethodInfo> getEnabledSystemInputMethodList() {
148176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        List<InputMethodInfo> enabledInputMethodInfos =
149176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                new ArrayList<>(mInputMethodManager.getEnabledInputMethodList());
150176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        // Filter auxiliary keyboards out
151176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        for (Iterator<InputMethodInfo> it = enabledInputMethodInfos.iterator(); it.hasNext();) {
152176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            if (it.next().isAuxiliaryIme()) {
153176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                it.remove();
154176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
155176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
156176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        return enabledInputMethodInfos;
157176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
158176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
159176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private Intent getInputMethodSettingsIntent(InputMethodInfo imi) {
160176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final Intent intent;
161176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        final String settingsActivity = imi.getSettingsActivity();
162176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        if (!TextUtils.isEmpty(settingsActivity)) {
163176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            intent = new Intent(Intent.ACTION_MAIN);
164176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            intent.setClassName(imi.getPackageName(), settingsActivity);
165176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        } else {
166176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            intent = null;
167176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
168176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        return intent;
169176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
170176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
171176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    private void enableAllInputMethods() {
172176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        List<InputMethodInfo> allInputMethodInfos =
173176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                new ArrayList<>(mInputMethodManager.getInputMethodList());
174176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        boolean needAppendSeparator = false;
175176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        StringBuilder builder = new StringBuilder();
176176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        for (InputMethodInfo imi : allInputMethodInfos) {
177176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            if (needAppendSeparator) {
178176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                builder.append(INPUT_METHOD_SEPARATOR);
179176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            } else {
180176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                needAppendSeparator = true;
181176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            }
182176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler            builder.append(imi.getId());
183176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        }
184176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler        Settings.Secure.putString(getActivity().getContentResolver(),
185176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler                Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
186176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler    }
187176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler
188176350e7e15ba9a55acc557dac311d7be9731e94Tony Mantler}
189