Skip to content
Commit a878b950 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Support per-profile IME behind the flag

In order to support BYOD (Bring your own device) use cases, Android
phones can associate multiple users into a single profile group so
that other system components such as launcher can help users
seamlessly switch user identity without doing a heavy-weight
device-level user switching.

For instance, an Android device can be configured to work for two
different users Alice and Bob, while Alice also has two different
identities: one as her private account and the other for her
work-related account.

  Profile group X == Alice:
    Parent user X (user id: 0)
      for personal account, under her control.
    Child user 1 (user id: 10)
      for work-related account, partly under system-admin's control.
  Profile group Y == Bob:
    Parent user Y (user id: 11)
      private account, under his control.

The above configuration allows system-level data separation not only
between Alice (user 0) and Bob (user 11) but also between Alice's
personal account (user 0) and Alice's work-related account
(user 10). For instance, Calendar app that runs under user 0 cannot
see any data for other users including user 10.

IME is one of known exceptions in the above design. For instance, when
Alice is using the device, the system launches InputMethodService,
which is the code-level representation of IMEs, only for the user 0
then gives it a special ability to interact with all the applications
that run under the same profile group.

  Profile group X == Alice:
    IME works as user 0 but interacts with apps that run under
    user 0 and 10.
  Profile group Y == Bob:
    IME works as user 11 and interacts with apps that run under
    user 11.

Of course there are non-trivial imprications by sharing the same
instance of InputMethodService across profiles but this was basically
the only option when we initially introduced in Android 5.0 [1]
because of multiple challenges (schedule, complexity, performance
concerns, and so on). To to mitigate the risk, we also introduced APIs
that allow system administrators to whitelist what IMEs can be enabled
for the entire profile [2].  Even with such a whitelist feature, we
have received multiple feature requests to completely separate IME
instances by profile boundaries, like other applications behave.

This is why this CL was authored.

With this CL, a new runtime mode "per-profile IME" is introduced
behind the flag.  When the flag is enabled:

  * InputMethodManagerService (IMMS) may calls IMMS#switchUserLocked()
    from IMMS#startInputOrWindowGainedFocus() every time when a
    different profile's IME client gains IME focus.
  * SpellCheckerService also enables per-user mode, which has been
    temporarily disabled [3].
  * DevicePolicyManagerService no longer disable packages that contain
    system IMEs when creating a new profile user.
  * Following IME APIs start returning result based on the caller's
    user (profile) ID.
     * InputMethodManager#getInputMethodList()
     * InputMethodManager#getEnabledInputMethodList()
     * InputMethodManager#getEnabledInputMethodSubtypeList()

There are still multiple known issues though. Hopefully we can address
those issues in subsequent CLs.

 * Inline-reply from non-primary profiles is still dispatched to the
   main profile's IME because SysUI is always running under main
   profile (Bug 120744418).  This probably can be addressed by
   allowing the IME clients that have INTERACT_ACROSS_USERS_FULL to
   specify the target user ID in some @hide parameter.
 * IMMS#switchUserLocked() is not yet fully optimized (Bug 28750507).
   New client app's UI thread can be blocked more than 100ms,
   depending on the number of installed IMEs and the number of IME
   subtypes implemented by those IMEs.
 * Even after IMMS#switchUserLocked() is fully optimized, IMEs'
   cold-startups are known to be slow.  One way to optimize this is
   keeping binding to those IMEs, but doing so would require 1)
   non-trivial amount of code changes and 2) doubles RAM consumption.
 * Virtual keyboard settings page for profile users are not yet
   available (Bug 120748696).
 * Migration from shared-profile IME mode to per-profile IME mode is
   not yet supported (Bug 121348796).  By default, IME packages will
   be automatically disabled when a profile user is created.  This
   means if the device switches from shared-profile IME mode to
   per-profile IME mode, IME packages continue to be disabled hence
   the user cannot type anything for those profiles.

Anyway, there should be no behavior change unless the debug flag is
explicitly flipped.

 [1]: I3bd87b32aec69c3f8d470c8b29b144f4e849c808
      734983ff
 [2]: I921888660d29a5370395db87adf75d4d106660c9
      9c9cbac5b71a23ed0dbab0f44cb78a820514cfc6
 [3]: Ic046f832f203115106409a53418a5746eb6d4939
      3f8c5688

Fix: 120709962
Test: atest CtsInputMethodTestCases CtsInputMethodServiceHostTestCases
Test: Made sure that there is no behavior change if the debug flag is
      not set as follows.
  1. Install Test DPC
  2. Enable managed profile with Test DPC
  3. make -j EditTextVariations
  4. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
  5. Open two EditTextVariations instances in split-screen mode
   5.1. One is for the main profile
   5.2. The other is for the managed profile
  6. Make sure that main profile's instance of AOSP Keyboard is used
     for both applications.
  7. Make sure that main profile's instance of Android Spell Checker
     is used for both applications.
  8. adb shell ime list -a -s --user all
      -> Only "com.android.inputmethod.latin/.LatinIME" is shown.
  9. adb shell dumpsys textservices
      -> Only result for user #0 is shown.
Test: Made sure that basic text input can be done with
      "per-profile IME" mode enabled as follows.
  1. adb root
  2. adb shell setprop persist.debug.per_profile_ime 1
  3. adb reboot
  4. Install Test DPC
  5. Enable managed profile with Test DPC
  6. make -j EditTextVariations
  7. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
  8. Open two EditTextVariations instances in split-screen mode
   8.1. One is for the main profile
   8.2. The other is for the managed profile
  9. Make sure that AOSP Keyboard will be re-launched to correspond to
     the focused IME client's user profile.
   9.1 When EditTextVariations for the main profile is focused,
       AOSP Keyboard for the main profile is shown.
   9.2 When EditTextVariations for the work profile is focused,
       AOSP Keyboard for the work profile is shown.
 10. Make sure that different instances of Android Spell Checker are
     used based on target application's profile
 11. adb shell ime list -a -s --user all
      -> "com.android.inputmethod.latin/.LatinIME" is shown for both
         user #0 and user #10.
 12. adb shell dumpsys textservices
      -> Both user #0 and user #10 have results.
Test: atest DevicePolicyManagerTest#testSetPermittedInputMethods_failIfNotProfileOwner
Test: atest com.android.server.devicepolicy.OverlayPackagesProviderTest
Change-Id: Ied99664d3dc61b97c919b220c601f90b29761b96
parent 5f080277
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment