Add InputMethodListListener interface.

It's for watching changes of installed IMEs.
The services in system_server can watch changes of installed IMEs by
implementing the new interface and register it to
InputMethodManagerInternal which can be obtained as LocalService.

Bug: 111905132
Test: Manually tested. The IME list on ChromeOS settings is updated
      correctly when installing/uninstalling IME apps.
Change-Id: I02a42d01c71f661ea877de472c5c9bd365014ac5
Merged-In: I02a42d01c71f661ea877de472c5c9bd365014ac5
This commit is contained in:
Yuichiro Hanada
2020-01-15 16:53:07 +09:00
parent aff240adcc
commit 34c4c0ed9d
3 changed files with 54 additions and 1 deletions

View File

@@ -33,6 +33,16 @@ import java.util.List;
* Input method manager local system service interface.
*/
public abstract class InputMethodManagerInternal {
/**
* Listener for input method list changed events.
*/
public interface InputMethodListListener {
/**
* Called with the list of the installed IMEs when it's updated.
*/
void onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId);
}
/**
* Called by the power manager to tell the input method manager whether it
* should start watching for wake events.
@@ -84,6 +94,11 @@ public abstract class InputMethodManagerInternal {
*/
public abstract boolean switchToInputMethod(String imeId, @UserIdInt int userId);
/**
* Registers a new {@link InputMethodListListener}.
*/
public abstract void registerInputMethodListListener(InputMethodListListener listener);
/**
* Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/
@@ -117,6 +132,10 @@ public abstract class InputMethodManagerInternal {
public boolean switchToInputMethod(String imeId, int userId) {
return false;
}
@Override
public void registerInputMethodListListener(InputMethodListListener listener) {
}
};
/**

View File

@@ -154,6 +154,7 @@ import com.android.internal.view.InputBindResult;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
import com.android.server.statusbar.StatusBarManagerService;
@@ -172,6 +173,7 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -214,6 +216,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
static final int MSG_SYSTEM_UNLOCK_USER = 5000;
static final int MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED = 5010;
static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
@@ -688,6 +691,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final IPackageManager mIPackageManager;
private final String mSlotIme;
/**
* Registered {@link InputMethodListListeners}.
* This variable can be accessed from both of MainThread and BinderThread.
*/
private final CopyOnWriteArrayList<InputMethodListListener> mInputMethodListListeners =
new CopyOnWriteArrayList<>();
/**
* Internal state snapshot when {@link #MSG_START_INPUT} message is about to be posted to the
* internal message queue. Any subsequent state change inside {@link InputMethodManagerService}
@@ -3946,10 +3956,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mHardKeyboardListener.handleHardKeyboardStatusChange(msg.arg1 == 1);
return true;
case MSG_SYSTEM_UNLOCK_USER:
case MSG_SYSTEM_UNLOCK_USER: {
final int userId = msg.arg1;
onUnlockUser(userId);
return true;
}
case MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED: {
final int userId = msg.arg1;
final List<InputMethodInfo> imes = (List<InputMethodInfo>) msg.obj;
mInputMethodListListeners.forEach(
listener -> listener.onInputMethodListUpdated(imes, userId));
return true;
}
// ---------------------------------------------------------------
case MSG_INLINE_SUGGESTIONS_REQUEST:
@@ -4142,6 +4160,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// TODO: Make sure that mSwitchingController and mSettings are sharing the
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
// Notify InputMethodListListeners of the new installed InputMethods.
final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
mHandler.obtainMessage(MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED,
mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
}
// ----------------------------------------------------------------------
@@ -4606,6 +4629,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public boolean switchToInputMethod(String imeId, int userId) {
return mService.switchToInputMethod(imeId, userId);
}
@Override
public void registerInputMethodListListener(InputMethodListListener listener) {
mService.mInputMethodListListeners.addIfAbsent(listener);
}
}
@BinderThread

View File

@@ -207,6 +207,12 @@ public final class MultiClientInputMethodManagerService {
reportNotSupported();
return false;
}
@Override
public void registerInputMethodListListener(
InputMethodListListener listener) {
reportNotSupported();
}
});
}