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

Commit 39810767 authored by Vadim Tryshev's avatar Vadim Tryshev
Browse files

Using actual users in more places.

Fixing an issue when installed apps in Guest user were treated incorrectly.
This happened because we used APIs using the systemui current user (0),
not the app's user.

Also, switching AppInfo from user's serial numbers to UserHandle. Earlier,
I declared that user ids (not serials) is the "lingua franca" between different classes,
so, this move is along these lines. In addition, this is simply more convenient.

Bug: 20024603
Change-Id: I749d900aa17083a41e4215c6587ae5ccaa31f5eb
parent 16ac7c3b
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -17,24 +17,26 @@
package com.android.systemui.statusbar.phone;
package com.android.systemui.statusbar.phone;


import android.content.ComponentName;
import android.content.ComponentName;
import android.os.UserHandle;


/**
/**
 * Navigation bar app information.
 * Navigation bar app information.
 */
 */
class AppInfo {
class AppInfo {
    private final ComponentName mComponentName;
    private final ComponentName mComponentName;
    private final long mUserSerialNumber;
    private final UserHandle mUser;


    public AppInfo(ComponentName componentName, long userSerialNumber) {
    public AppInfo(ComponentName componentName, UserHandle user) {
        if (componentName == null || user == null) throw new IllegalArgumentException();
        mComponentName = componentName;
        mComponentName = componentName;
        mUserSerialNumber = userSerialNumber;
        mUser = user;
    }
    }


    public ComponentName getComponentName() {
    public ComponentName getComponentName() {
        return mComponentName;
        return mComponentName;
    }
    }


    public long getUserSerialNumber() {
    public UserHandle getUser() {
        return mUserSerialNumber;
        return mUser;
    }
    }
}
}
+21 −9
Original line number Original line Diff line number Diff line
@@ -16,20 +16,21 @@


package com.android.systemui.statusbar.phone;
package com.android.systemui.statusbar.phone;


import android.content.ComponentName;
import android.app.AppGlobals;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.AsyncTask;
import android.os.RemoteException;
import android.util.Slog;
import android.util.Slog;
import android.view.View;
import android.widget.ImageView;
import android.widget.ImageView;


/**
/**
 * Retrieves the icon for an activity and sets it as the Drawable on an ImageView. The ImageView
 * Retrieves the icon for an activity and sets it as the Drawable on an ImageView. The ImageView
 * is hidden if the activity isn't recognized or if there is no icon.
 * is hidden if the activity isn't recognized or if there is no icon.
 */
 */
class GetActivityIconTask extends AsyncTask<ComponentName, Void, Drawable> {
class GetActivityIconTask extends AsyncTask<AppInfo, Void, Drawable> {
    private final static String TAG = "GetActivityIconTask";
    private final static String TAG = "GetActivityIconTask";


    private final PackageManager mPackageManager;
    private final PackageManager mPackageManager;
@@ -43,15 +44,26 @@ class GetActivityIconTask extends AsyncTask<ComponentName, Void, Drawable> {
    }
    }


    @Override
    @Override
    protected Drawable doInBackground(ComponentName... params) {
    protected Drawable doInBackground(AppInfo... params) {
        if (params.length != 1) {
        if (params.length != 1) {
            throw new IllegalArgumentException("Expected one parameter");
            throw new IllegalArgumentException("Expected one parameter");
        }
        }
        ComponentName activityName = params[0];
        AppInfo appInfo = params[0];
        try {
        try {
            return mPackageManager.getActivityIcon(activityName);
            IPackageManager mPM = AppGlobals.getPackageManager();
        } catch (NameNotFoundException e) {
            ActivityInfo ai = mPM.getActivityInfo(
            Slog.w(TAG, "Icon not found for " + activityName);
                    appInfo.getComponentName(),
                    0,
                    appInfo.getUser().getIdentifier());

            if (ai == null) {
                Slog.w(TAG, "Icon not found for " + appInfo);
                return null;
            }

            return ai.loadIcon(mPackageManager);
        } catch (RemoteException e) {
            Slog.w(TAG, "Icon not found for " + appInfo, e);
            return null;
            return null;
        }
        }
    }
    }
+20 −42
Original line number Original line Diff line number Diff line
@@ -28,14 +28,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.view.DragEvent;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
@@ -48,8 +46,6 @@ import android.widget.Toast;
import com.android.internal.content.PackageMonitor;
import com.android.internal.content.PackageMonitor;
import com.android.systemui.R;
import com.android.systemui.R;


import java.util.List;

/**
/**
 * Container for application icons that appear in the navigation bar. Their appearance is similar
 * Container for application icons that appear in the navigation bar. Their appearance is similar
 * to the launcher hotseat. Clicking an icon launches the associated activity. A long click will
 * to the launcher hotseat. Clicking an icon launches the associated activity. A long click will
@@ -84,8 +80,6 @@ class NavigationBarApps extends LinearLayout {
    // When the user is not dragging this member is null.
    // When the user is not dragging this member is null.
    private View mDragView;
    private View mDragView;


    private long mCurrentUserSerialNumber = -1;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
@@ -173,17 +167,17 @@ class NavigationBarApps extends LinearLayout {
    }
    }


    private void removeIfUnlauncheable(String packageName, UserHandle user) {
    private void removeIfUnlauncheable(String packageName, UserHandle user) {
        long appUserSerialNumber = mUserManager.getSerialNumberForUser(user);

        // Remove icons for all apps that match a package that perhaps became unlauncheable.
        // Remove icons for all apps that match a package that perhaps became unlauncheable.
        for(int i = sAppsModel.getAppCount() - 1; i >= 0; --i) {
        for(int i = sAppsModel.getAppCount() - 1; i >= 0; --i) {
            AppInfo appInfo = sAppsModel.getApp(i);
            AppInfo appInfo = sAppsModel.getApp(i);
            if (appInfo.getUserSerialNumber() != appUserSerialNumber) continue;
            if (!appInfo.getUser().equals(user)) continue;


            ComponentName appComponentName = appInfo.getComponentName();
            ComponentName appComponentName = appInfo.getComponentName();
            if (!appComponentName.getPackageName().equals(packageName)) continue;
            if (!appComponentName.getPackageName().equals(packageName)) continue;


            if (sAppsModel.buildAppLaunchIntent(appComponentName, user) != null) continue;
            if (sAppsModel.buildAppLaunchIntent(new AppInfo(appComponentName, user)) != null) {
                continue;
            }


            removeViewAt(i);
            removeViewAt(i);
            sAppsModel.removeApp(i);
            sAppsModel.removeApp(i);
@@ -206,10 +200,7 @@ class NavigationBarApps extends LinearLayout {
        transition.enableTransitionType(LayoutTransition.CHANGING);
        transition.enableTransitionType(LayoutTransition.CHANGING);
        parent.setLayoutTransition(transition);
        parent.setLayoutTransition(transition);


        int currentUserId = ActivityManager.getCurrentUser();
        sAppsModel.setCurrentUser(ActivityManager.getCurrentUser());
        mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(
                new UserHandle(currentUserId));
        sAppsModel.setCurrentUser(currentUserId);
        recreateAppButtons();
        recreateAppButtons();


        IntentFilter filter = new IntentFilter();
        IntentFilter filter = new IntentFilter();
@@ -244,7 +235,7 @@ class NavigationBarApps extends LinearLayout {
            button.setContentDescription(appLabel);
            button.setContentDescription(appLabel);


            // Load the icon asynchronously.
            // Load the icon asynchronously.
            new GetActivityIconTask(mPackageManager, button).execute(app.getComponentName());
            new GetActivityIconTask(mPackageManager, button).execute(app);
        }
        }
    }
    }


@@ -296,7 +287,10 @@ class NavigationBarApps extends LinearLayout {
    static void startAppDrag(ImageView icon, AppInfo appInfo) {
    static void startAppDrag(ImageView icon, AppInfo appInfo) {
        // The drag data is an Intent to launch the activity.
        // The drag data is an Intent to launch the activity.
        Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
        Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
        mainIntent.putExtra(EXTRA_PROFILE, appInfo.getUserSerialNumber());
        UserManager userManager =
                (UserManager) icon.getContext().getSystemService(Context.USER_SERVICE);
        long userSerialNumber = userManager.getSerialNumberForUser(appInfo.getUser());
        mainIntent.putExtra(EXTRA_PROFILE, userSerialNumber);
        ClipData dragData = ClipData.newIntent("", mainIntent);
        ClipData dragData = ClipData.newIntent("", mainIntent);
        // Use the ImageView to create the shadow.
        // Use the ImageView to create the shadow.
        View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
        View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
@@ -472,17 +466,17 @@ class NavigationBarApps extends LinearLayout {
        // Validate the received user serial number.
        // Validate the received user serial number.
        UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
        UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
        if (appUser == null) {
        if (appUser == null) {
            userSerialNumber = mCurrentUserSerialNumber;
            appUser = new UserHandle(ActivityManager.getCurrentUser());
        }
        }


        return new AppInfo(intent.getComponent(), userSerialNumber);
        return new AppInfo(intent.getComponent(), appUser);
    }
    }


    /** Updates the app at a given view index. */
    /** Updates the app at a given view index. */
    private void updateAppAt(int index, AppInfo appInfo) {
    private void updateAppAt(int index, AppInfo appInfo) {
        sAppsModel.setApp(index, appInfo);
        sAppsModel.setApp(index, appInfo);
        ImageView button = (ImageView) getChildAt(index);
        ImageView button = (ImageView) getChildAt(index);
        new GetActivityIconTask(mPackageManager, button).execute(appInfo.getComponentName());
        new GetActivityIconTask(mPackageManager, button).execute(appInfo);
    }
    }


