2727import android .os .RemoteException ;
2828import android .os .ServiceManager ;
2929import android .os .SystemClock ;
30+ import android .os .UserHandle ;
3031import android .util .Log ;
3132import android .view .IWindow ;
3233import android .view .View ;
@@ -79,6 +80,8 @@ public final class AccessibilityManager {
7980
8081 final IAccessibilityManager mService ;
8182
83+ final int mUserId ;
84+
8285 final Handler mHandler ;
8386
8487 boolean mIsEnabled ;
@@ -128,36 +131,73 @@ public void handleMessage(Message message) {
128131 }
129132 }
130133
134+ /**
135+ * Creates the singleton AccessibilityManager to be shared across users. This
136+ * has to be called before the local AccessibilityManager is created to ensure
137+ * it registers itself in the system correctly.
138+ * <p>
139+ * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or
140+ * INTERACT_ACROSS_USERS permission.
141+ * </p>
142+ * @param context Context in which this manager operates.
143+ * @throws IllegalStateException if not called before the local
144+ * AccessibilityManager is instantiated.
145+ *
146+ * @hide
147+ */
148+ public static void createAsSharedAcrossUsers (Context context ) {
149+ synchronized (sInstanceSync ) {
150+ if (sInstance != null ) {
151+ throw new IllegalStateException ("AccessibilityManager already created." );
152+ }
153+ createSingletonInstance (context , UserHandle .USER_CURRENT );
154+ }
155+ }
156+
131157 /**
132158 * Get an AccessibilityManager instance (create one if necessary).
133159 *
160+ * @param context Context in which this manager operates.
161+ *
134162 * @hide
135163 */
136164 public static AccessibilityManager getInstance (Context context ) {
137165 synchronized (sInstanceSync ) {
138166 if (sInstance == null ) {
139- IBinder iBinder = ServiceManager .getService (Context .ACCESSIBILITY_SERVICE );
140- IAccessibilityManager service = IAccessibilityManager .Stub .asInterface (iBinder );
141- sInstance = new AccessibilityManager (context , service );
167+ createSingletonInstance (context , UserHandle .myUserId ());
142168 }
143169 }
144170 return sInstance ;
145171 }
146172
173+ /**
174+ * Creates the singleton instance.
175+ *
176+ * @param context Context in which this manager operates.
177+ * @param userId The user id under which to operate.
178+ */
179+ private static void createSingletonInstance (Context context , int userId ) {
180+ IBinder iBinder = ServiceManager .getService (Context .ACCESSIBILITY_SERVICE );
181+ IAccessibilityManager service = IAccessibilityManager .Stub .asInterface (iBinder );
182+ sInstance = new AccessibilityManager (context , service , userId );
183+ }
184+
147185 /**
148186 * Create an instance.
149187 *
150188 * @param context A {@link Context}.
151189 * @param service An interface to the backing service.
190+ * @param userId User id under which to run.
152191 *
153192 * @hide
154193 */
155- public AccessibilityManager (Context context , IAccessibilityManager service ) {
194+ public AccessibilityManager (Context context , IAccessibilityManager service , int userId ) {
156195 mHandler = new MyHandler (context .getMainLooper ());
157196 mService = service ;
197+ mUserId = userId ;
158198
159199 try {
160- final int stateFlags = mService .addClient (mClient );
200+ final int stateFlags = mService .addClient (mClient , userId );
161201 setState (stateFlags );
162202 } catch (RemoteException re ) {
163203 Log .e (LOG_TAG , "AccessibilityManagerService is dead" , re );
@@ -222,7 +262,7 @@ public void sendAccessibilityEvent(AccessibilityEvent event) {
222262 // client using it is called through Binder from another process. Example: MMS
223263 // app adds a SMS notification and the NotificationManagerService calls this method
224264 long identityToken = Binder .clearCallingIdentity ();
225- doRecycle = mService .sendAccessibilityEvent (event );
265+ doRecycle = mService .sendAccessibilityEvent (event , mUserId );
226266 Binder .restoreCallingIdentity (identityToken );
227267 if (DEBUG ) {
228268 Log .i (LOG_TAG , event + " sent" );
@@ -244,7 +284,7 @@ public void interrupt() {
244284 throw new IllegalStateException ("Accessibility off. Did you forget to check that?" );
245285 }
246286 try {
247- mService .interrupt ();
287+ mService .interrupt (mUserId );
248288 if (DEBUG ) {
249289 Log .i (LOG_TAG , "Requested interrupt from all services" );
250290 }
@@ -280,7 +320,7 @@ public List<ServiceInfo> getAccessibilityServiceList() {
280320 public List <AccessibilityServiceInfo > getInstalledAccessibilityServiceList () {
281321 List <AccessibilityServiceInfo > services = null ;
282322 try {
283- services = mService .getInstalledAccessibilityServiceList ();
323+ services = mService .getInstalledAccessibilityServiceList (mUserId );
284324 if (DEBUG ) {
285325 Log .i (LOG_TAG , "Installed AccessibilityServices " + services );
286326 }
@@ -307,7 +347,7 @@ public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
307347 int feedbackTypeFlags ) {
308348 List <AccessibilityServiceInfo > services = null ;
309349 try {
310- services = mService .getEnabledAccessibilityServiceList (feedbackTypeFlags );
350+ services = mService .getEnabledAccessibilityServiceList (feedbackTypeFlags , mUserId );
311351 if (DEBUG ) {
312352 Log .i (LOG_TAG , "Installed AccessibilityServices " + services );
313353 }
@@ -385,7 +425,7 @@ private void notifyAccessibilityStateChanged() {
385425 public int addAccessibilityInteractionConnection (IWindow windowToken ,
386426 IAccessibilityInteractionConnection connection ) {
387427 try {
388- return mService .addAccessibilityInteractionConnection (windowToken , connection );
428+ return mService .addAccessibilityInteractionConnection (windowToken , connection , mUserId );
389429 } catch (RemoteException re ) {
390430 Log .e (LOG_TAG , "Error while adding an accessibility interaction connection. " , re );
391431 }
0 commit comments