Skip to content

Commit 0a5c556

Browse files
sganovAndroid (Google) Code Review
authored andcommitted
Merge "Multi-user support for the accessibility layer." into jb-mr1-dev
2 parents dbb2614 + 58d37b5 commit 0a5c556

File tree

10 files changed

+1010
-593
lines changed

10 files changed

+1010
-593
lines changed

core/java/android/app/ApplicationPackageManager.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@
4242
import android.content.pm.ResolveInfo;
4343
import android.content.pm.ServiceInfo;
4444
import android.content.pm.ManifestDigest;
45-
import android.content.pm.UserInfo;
4645
import android.content.pm.VerificationParams;
4746
import android.content.pm.VerifierDeviceIdentity;
48-
import android.content.pm.PackageManager.NameNotFoundException;
4947
import android.content.res.Resources;
5048
import android.content.res.XmlResourceParser;
5149
import android.graphics.drawable.Drawable;
@@ -453,11 +451,17 @@ public List<ApplicationInfo> getInstalledApplications(int flags) {
453451

454452
@Override
455453
public ResolveInfo resolveActivity(Intent intent, int flags) {
454+
return resolveActivityAsUser(intent, flags, UserHandle.myUserId());
455+
}
456+
457+
@Override
458+
public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
456459
try {
457460
return mPM.resolveIntent(
458461
intent,
459462
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
460-
flags, UserHandle.myUserId());
463+
flags,
464+
userId);
461465
} catch (RemoteException e) {
462466
throw new RuntimeException("Package manager has died", e);
463467
}
@@ -466,12 +470,12 @@ public ResolveInfo resolveActivity(Intent intent, int flags) {
466470
@Override
467471
public List<ResolveInfo> queryIntentActivities(Intent intent,
468472
int flags) {
469-
return queryIntentActivitiesForUser(intent, flags, UserHandle.myUserId());
473+
return queryIntentActivitiesAsUser(intent, flags, UserHandle.myUserId());
470474
}
471475

472476
/** @hide Same as above but for a specific user */
473477
@Override
474-
public List<ResolveInfo> queryIntentActivitiesForUser(Intent intent,
478+
public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
475479
int flags, int userId) {
476480
try {
477481
return mPM.queryIntentActivities(
@@ -551,18 +555,23 @@ public ResolveInfo resolveService(Intent intent, int flags) {
551555
}
552556

553557
@Override
554-
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
558+
public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
555559
try {
556560
return mPM.queryIntentServices(
557561
intent,
558562
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
559563
flags,
560-
UserHandle.myUserId());
564+
userId);
561565
} catch (RemoteException e) {
562566
throw new RuntimeException("Package manager has died", e);
563567
}
564568
}
565569

570+
@Override
571+
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
572+
return queryIntentServicesAsUser(intent, flags, UserHandle.myUserId());
573+
}
574+
566575
@Override
567576
public ProviderInfo resolveContentProvider(String name,
568577
int flags) {

core/java/android/content/pm/PackageManager.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,39 @@ public abstract int getUidForSharedUser(String sharedUserName)
17961796
*/
17971797
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
17981798

1799+
/**
1800+
* Determine the best action to perform for a given Intent for a given user. This
1801+
* is how {@link Intent#resolveActivity} finds an activity if a class has not
1802+
* been explicitly specified.
1803+
*
1804+
* <p><em>Note:</em> if using an implicit Intent (without an explicit ComponentName
1805+
* specified), be sure to consider whether to set the {@link #MATCH_DEFAULT_ONLY}
1806+
* only flag. You need to do so to resolve the activity in the same way
1807+
* that {@link android.content.Context#startActivity(Intent)} and
1808+
* {@link android.content.Intent#resolveActivity(PackageManager)
1809+
* Intent.resolveActivity(PackageManager)} do.</p>
1810+
*
1811+
* @param intent An intent containing all of the desired specification
1812+
* (action, data, type, category, and/or component).
1813+
* @param flags Additional option flags. The most important is
1814+
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
1815+
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
1816+
* @param userId The user id.
1817+
*
1818+
* @return Returns a ResolveInfo containing the final activity intent that
1819+
* was determined to be the best action. Returns null if no
1820+
* matching activity was found. If multiple matching activities are
1821+
* found and there is no default set, returns a ResolveInfo
1822+
* containing something else, such as the activity resolver.
1823+
*
1824+
* @see #MATCH_DEFAULT_ONLY
1825+
* @see #GET_INTENT_FILTERS
1826+
* @see #GET_RESOLVED_FILTER
1827+
*
1828+
* @hide
1829+
*/
1830+
public abstract ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId);
1831+
17991832
/**
18001833
* Retrieve all activities that can be performed for the given intent.
18011834
*
@@ -1836,7 +1869,7 @@ public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
18361869
* @see #GET_RESOLVED_FILTER
18371870
* @hide
18381871
*/
1839-
public abstract List<ResolveInfo> queryIntentActivitiesForUser(Intent intent,
1872+
public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
18401873
int flags, int userId);
18411874

18421875

@@ -1943,6 +1976,27 @@ public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent,
19431976
public abstract List<ResolveInfo> queryIntentServices(Intent intent,
19441977
int flags);
19451978

1979+
/**
1980+
* Retrieve all services that can match the given intent for a given user.
1981+
*
1982+
* @param intent The desired intent as per resolveService().
1983+
* @param flags Additional option flags.
1984+
* @param userId The user id.
1985+
*
1986+
* @return A List&lt;ResolveInfo&gt; containing one entry for each matching
1987+
* ServiceInfo. These are ordered from best to worst match -- that
1988+
* is, the first item in the list is what is returned by
1989+
* resolveService(). If there are no matching services, an empty
1990+
* list is returned.
1991+
*
1992+
* @see #GET_INTENT_FILTERS
1993+
* @see #GET_RESOLVED_FILTER
1994+
*
1995+
* @hide
1996+
*/
1997+
public abstract List<ResolveInfo> queryIntentServicesAsUser(Intent intent,
1998+
int flags, int userId);
1999+
19462000
/**
19472001
* Find a single content provider by its base path name.
19482002
*

core/java/android/view/accessibility/AccessibilityManager.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import android.os.RemoteException;
2828
import android.os.ServiceManager;
2929
import android.os.SystemClock;
30+
import android.os.UserHandle;
3031
import android.util.Log;
3132
import android.view.IWindow;
3233
import 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
}

core/java/android/view/accessibility/IAccessibilityManager.aidl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ import android.view.IWindow;
3434
*/
3535
interface IAccessibilityManager {
3636

37-
int addClient(IAccessibilityManagerClient client);
37+
int addClient(IAccessibilityManagerClient client, int userId);
3838

39-
boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent);
39+
boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent, int userId);
4040

41-
List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
41+
List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId);
4242

43-
List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType);
43+
List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId);
4444

45-
void interrupt();
45+
void interrupt(int userId);
4646

4747
int addAccessibilityInteractionConnection(IWindow windowToken,
48-
in IAccessibilityInteractionConnection connection);
48+
in IAccessibilityInteractionConnection connection, int userId);
4949

5050
void removeAccessibilityInteractionConnection(IWindow windowToken);
5151

packages/SystemUI/src/com/android/systemui/SystemUIService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import android.util.Slog;
3333
import android.view.IWindowManager;
3434
import android.view.WindowManagerGlobal;
35+
import android.view.accessibility.AccessibilityManager;
3536

3637
public class SystemUIService extends Service {
3738
static final String TAG = "SystemUIService";
@@ -67,6 +68,10 @@ private Class chooseClass(Object o) {
6768

6869
@Override
6970
public void onCreate() {
71+
// Tell the accessibility layer that this process will
72+
// run as the current user, i.e. run across users.
73+
AccessibilityManager.createAsSharedAcrossUsers(this);
74+
7075
// Pick status bar or system bar.
7176
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
7277
try {

0 commit comments

Comments
 (0)