1 /*
2  * Copyright (C) 2017 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 android.inputmethodservice.cts.ime;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.inputmethodservice.InputMethodService;
24 import android.inputmethodservice.cts.common.ImeCommandConstants;
25 import android.inputmethodservice.cts.ime.ImeCommandReceiver.ImeCommandCallbacks;
26 import android.util.Log;
27 
28 /**
29  * {@link ImeCommandConstants#ACTION_IME_COMMAND} intent receiver.
30  */
31 final class ImeCommandReceiver<T extends InputMethodService & ImeCommandCallbacks>
32         extends BroadcastReceiver {
33 
34     private static final boolean DEBUG = false;
35 
36     interface ImeCommandCallbacks {
37         /**
38          * Callback method for {@link ImeCommandConstants#COMMAND_COMMIT_TEXT} intent.
39          *
40          * @param text text to be committed via {@link android.view.inputmethod.InputConnection}.
41          * @param newCursorPosition new cursor position after commit.
42          */
commandCommitText(CharSequence text, int newCursorPosition)43         void commandCommitText(CharSequence text, int newCursorPosition);
44 
45         /**
46          * Callback method for {@link ImeCommandConstants#COMMAND_SWITCH_INPUT_METHOD} intent.
47          *
48          * @param imeId IME id to switch.
49          */
commandSwitchInputMethod(String imeId)50         void commandSwitchInputMethod(String imeId);
51 
52         /**
53          * Callback method for {@link ImeCommandConstants#COMMAND_REQUEST_HIDE_SELF} intent.
54          */
commandRequestHideSelf(int flags)55         void commandRequestHideSelf(int flags);
56     }
57 
58     private T mIme;
59 
register(T ime)60     void register(T ime) {
61         mIme = ime;
62         ime.registerReceiver(this, new IntentFilter(ImeCommandConstants.ACTION_IME_COMMAND),
63                 Context.RECEIVER_EXPORTED);
64     }
65 
66     @Override
onReceive(Context context, Intent intent)67     public void onReceive(Context context, Intent intent) {
68         final String command = intent.getStringExtra(ImeCommandConstants.EXTRA_COMMAND);
69         if (DEBUG) {
70             Log.d(mIme.getClass().getSimpleName(), "onReceive: command=" + command);
71         }
72 
73         switch (command) {
74             case ImeCommandConstants.COMMAND_COMMIT_TEXT: {
75                 final CharSequence text = getCharSequence1(intent);
76                 final int newCursorPosition = getInt1(intent);
77                 mIme.commandCommitText(text, newCursorPosition);
78                 return;
79             }
80             case ImeCommandConstants.COMMAND_SWITCH_INPUT_METHOD: {
81                 final String imeId = getString1(intent);
82                 mIme.commandSwitchInputMethod(imeId);
83                 return;
84             }
85             case ImeCommandConstants.COMMAND_REQUEST_HIDE_SELF: {
86                 final int flags = getInt1(intent);
87                 mIme.commandRequestHideSelf(flags);
88                 return;
89             }
90             case ImeCommandConstants.COMMAND_SWITCH_INPUT_METHOD_WITH_SUBTYPE: {
91                 final String imeId = getString1(intent);
92                 // we don't support mock imes with subtypes yet.
93                 mIme.switchInputMethod(imeId, null /* subtype*/);
94                 return;
95             }
96             case ImeCommandConstants.COMMAND_SWITCH_TO_NEXT_INPUT: {
97                 mIme.switchToNextInputMethod(false);
98                 return;
99             }
100             case ImeCommandConstants.COMMAND_SWITCH_TO_PREVIOUS_INPUT: {
101                 mIme.switchToPreviousInputMethod();
102                 return;
103             }
104             default: {
105                 throw new UnsupportedOperationException("Unknown IME command: " + command);
106             }
107         }
108     }
109 
getCharSequence1(Intent intent)110     private static CharSequence getCharSequence1(Intent intent) {
111         return intent.getCharSequenceExtra(ImeCommandConstants.EXTRA_ARG_CHARSEQUENCE1);
112     }
113 
getString1(Intent intent)114     private static String getString1(Intent intent) {
115         return intent.getStringExtra(ImeCommandConstants.EXTRA_ARG_STRING1);
116     }
117 
getInt1(Intent intent)118     private static int getInt1(Intent intent) {
119         if (intent.hasExtra(ImeCommandConstants.EXTRA_ARG_INT1)) {
120             return intent.getIntExtra(ImeCommandConstants.EXTRA_ARG_INT1, 0);
121         }
122         throw new IllegalArgumentException(
123                 "Needs " + ImeCommandConstants.EXTRA_ARG_INT1 + " in " + intent);
124     }
125 }
126