1/*
2 * Copyright (C) 2011 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
17package com.android.inputmethodcommon;
18
19import android.content.Context;
20import android.content.Intent;
21import android.graphics.drawable.Drawable;
22import android.preference.Preference;
23import android.preference.Preference.OnPreferenceClickListener;
24import android.preference.PreferenceScreen;
25import android.provider.Settings;
26import android.text.TextUtils;
27import android.view.inputmethod.InputMethodInfo;
28import android.view.inputmethod.InputMethodManager;
29import android.view.inputmethod.InputMethodSubtype;
30
31import java.util.List;
32
33/* package private */ class InputMethodSettingsImpl implements InputMethodSettingsInterface {
34    private Preference mSubtypeEnablerPreference;
35    private int mInputMethodSettingsCategoryTitleRes;
36    private CharSequence mInputMethodSettingsCategoryTitle;
37    private int mSubtypeEnablerTitleRes;
38    private CharSequence mSubtypeEnablerTitle;
39    private int mSubtypeEnablerIconRes;
40    private Drawable mSubtypeEnablerIcon;
41    private InputMethodManager mImm;
42    private InputMethodInfo mImi;
43    private Context mContext;
44
45    /**
46     * Initialize internal states of this object.
47     * @param context the context for this application.
48     * @param prefScreen a PreferenceScreen of PreferenceActivity or PreferenceFragment.
49     * @return true if this application is an IME and has two or more subtypes, false otherwise.
50     */
51    public boolean init(final Context context, final PreferenceScreen prefScreen) {
52        mContext = context;
53        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
54        mImi = getMyImi(context, mImm);
55        if (mImi == null || mImi.getSubtypeCount() <= 1) {
56            return false;
57        }
58        mSubtypeEnablerPreference = new Preference(context);
59        mSubtypeEnablerPreference
60                .setOnPreferenceClickListener(new OnPreferenceClickListener() {
61                    @Override
62                    public boolean onPreferenceClick(Preference preference) {
63                        final CharSequence title = getSubtypeEnablerTitle(context);
64                        final Intent intent =
65                                new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
66                        intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, mImi.getId());
67                        if (!TextUtils.isEmpty(title)) {
68                            intent.putExtra(Intent.EXTRA_TITLE, title);
69                        }
70                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
71                                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
72                                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
73                        context.startActivity(intent);
74                        return true;
75                    }
76                });
77        prefScreen.addPreference(mSubtypeEnablerPreference);
78        updateSubtypeEnabler();
79        return true;
80    }
81
82    private static InputMethodInfo getMyImi(Context context, InputMethodManager imm) {
83        final List<InputMethodInfo> imis = imm.getInputMethodList();
84        for (int i = 0; i < imis.size(); ++i) {
85            final InputMethodInfo imi = imis.get(i);
86            if (imis.get(i).getPackageName().equals(context.getPackageName())) {
87                return imi;
88            }
89        }
90        return null;
91    }
92
93    private static String getEnabledSubtypesLabel(
94            Context context, InputMethodManager imm, InputMethodInfo imi) {
95        if (context == null || imm == null || imi == null) return null;
96        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true);
97        final StringBuilder sb = new StringBuilder();
98        final int N = subtypes.size();
99        for (int i = 0; i < N; ++i) {
100            final InputMethodSubtype subtype = subtypes.get(i);
101            if (sb.length() > 0) {
102                sb.append(", ");
103            }
104            sb.append(subtype.getDisplayName(context, imi.getPackageName(),
105                    imi.getServiceInfo().applicationInfo));
106        }
107        return sb.toString();
108    }
109    /**
110     * {@inheritDoc}
111     */
112    @Override
113    public void setInputMethodSettingsCategoryTitle(int resId) {
114        mInputMethodSettingsCategoryTitleRes = resId;
115        updateSubtypeEnabler();
116    }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public void setInputMethodSettingsCategoryTitle(CharSequence title) {
123        mInputMethodSettingsCategoryTitleRes = 0;
124        mInputMethodSettingsCategoryTitle = title;
125        updateSubtypeEnabler();
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    @Override
132    public void setSubtypeEnablerTitle(int resId) {
133        mSubtypeEnablerTitleRes = resId;
134        updateSubtypeEnabler();
135    }
136
137    /**
138     * {@inheritDoc}
139     */
140    @Override
141    public void setSubtypeEnablerTitle(CharSequence title) {
142        mSubtypeEnablerTitleRes = 0;
143        mSubtypeEnablerTitle = title;
144        updateSubtypeEnabler();
145    }
146
147    /**
148     * {@inheritDoc}
149     */
150    @Override
151    public void setSubtypeEnablerIcon(int resId) {
152        mSubtypeEnablerIconRes = resId;
153        updateSubtypeEnabler();
154    }
155
156    /**
157     * {@inheritDoc}
158     */
159    @Override
160    public void setSubtypeEnablerIcon(Drawable drawable) {
161        mSubtypeEnablerIconRes = 0;
162        mSubtypeEnablerIcon = drawable;
163        updateSubtypeEnabler();
164    }
165
166    private CharSequence getSubtypeEnablerTitle(Context context) {
167        if (mSubtypeEnablerTitleRes != 0) {
168            return context.getString(mSubtypeEnablerTitleRes);
169        } else {
170            return mSubtypeEnablerTitle;
171        }
172    }
173
174    public void updateSubtypeEnabler() {
175        if (mSubtypeEnablerPreference != null) {
176            if (mSubtypeEnablerTitleRes != 0) {
177                mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitleRes);
178            } else if (!TextUtils.isEmpty(mSubtypeEnablerTitle)) {
179                mSubtypeEnablerPreference.setTitle(mSubtypeEnablerTitle);
180            }
181            final String summary = getEnabledSubtypesLabel(mContext, mImm, mImi);
182            if (!TextUtils.isEmpty(summary)) {
183                mSubtypeEnablerPreference.setSummary(summary);
184            }
185            if (mSubtypeEnablerIconRes != 0) {
186                mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIconRes);
187            } else if (mSubtypeEnablerIcon != null) {
188                mSubtypeEnablerPreference.setIcon(mSubtypeEnablerIcon);
189            }
190        }
191    }
192}
193