Yohei Yukawa 7276946b92 Use setTextOperationUser() in KeyguardPasswordView and RemoteInputView
Android implements many complex text-related operations as per-user
out-of-process services. Notable examples are:

  * InputMethodServices
  * SpellCheckerService
  * TextClassifierService
  * AutofillService

For service client processes to connect to the right user's services
often the system assumes that a process that runs as user X should
connect to services that run as user X.  While this approach works for
most of cases, there is at least one exception, System UI, which
always runs as the primary user (unless the device enables special
mode e.g. UserManager.isSplitSystemUser()) no matter who is the
current foreground user.

In order to deal with this special case, we recently introduced an
@hide API TextView#setTextOperationUser() [1] to centralize cross-user
special logic inside TextView.  With this CL, KeyguardPasswordView and
RemoteInputView actually start calling it.

Note that TextView#setTextOperationUser() already takes care of IMEs
and SpellCheckers hence those two operations start working as expected
with this CL.  Once TextView#setTextOperationUser() start taking care
of other operations such as text classification and clipboard,
KeyguardPasswordView and RemoteInputView will be automatically taken
care of with no code change.

 [1]: I6d11e4d6a84570bc2991a8552349e8b216b0d139
      401e3d4c842ce86569de4477138137dc07a6aa6f

Fix: 120744418
Fix: 123043618
Test: atest SystemUITests
Test: Manually tested Bug 120744418 scenario as follows.
  1. Build and flash an AOSP build
  2. adb root
  3. adb shell setprop persist.debug.per_profile_ime 1
  4. adb reboot
  5. Install Test DPC
  6. Enable managed profile with Test DPC
  7. make -j SoftKeyboard
  8. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk
  9. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard
 10. adb shell ime set com.example.android.softkeyboard/.SoftKeyboard
 11. make -j EditTextVariations
 12. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
 13. adb shell am start --user 0 \
     -n com.android.inputmethod.tools.edittextvariations/.EditTextVariations
 14. Tap the menu icon on the EditTextVariations then click "Direct Reply"
 15. adb shell am start --user 10 \
     -n com.android.inputmethod.tools.edittextvariations/.EditTextVariations
 16. Tap the menu icon on the EditTextVariations then click "Direct Reply"
 17. Open notification shade.
 18. Tap reply icon on "Message from UserHandle{0}".
 19. Make sure that SoftKeyboard Sample IME is shown.
 20. Tap reply icon on "Message from UserHandle{10}".
 21. Make sure that AOSP Keyboard is shown.
 22. Tap reply icon on "Message from UserHandle{0}" again.
 23. Make sure that SoftKeyboard Sample IME is shown again.
Test: Manually tested Bug 123043618 scenario as follows.
  1. Build and flash an AOSP build
  2. Create a secondary user then switch to it.
  3. make -j SoftKeyboard
  4. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk
  5. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard
  6. adb shell ime set com.example.android.softkeyboard/.SoftKeyboard
  7. make -j EditTextVariations
  8. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
  9. adb shell am start \
     -n com.android.inputmethod.tools.edittextvariations/.EditTextVariations
 10. Tap the menu icon on the EditTextVariations then click "Direct Reply"
 11. Tap reply icon on "Message from UserHandle{10}".
 12. Make sure that SoftKeyboard Sample IME is shown.
 13. Type "ggggg" then hit the space key.
 14. Make sure that red underline is drawn under "ggggg"
 15. Make sure that AndroidSpellCheckerService runs as user 10.
Test: Manually tested multi-user scenario with per-profile mode as follows.
  1. Build and flash an AOSP build
  2. adb root
  3. adb shell setprop persist.debug.per_profile_ime 1
  4. adb reboot
  5. Create a secondary user then switch to it.
  6. make -j SoftKeyboard
  7. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk
  8. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard
  9. adb shell ime set com.example.android.softkeyboard/.SoftKeyboard
 10. make -j EditTextVariations
 11. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
 12. adb shell am start \
     -n com.android.inputmethod.tools.edittextvariations/.EditTextVariations
 13. Tap the menu icon on the EditTextVariations then click "Direct Reply"
 14. Tap reply icon on "Message from UserHandle{10}".
 15. Make sure that SoftKeyboard Sample IME is shown.
 16. Type "ggggg" then hit the space key.
 17. Make sure that red underline is drawn under "ggggg"
 18. Make sure that AndroidSpellCheckerService runs as user 10.
 19. Set up a text screenlock.
 20. Turn off the display.
 21. Turn on the display.
 22. Make sure that SoftKeyboard Sample IME is shown.
Change-Id: Ibabe13e5b85e5bb91f9f8af6ec07c395c25c4393
2019-01-20 09:28:08 -08:00
..
2018-12-27 07:46:57 -05:00
2019-01-19 03:39:55 +00:00
2018-12-19 09:47:37 -05:00
2018-11-01 21:07:11 +00:00

SystemUI

“Everything you see in Android that's not an app”

SystemUI is a persistent process that provides UI for the system but outside of the system_server process.

