1/*
2 * Copyright (C) 2007 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.commands.ime;
18
19import com.android.internal.view.IInputMethodManager;
20
21import android.os.RemoteException;
22import android.os.ServiceManager;
23import android.util.PrintStreamPrinter;
24import android.util.Printer;
25import android.view.inputmethod.InputMethodInfo;
26
27import java.util.List;
28
29public final class Ime {
30    IInputMethodManager mImm;
31
32    private String[] mArgs;
33    private int mNextArg;
34    private String mCurArgData;
35
36    private static final String IMM_NOT_RUNNING_ERR =
37        "Error: Could not access the Input Method Manager.  Is the system running?";
38
39    public static void main(String[] args) {
40        new Ime().run(args);
41    }
42
43    public void run(String[] args) {
44        if (args.length < 1) {
45            showUsage();
46            return;
47        }
48
49        mImm = IInputMethodManager.Stub.asInterface(ServiceManager.getService("input_method"));
50        if (mImm == null) {
51            System.err.println(IMM_NOT_RUNNING_ERR);
52            return;
53        }
54
55        mArgs = args;
56        String op = args[0];
57        mNextArg = 1;
58
59        if ("list".equals(op)) {
60            runList();
61            return;
62        }
63
64        if ("enable".equals(op)) {
65            runSetEnabled(true);
66            return;
67        }
68
69        if ("disable".equals(op)) {
70            runSetEnabled(false);
71            return;
72        }
73
74        if ("set".equals(op)) {
75            runSet();
76            return;
77        }
78
79        if (op != null) {
80            System.err.println("Error: unknown command '" + op + "'");
81        }
82        showUsage();
83    }
84
85    /**
86     * Execute the list sub-command.
87     */
88    private void runList() {
89        String opt;
90        boolean all = false;
91        boolean brief = false;
92        while ((opt=nextOption()) != null) {
93            if (opt.equals("-a")) {
94                all = true;
95            } else if (opt.equals("-s")) {
96                brief = true;
97            } else {
98                System.err.println("Error: Unknown option: " + opt);
99                showUsage();
100                return;
101            }
102        }
103
104
105        List<InputMethodInfo> methods;
106        if (!all) {
107            try {
108                methods = mImm.getEnabledInputMethodList();
109            } catch (RemoteException e) {
110                System.err.println(e.toString());
111                System.err.println(IMM_NOT_RUNNING_ERR);
112                return;
113            }
114        } else {
115            try {
116                methods = mImm.getInputMethodList();
117            } catch (RemoteException e) {
118                System.err.println(e.toString());
119                System.err.println(IMM_NOT_RUNNING_ERR);
120                return;
121            }
122        }
123
124        if (methods != null) {
125            Printer pr = new PrintStreamPrinter(System.out);
126            for (int i=0; i<methods.size(); i++) {
127                InputMethodInfo imi = methods.get(i);
128                if (brief) {
129                    System.out.println(imi.getId());
130                } else {
131                    System.out.println(imi.getId() + ":");
132                    imi.dump(pr, "  ");
133                }
134            }
135        }
136    }
137
138    private void runSetEnabled(boolean state) {
139        String id = nextArg();
140        if (id == null) {
141            System.err.println("Error: no input method ID specified");
142            showUsage();
143            return;
144        }
145
146        try {
147            boolean res = mImm.setInputMethodEnabled(id, state);
148            if (state) {
149                System.out.println("Input method " + id + ": "
150                        + (res ? "already enabled" : "now enabled"));
151            } else {
152                System.out.println("Input method " + id + ": "
153                        + (res ? "now disabled" : "already disabled"));
154            }
155        } catch (IllegalArgumentException e) {
156            System.err.println("Error: " + e.getMessage());
157            return;
158        } catch (RemoteException e) {
159            System.err.println(e.toString());
160            System.err.println(IMM_NOT_RUNNING_ERR);
161            return;
162        }
163    }
164
165    private void runSet() {
166        String id = nextArg();
167        if (id == null) {
168            System.err.println("Error: no input method ID specified");
169            showUsage();
170            return;
171        }
172
173        try {
174            mImm.setInputMethod(null, id);
175            System.out.println("Input method " + id + " selected");
176        } catch (IllegalArgumentException e) {
177            System.err.println("Error: " + e.getMessage());
178            return;
179        } catch (RemoteException e) {
180            System.err.println(e.toString());
181            System.err.println(IMM_NOT_RUNNING_ERR);
182            return;
183        }
184    }
185
186    private String nextOption() {
187        if (mNextArg >= mArgs.length) {
188            return null;
189        }
190        String arg = mArgs[mNextArg];
191        if (!arg.startsWith("-")) {
192            return null;
193        }
194        mNextArg++;
195        if (arg.equals("--")) {
196            return null;
197        }
198        if (arg.length() > 1 && arg.charAt(1) != '-') {
199            if (arg.length() > 2) {
200                mCurArgData = arg.substring(2);
201                return arg.substring(0, 2);
202            } else {
203                mCurArgData = null;
204                return arg;
205            }
206        }
207        mCurArgData = null;
208        return arg;
209    }
210
211    private String nextOptionData() {
212        if (mCurArgData != null) {
213            return mCurArgData;
214        }
215        if (mNextArg >= mArgs.length) {
216            return null;
217        }
218        String data = mArgs[mNextArg];
219        mNextArg++;
220        return data;
221    }
222
223    private String nextArg() {
224        if (mNextArg >= mArgs.length) {
225            return null;
226        }
227        String arg = mArgs[mNextArg];
228        mNextArg++;
229        return arg;
230    }
231
232    private static void showUsage() {
233        System.err.println("usage: ime list [-a] [-s]");
234        System.err.println("       ime enable ID");
235        System.err.println("       ime disable ID");
236        System.err.println("       ime set ID");
237        System.err.println("");
238        System.err.println("The list command prints all enabled input methods.  Use");
239        System.err.println("the -a option to see all input methods.  Use");
240        System.err.println("the -s option to see only a single summary line of each.");
241        System.err.println("");
242        System.err.println("The enable command allows the given input method ID to be used.");
243        System.err.println("");
244        System.err.println("The disable command disallows the given input method ID from use.");
245        System.err.println("");
246        System.err.println("The set command switches to the given input method ID.");
247    }
248}
249