    /** Removes the empty placeholder view and cleans up the data model. */
    /** Removes the empty placeholder view and cleans up the data model. */
@@ -540,20 +534,10 @@ class NavigationBarApps extends LinearLayout {
        @Override
        @Override
        public void onClick(View v) {
        public void onClick(View v) {
            AppInfo appInfo = sAppsModel.getApp(indexOfChild(v));
            AppInfo appInfo = sAppsModel.getApp(indexOfChild(v));
            ComponentName component = appInfo.getComponentName();
            Intent launchIntent = sAppsModel.buildAppLaunchIntent(appInfo);

            long appUserSerialNumber = appInfo.getUserSerialNumber();
            UserHandle appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
            if (appUser == null) {
                Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                Log.e(TAG, "Can't start activity " + component +
                        " because its user doesn't exist.");
                return;
            }

            Intent launchIntent = sAppsModel.buildAppLaunchIntent(component, appUser);
            if (launchIntent == null) {
            if (launchIntent == null) {
                Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                Toast.makeText(
                        getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                return;
                return;
            }
            }


@@ -568,18 +552,12 @@ class NavigationBarApps extends LinearLayout {
            Bundle optsBundle = opts.toBundle();
            Bundle optsBundle = opts.toBundle();
            launchIntent.setSourceBounds(sourceBounds);
            launchIntent.setSourceBounds(sourceBounds);


            mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
            mContext.startActivityAsUser(launchIntent, optsBundle, appInfo.getUser());
        }
        }
    }
    }


    private void onUserSwitched(int currentUserId) {
    private void onUserSwitched(int currentUserId) {
        final long newUserSerialNumber =
                mUserManager.getSerialNumberForUser(new UserHandle(currentUserId));

        if (newUserSerialNumber != mCurrentUserSerialNumber) {
            mCurrentUserSerialNumber = newUserSerialNumber;
        sAppsModel.setCurrentUser(currentUserId);
        sAppsModel.setCurrentUser(currentUserId);
        recreateAppButtons();
        recreateAppButtons();
    }
    }
}
}
}
+10 −7
Original line number Original line Diff line number Diff line
@@ -106,9 +106,10 @@ class NavigationBarAppsModel {
        return AppGlobals.getPackageManager();
        return AppGlobals.getPackageManager();
    }
    }


    // Returns a launch intent for a given component, or null if the component is unlauncheable.
    // Returns a launch intent for a given app info, or null if the app info is unlauncheable.
    public Intent buildAppLaunchIntent(ComponentName component, UserHandle appUser) {
    public Intent buildAppLaunchIntent(AppInfo appInfo) {
        int appUserId = appUser.getIdentifier();
        ComponentName component = appInfo.getComponentName();
        int appUserId = appInfo.getUser().getIdentifier();


        // This code is based on LauncherAppsService.startActivityAsUser code.
        // This code is based on LauncherAppsService.startActivityAsUser code.
        Intent launchIntent = new Intent(Intent.ACTION_MAIN);
        Intent launchIntent = new Intent(Intent.ACTION_MAIN);
@@ -250,7 +251,8 @@ class NavigationBarAppsModel {
            final AppInfo appInfo = mApps.get(i);
            final AppInfo appInfo = mApps.get(i);
            String componentNameString = appInfo.getComponentName().flattenToString();
            String componentNameString = appInfo.getComponentName().flattenToString();
            edit.putString(prefNameForApp(i), componentNameString);
            edit.putString(prefNameForApp(i), componentNameString);
            edit.putLong(prefUserForApp(i), appInfo.getUserSerialNumber());
            long userSerialNumber = mUserManager.getSerialNumberForUser(appInfo.getUser());
            edit.putLong(prefUserForApp(i), userSerialNumber);
        }
        }
        // Start an asynchronous disk write.
        // Start an asynchronous disk write.
        edit.apply();
        edit.apply();
@@ -278,8 +280,9 @@ class NavigationBarAppsModel {
                continue;
                continue;
            }
            }
            UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
            UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
            if (appUser != null && buildAppLaunchIntent(componentName, appUser) != null) {
            AppInfo appInfo = new AppInfo(componentName, appUser);
                mApps.add(new AppInfo(componentName, userSerialNumber));
            if (appUser != null && buildAppLaunchIntent(appInfo) != null) {
                mApps.add(appInfo);
            } else {
            } else {
                hadUnlauncheableApps = true;
                hadUnlauncheableApps = true;
            }
            }