The starting point for most of sysui code is a list of services that extend SystemUI that are started up by SystemUIApplication. These services then depend on some custom dependency injection provided by Dependency.

Inputs directed at sysui (as opposed to general listeners) generally come in through IStatusBar. Outputs from sysui are through a variety of private APIs to the android platform all over.

SystemUIApplication

When SystemUIApplication starts up, it will start up the services listed in config_systemUIServiceComponents or config_systemUIServiceComponentsPerUser.

Each of these services extend SystemUI. SystemUI provides them with a Context and gives them callbacks for onConfigurationChanged (this historically was the main path for onConfigurationChanged, now also happens through ConfigurationController). They also receive a callback for onBootCompleted since these objects may be started before the device has finished booting.

SystemUI and SystemUIApplication also have methods for putComponent and getComponent which were existing systems to get a hold of other parts of sysui before Dependency existed. Generally new things should not be added to putComponent, instead Dependency and other refactoring is preferred to make sysui structure cleaner.

Each SystemUI service is expected to be a major part of system ui and the goal is to minimize communication between them. So in general they should be relatively silo'd.

Dependencies

The first SystemUI service that is started should always be Dependency. Dependency provides a static method for getting a hold of dependencies that have a lifecycle that spans sysui. Dependency has code for how to create all dependencies manually added. SystemUIFactory is also capable of adding/replacing these dependencies.

Dependencies are lazily initialized, so if a Dependency is never referenced at runtime, it will never be created.

If an instantiated dependency implements Dumpable it will be included in dumps of sysui (and bug reports), allowing it to include current state information. This is how *Controllers dump state to bug reports.

If an instantiated dependency implements ConfigurationChangeReceiver it will receive onConfigurationChange callbacks when the configuration changes.

IStatusBar

CommandQueue is the object that receives all of the incoming events from the system_server. It extends IStatusBar and dispatches those callbacks back any number of listeners. The system_server gets a hold of the IStatusBar when StatusBar calls IStatusBarService#registerStatusBar, so if StatusBar is not included in the XML service list, it will not be registered with the OS.

CommandQueue posts all incoming callbacks to a handler and then dispatches those messages to each callback that is currently registered. CommandQueue also tracks the current value of disable flags and will call #disable immediately for any callbacks added.

There are a few places where CommandQueue is used as a bus to communicate across sysui. Such as when StatusBar calls CommandQueue#recomputeDisableFlags. This is generally used a shortcut to directly trigger CommandQueue rather than calling StatusManager and waiting for the call to come back to IStatusBar.

Default SystemUI services list

com.android.systemui.Dependency

Provides custom dependency injection.

com.android.systemui.util.NotificationChannels

Creates/initializes the channels sysui uses when posting notifications.

com.android.systemui.statusbar.CommandQueue$CommandQueueStart

Creates CommandQueue and calls putComponent because its always been there and sysui expects it to be there :/

com.android.systemui.keyguard.KeyguardViewMediator

Manages keyguard view state.

com.android.systemui.recents.Recents

Recents tracks all the data needed for recents and starts/stops the recents activity. It provides this cached data to RecentsActivity when it is started.

com.android.systemui.volume.VolumeUI

Registers all the callbacks/listeners required to show the Volume dialog when it should be shown.

com.android.systemui.stackdivider.Divider

Shows the drag handle for the divider between two apps when in split screen mode.

com.android.systemui.SystemBars

This is a proxy to the actual SystemUI for the status bar. This loads from config_statusBarComponent which defaults to StatusBar. (maybe this should be removed and copy how config_systemUiVendorServiceComponent works)

com.android.systemui.status.phone.StatusBar

This shows the UI for the status bar and the notification shade it contains. It also contains a significant amount of other UI that interacts with these surfaces (keyguard, AOD, etc.). StatusBar also contains a notification listener to receive notification callbacks.

com.android.systemui.usb.StorageNotification

Tracks USB status and sends notifications for it.

com.android.systemui.power.PowerUI

Tracks power status and sends notifications for low battery/power saver.

com.android.systemui.media.RingtonePlayer

Plays ringtones.

com.android.systemui.keyboard.KeyboardUI

Shows UI for keyboard shortcuts (triggered by keyboard shortcut).

com.android.systemui.pip.PipUI

Shows the overlay controls when Pip is showing.

com.android.systemui.shortcut.ShortcutKeyDispatcher

Dispatches shortcut to System UI components.

@string/config_systemUIVendorServiceComponent

Component allowing the vendor/OEM to inject a custom component.

com.android.systemui.util.leak.GarbageMonitor$Service

Tracks large objects in sysui to see if there are leaks.

com.android.systemui.LatencyTester

Class that only runs on debuggable builds that listens to broadcasts that simulate actions in the system that are used for testing the latency.

com.android.systemui.globalactions.GlobalActionsComponent

Shows the global actions dialog (long-press power).

com.android.systemui.ScreenDecorations

Draws decorations about the screen in software (e.g. rounded corners, cutouts).

com.android.systemui.biometrics.BiometricDialogImpl

Biometric UI.