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

Commit 631b6380 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android Git Automerger
Browse files

am 0a5c5567: Merge "Multi-user support for the accessibility layer." into jb-mr1-dev

* commit '0a5c5567':
  Multi-user support for the accessibility layer.
parents 95c8534a 0a5c5567
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -42,10 +42,8 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.ManifestDigest;
import android.content.pm.UserInfo;
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
@@ -453,11 +451,17 @@ final class ApplicationPackageManager extends PackageManager {

    @Override
    public ResolveInfo resolveActivity(Intent intent, int flags) {
        return resolveActivityAsUser(intent, flags, UserHandle.myUserId());
    }

    @Override
    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
        try {
            return mPM.resolveIntent(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags, UserHandle.myUserId());
                flags,
                userId);
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
@@ -466,12 +470,12 @@ final class ApplicationPackageManager extends PackageManager {
    @Override
    public List<ResolveInfo> queryIntentActivities(Intent intent,
                                                   int flags) {
        return queryIntentActivitiesForUser(intent, flags, UserHandle.myUserId());
        return queryIntentActivitiesAsUser(intent, flags, UserHandle.myUserId());
    }

    /** @hide Same as above but for a specific user */
    @Override
    public List<ResolveInfo> queryIntentActivitiesForUser(Intent intent,
    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
                                                   int flags, int userId) {
        try {
            return mPM.queryIntentActivities(
@@ -551,18 +555,23 @@ final class ApplicationPackageManager extends PackageManager {
    }

    @Override
    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
        try {
            return mPM.queryIntentServices(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags,
                UserHandle.myUserId());
                userId);
        } catch (RemoteException e) {
            throw new RuntimeException("Package manager has died", e);
        }
    }

    @Override
    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
        return queryIntentServicesAsUser(intent, flags, UserHandle.myUserId());
    }

    @Override
    public ProviderInfo resolveContentProvider(String name,
                                               int flags) {
+55 −1
Original line number Diff line number Diff line
@@ -1796,6 +1796,39 @@ public abstract class PackageManager {
     */
    public abstract ResolveInfo resolveActivity(Intent intent, int flags);

    /**
     * Determine the best action to perform for a given Intent for a given user. This
     * is how {@link Intent#resolveActivity} finds an activity if a class has not
     * been explicitly specified.
     *
     * <p><em>Note:</em> if using an implicit Intent (without an explicit ComponentName
     * specified), be sure to consider whether to set the {@link #MATCH_DEFAULT_ONLY}
     * only flag.  You need to do so to resolve the activity in the same way
     * that {@link android.content.Context#startActivity(Intent)} and
     * {@link android.content.Intent#resolveActivity(PackageManager)
     * Intent.resolveActivity(PackageManager)} do.</p>
     *
     * @param intent An intent containing all of the desired specification
     *               (action, data, type, category, and/or component).
     * @param flags Additional option flags.  The most important is
     * {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
     * those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
     * @param userId The user id.
     *
     * @return Returns a ResolveInfo containing the final activity intent that
     *         was determined to be the best action.  Returns null if no
     *         matching activity was found. If multiple matching activities are
     *         found and there is no default set, returns a ResolveInfo
     *         containing something else, such as the activity resolver.
     *
     * @see #MATCH_DEFAULT_ONLY
     * @see #GET_INTENT_FILTERS
     * @see #GET_RESOLVED_FILTER
     *
     * @hide
     */
    public abstract ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId);

    /**
     * Retrieve all activities that can be performed for the given intent.
     *
@@ -1836,7 +1869,7 @@ public abstract class PackageManager {
     * @see #GET_RESOLVED_FILTER
     * @hide
     */
    public abstract List<ResolveInfo> queryIntentActivitiesForUser(Intent intent,
    public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
            int flags, int userId);


@@ -1943,6 +1976,27 @@ public abstract class PackageManager {
    public abstract List<ResolveInfo> queryIntentServices(Intent intent,
            int flags);

    /**
     * Retrieve all services that can match the given intent for a given user.
     *
     * @param intent The desired intent as per resolveService().
     * @param flags Additional option flags.
     * @param userId The user id.
     *
     * @return A List&lt;ResolveInfo&gt; containing one entry for each matching
     *         ServiceInfo. These are ordered from best to worst match -- that
     *         is, the first item in the list is what is returned by
     *         resolveService().  If there are no matching services, an empty
     *         list is returned.
     *
     * @see #GET_INTENT_FILTERS
     * @see #GET_RESOLVED_FILTER
     *
     * @hide
     */
    public abstract List<ResolveInfo> queryIntentServicesAsUser(Intent intent,
            int flags, int userId);

    /**
     * Find a single content provider by its base path name.
     *
+50 −10
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;
import android.view.IWindow;
import android.view.View;
@@ -79,6 +80,8 @@ public final class AccessibilityManager {

    final IAccessibilityManager mService;

    final int mUserId;

    final Handler mHandler;

    boolean mIsEnabled;
@@ -128,36 +131,73 @@ public final class AccessibilityManager {
        }
    }

    /**
     * Creates the singleton AccessibilityManager to be shared across users. This
     * has to be called before the local AccessibilityManager is created to ensure
     * it registers itself in the system correctly.
     * <p>
     * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or
     *       INTERACT_ACROSS_USERS permission.
     * </p>
     * @param context Context in which this manager operates.
     * @throws IllegalStateException if not called before the local
     *     AccessibilityManager is instantiated.
     *
     * @hide
     */
    public static void createAsSharedAcrossUsers(Context context) {
        synchronized (sInstanceSync) {
            if (sInstance != null) {
                throw new IllegalStateException("AccessibilityManager already created.");
            }
            createSingletonInstance(context, UserHandle.USER_CURRENT);
        }
    }

    /**
     * Get an AccessibilityManager instance (create one if necessary).
     *
     * @param context Context in which this manager operates.
     *
     * @hide
     */
    public static AccessibilityManager getInstance(Context context) {
        synchronized (sInstanceSync) {
            if (sInstance == null) {
                IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
                IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
                sInstance = new AccessibilityManager(context, service);
                createSingletonInstance(context, UserHandle.myUserId());
            }
        }
        return sInstance;
    }

    /**
     * Creates the singleton instance.
     *
     * @param context Context in which this manager operates.
     * @param userId The user id under which to operate.
     */
    private static void createSingletonInstance(Context context, int userId) {
        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
        IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
        sInstance = new AccessibilityManager(context, service, userId);
    }

    /**
     * Create an instance.
     *
     * @param context A {@link Context}.
     * @param service An interface to the backing service.
     * @param userId User id under which to run.
     *
     * @hide
     */
    public AccessibilityManager(Context context, IAccessibilityManager service) {
    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
        mHandler = new MyHandler(context.getMainLooper());
        mService = service;
        mUserId = userId;

        try {
            final int stateFlags = mService.addClient(mClient);
            final int stateFlags = mService.addClient(mClient, userId);
            setState(stateFlags);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
@@ -222,7 +262,7 @@ public final class AccessibilityManager {
            // client using it is called through Binder from another process. Example: MMS
            // app adds a SMS notification and the NotificationManagerService calls this method
            long identityToken = Binder.clearCallingIdentity();
            doRecycle = mService.sendAccessibilityEvent(event);
            doRecycle = mService.sendAccessibilityEvent(event, mUserId);
            Binder.restoreCallingIdentity(identityToken);
            if (DEBUG) {
                Log.i(LOG_TAG, event + " sent");
@@ -244,7 +284,7 @@ public final class AccessibilityManager {
            throw new IllegalStateException("Accessibility off. Did you forget to check that?");
        }
        try {
            mService.interrupt();
            mService.interrupt(mUserId);
            if (DEBUG) {
                Log.i(LOG_TAG, "Requested interrupt from all services");
            }
@@ -280,7 +320,7 @@ public final class AccessibilityManager {
    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
        List<AccessibilityServiceInfo> services = null;
        try {
            services = mService.getInstalledAccessibilityServiceList();
            services = mService.getInstalledAccessibilityServiceList(mUserId);
            if (DEBUG) {
                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
            }
@@ -307,7 +347,7 @@ public final class AccessibilityManager {
            int feedbackTypeFlags) {
        List<AccessibilityServiceInfo> services = null;
        try {
            services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags);
            services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags, mUserId);
            if (DEBUG) {
                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
            }
@@ -385,7 +425,7 @@ public final class AccessibilityManager {
    public int addAccessibilityInteractionConnection(IWindow windowToken,
            IAccessibilityInteractionConnection connection) {
        try {
            return mService.addAccessibilityInteractionConnection(windowToken, connection);
            return mService.addAccessibilityInteractionConnection(windowToken, connection, mUserId);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re);
        }
+6 −6
Original line number Diff line number Diff line
@@ -34,18 +34,18 @@ import android.view.IWindow;
 */
interface IAccessibilityManager {

    int addClient(IAccessibilityManagerClient client);
    int addClient(IAccessibilityManagerClient client, int userId);

    boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent);
    boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent, int userId);

    List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
    List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId);

    List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType);
    List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId);

    void interrupt();
    void interrupt(int userId);

    int addAccessibilityInteractionConnection(IWindow windowToken,
        in IAccessibilityInteractionConnection connection);
        in IAccessibilityInteractionConnection connection, int userId);

    void removeAccessibilityInteractionConnection(IWindow windowToken);

+5 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.os.ServiceManager;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;

public class SystemUIService extends Service {
    static final String TAG = "SystemUIService";
@@ -67,6 +68,10 @@ public class SystemUIService extends Service {

    @Override
    public void onCreate() {
        // Tell the accessibility layer that this process will
        // run as the current user, i.e. run across users.
        AccessibilityManager.createAsSharedAcrossUsers(this);

        // Pick status bar or system bar.
        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
        try {
Loading