/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.multiclientinputmethod; import android.app.Service; import android.content.Intent; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.inputmethodservice.MultiClientInputMethodServiceDelegate; import android.os.IBinder; import android.util.Log; import android.util.SparseIntArray; /** * A {@link Service} that implements multi-client IME protocol. */ public final class MultiClientInputMethod extends Service implements DisplayListener { private static final String TAG = "MultiClientInputMethod"; private static final boolean DEBUG = false; // last client that had active InputConnection for a given displayId. final SparseIntArray mDisplayToLastClientId = new SparseIntArray(); SoftInputWindowManager mSoftInputWindowManager; MultiClientInputMethodServiceDelegate mDelegate; private DisplayManager mDisplayManager; @Override public void onCreate() { if (DEBUG) { Log.v(TAG, "onCreate"); } mDelegate = MultiClientInputMethodServiceDelegate.create(this, new MultiClientInputMethodServiceDelegate.ServiceCallback() { @Override public void initialized() { if (DEBUG) { Log.i(TAG, "initialized"); } } @Override public void addClient(int clientId, int uid, int pid, int selfReportedDisplayId) { final ClientCallbackImpl callback = new ClientCallbackImpl( MultiClientInputMethod.this, mDelegate, mSoftInputWindowManager, clientId, uid, pid, selfReportedDisplayId); if (DEBUG) { Log.v(TAG, "addClient clientId=" + clientId + " uid=" + uid + " pid=" + pid + " displayId=" + selfReportedDisplayId); } mDelegate.acceptClient(clientId, callback, callback.getDispatcherState(), callback.getLooper()); } @Override public void removeClient(int clientId) { if (DEBUG) { Log.v(TAG, "removeClient clientId=" + clientId); } } }); mSoftInputWindowManager = new SoftInputWindowManager(this, mDelegate); } @Override public void onDisplayAdded(int displayId) { } @Override public void onDisplayRemoved(int displayId) { mDisplayToLastClientId.delete(displayId); } @Override public void onDisplayChanged(int displayId) { } @Override public IBinder onBind(Intent intent) { if (DEBUG) { Log.v(TAG, "onBind intent=" + intent); } mDisplayManager = getApplicationContext().getSystemService(DisplayManager.class); mDisplayManager.registerDisplayListener(this, getMainThreadHandler()); return mDelegate.onBind(intent); } @Override public boolean onUnbind(Intent intent) { if (DEBUG) { Log.v(TAG, "onUnbind intent=" + intent); } if (mDisplayManager != null) { mDisplayManager.unregisterDisplayListener(this); } return mDelegate.onUnbind(intent); } @Override public void onDestroy() { if (DEBUG) { Log.v(TAG, "onDestroy"); } mDelegate.onDestroy(); } }