@@ -301,7 +304,7 @@ class NavigationBarAppsModel {
            ResolveInfo ri = apps.get(i);
            ResolveInfo ri = apps.get(i);
            ComponentName componentName = new ComponentName(
            ComponentName componentName = new ComponentName(
                    ri.activityInfo.packageName, ri.activityInfo.name);
                    ri.activityInfo.packageName, ri.activityInfo.name);
            mApps.add(new AppInfo(componentName, mCurrentUserSerialNumber));
            mApps.add(new AppInfo(componentName, new UserHandle(mCurrentUserId)));
        }
        }


        savePrefs();
        savePrefs();
+37 −8
Original line number Original line Diff line number Diff line
@@ -25,11 +25,12 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.Handler;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
@@ -160,7 +161,8 @@ class NavigationBarRecents extends LinearLayout {


        button.setVisibility(View.VISIBLE);
        button.setVisibility(View.VISIBLE);
        // Load the activity icon on a background thread.
        // Load the activity icon on a background thread.
        new GetActivityIconTask(mPackageManager, button).execute(getRealActivityForTask(task));
        AppInfo app = new AppInfo(activityName, new UserHandle(task.userId));
        new GetActivityIconTask(mPackageManager, button).execute(app);


        final int taskPersistentId = task.persistentId;
        final int taskPersistentId = task.persistentId;
        button.setOnClickListener(new View.OnClickListener() {
        button.setOnClickListener(new View.OnClickListener() {
@@ -218,6 +220,35 @@ class NavigationBarRecents extends LinearLayout {
            mContext = context;
            mContext = context;
        }
        }


        private ComponentName getLaunchComponentForPackage(String packageName, int userId) {
            // This code is based on ApplicationPackageManager.getLaunchIntentForPackage.
            PackageManager packageManager = mContext.getPackageManager();

            // First see if the package has an INFO activity; the existence of
            // such an activity is implied to be the desired front-door for the
            // overall package (such as if it has multiple launcher entries).
            Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
            intentToResolve.addCategory(Intent.CATEGORY_INFO);
            intentToResolve.setPackage(packageName);
            List<ResolveInfo> ris = packageManager.queryIntentActivitiesAsUser(
                    intentToResolve, 0, userId);

            // Otherwise, try to find a main launcher activity.
            if (ris == null || ris.size() <= 0) {
                // reuse the intent instance
                intentToResolve.removeCategory(Intent.CATEGORY_INFO);
                intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
                intentToResolve.setPackage(packageName);
                ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
            }
            if (ris == null || ris.size() <= 0) {
                Log.e(TAG, "Failed to build intent for " + packageName);
                return null;
            }
            return new ComponentName(ris.get(0).activityInfo.packageName,
                    ris.get(0).activityInfo.name);
        }

        @Override
        @Override
        public boolean onLongClick(View v) {
        public boolean onLongClick(View v) {
            ImageView icon = (ImageView) v;
            ImageView icon = (ImageView) v;
@@ -226,17 +257,15 @@ class NavigationBarRecents extends LinearLayout {
            // for the task's package.
            // for the task's package.
            RecentTaskInfo task = (RecentTaskInfo) v.getTag();
            RecentTaskInfo task = (RecentTaskInfo) v.getTag();
            String packageName = getRealActivityForTask(task).getPackageName();
            String packageName = getRealActivityForTask(task).getPackageName();
            Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
            ComponentName component = getLaunchComponentForPackage(packageName, task.userId);
            if (intent == null) {
            if (component == null) {
                return false;
                return false;
            }
            }


            if (DEBUG) Slog.d(TAG, "Start drag with " + intent);
            if (DEBUG) Slog.d(TAG, "Start drag with " + component);


            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            long userSerialNumber = userManager.getSerialNumberForUser(new UserHandle(task.userId));
            NavigationBarApps.startAppDrag(
            NavigationBarApps.startAppDrag(
                    icon, new AppInfo(intent.getComponent(), userSerialNumber));
                    icon, new AppInfo(component, new UserHandle(task.userId)));
            return true;
            return true;
        }
        }
    }
    }
Loading