Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6e62f99 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Let MCIMMS warn if per-display focus is not enabled

With a recent CL [1], per-display focus is now configurable and not
guaranteed to be enabled.  On the other hand, multi-client IME
framework always expects that per-display focus is enabled.

In order to not confuse developers, with this CL the system will post
a notification when such a mismatch is found.  This CL also clarifies
this point in the developer document.

There should be no behavior changes unless multi-client IME mode is
explicitly enabled.

 [1]: Ie030eed523599b217060887171710692d050e5d8
      51c5a1d0

Fix: 126909664
Test: Manually verified as follows.
  1. Build aosp_blueline-userdebug and flash it.
  2. make -j MultiClientInputMethod
  3. adb install -r \
     $OUT/system/priv-app/MultiClientInputMethod/MultiClientInputMethod.apk
  4. adb root
  5. adb shell setprop persist.debug.multi_client_ime \
     com.example.android.multiclientinputmethod/.MultiClientInputMethod
  6. adb reboot
  7. Make sure that a notification is shown and says that
     "config_perDisplayFocusEnabled" needs to be true in the system image.
Change-Id: I881ad57dc6478aabc0e8d7d031196cb2cc48a96d
parent 44faad3e
Loading
Loading
Loading
Loading
+41 −3
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -44,6 +46,7 @@ import android.inputmethodservice.MultiClientInputMethodServiceDelegate;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
@@ -66,6 +69,7 @@ import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.view.inputmethod.InputMethodSystemProperty;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IMultiClientInputMethod;
import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
@@ -73,6 +77,8 @@ import com.android.internal.inputmethod.IMultiClientInputMethodSession;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -96,8 +102,15 @@ import java.util.WeakHashMap;
 * we can switch the implementation at the boot time.</p>
 */
public final class MultiClientInputMethodManagerService {
    static final String TAG = "MultiClientInputMethodManagerService";
    static final boolean DEBUG = false;
    private static final String TAG = "MultiClientInputMethodManagerService";
    private static final boolean DEBUG = false;

    private static final String PER_DISPLAY_FOCUS_DISABLED_WARNING_TITLE =
            "config_perDisplayFocusEnabled is not true.";

    private static final String PER_DISPLAY_FOCUS_DISABLED_WARNING_MSG =
            "Consider rebuilding the system image after enabling config_perDisplayFocusEnabled to "
                    + "make IME focus compatible with multi-client IME mode.";

    private static final long RECONNECT_DELAY_MSEC = 1000;

@@ -465,10 +478,35 @@ public final class MultiClientInputMethodManagerService {
                            onPackageAdded(intent);
                        }
                    }, filter, null, mHandler);
                    break;
                }
                case SystemService.PHASE_BOOT_COMPLETED: {
                    final boolean perDisplayFocusEnabled = mContext.getResources().getBoolean(
                            com.android.internal.R.bool.config_perDisplayFocusEnabled);
                    if (!perDisplayFocusEnabled) {
                        final Bundle extras = new Bundle();
                        extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
                        mContext.getSystemService(NotificationManager.class).notifyAsUser(TAG,
                                SystemMessageProto.SystemMessage.NOTE_SELECT_INPUT_METHOD,
                                new Notification.Builder(mContext,
                                        SystemNotificationChannels.VIRTUAL_KEYBOARD)
                                        .setContentTitle(PER_DISPLAY_FOCUS_DISABLED_WARNING_TITLE)
                                        .setStyle(new Notification.BigTextStyle()
                                                .bigText(PER_DISPLAY_FOCUS_DISABLED_WARNING_MSG))
                                        .setSmallIcon(R.drawable.ic_notification_ime_default)
                                        .setWhen(0)
                                        .setOngoing(true)
                                        .setLocalOnly(true)
                                        .addExtras(extras)
                                        .setCategory(Notification.CATEGORY_SYSTEM)
                                        .setColor(mContext.getColor(
                                                R.color.system_notification_accent_color))
                                        .build(), UserHandle.ALL);
                    }
                    break;
                }
            }
        }

        @WorkerThread
        void onPackageAdded(Intent intent) {
+3 −1
Original line number Diff line number Diff line
@@ -39,7 +39,9 @@ Thus the first decision we made was that to support such special multi-display e

## How to test

On AOSP-based development devices (e.g. phones) where `android.os.Build.IS_DEBUGGABLE` returns `true` and you can have root access, you can enable multi-client IME feature by setting a valid component name that supports multi-client IME protocol to the system property `persist.debug.multi_client_ime`. Reboot is required for this to take effect.
For multi-client IME to properly work, an internal boolean resource `com.android.internal.R.bool.config_perDisplayFocusEnabled` needs to be `true`. Since this value cannot be overridden at the run time, you may need to rebuild the system image to enable per-display focus mode.

As for multi-client IME mode itself, you can enable multi-client IME mode just by setting a valid component name that supports multi-client IME protocol to the system property `persist.debug.multi_client_ime`, as long as `android.os.Build.IS_DEBUGGABLE` returns `true` and you can have root access. Reboot is required for this to take effect.

```shell
# Build and install a sample multi-client IME