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

Commit eeea0d92 authored by Vadim Tryshev's avatar Vadim Tryshev Committed by Android (Google) Code Review
Browse files

Merge "Eliminating “-1” user serial numbers."

parents 344e838d e983fd88
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -22,11 +22,6 @@ import android.content.ComponentName;
 * Navigation bar app information.
 */
class AppInfo {
    /**
     * Unspecified serial number for the app's user.
     */
    public static final long USER_UNSPECIFIED = -1;

    private final ComponentName mComponentName;
    private final long mUserSerialNumber;

+20 −19
Original line number Diff line number Diff line
@@ -136,9 +136,10 @@ class NavigationBarApps extends LinearLayout {
        transition.enableTransitionType(LayoutTransition.CHANGING);
        parent.setLayoutTransition(transition);

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

        IntentFilter filter = new IntentFilter();
@@ -222,10 +223,7 @@ class NavigationBarApps extends LinearLayout {
    static void startAppDrag(ImageView icon, AppInfo appInfo) {
        // The drag data is an Intent to launch the activity.
        Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
        long userSerialNumber = appInfo.getUserSerialNumber();
        if (userSerialNumber != AppInfo.USER_UNSPECIFIED) {
            mainIntent.putExtra(EXTRA_PROFILE, userSerialNumber);
        }
        mainIntent.putExtra(EXTRA_PROFILE, appInfo.getUserSerialNumber());
        ClipData dragData = ClipData.newIntent("", mainIntent);
        // Use the ImageView to create the shadow.
        View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
@@ -396,7 +394,14 @@ class NavigationBarApps extends LinearLayout {
            return null;
        }

        long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, AppInfo.USER_UNSPECIFIED);
        long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, -1);

        // Validate the received user serial number.
        UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
        if (appUser == null) {
            userSerialNumber = mCurrentUserSerialNumber;
        }

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

@@ -466,18 +471,14 @@ class NavigationBarApps extends LinearLayout {

            long appUserSerialNumber = appInfo.getUserSerialNumber();

            UserHandle appUser = null;
            if (appUserSerialNumber != AppInfo.USER_UNSPECIFIED) {
                appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
            }

            int appUserId;
            if (appUser != null) {
                appUserId = appUser.getIdentifier();
            } else {
                appUserId = ActivityManager.getCurrentUser();
                appUser = new UserHandle(appUserId);
            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;
            }
            int appUserId = appUser.getIdentifier();

            // Play a scale-up animation while launching the activity.
            // TODO: Consider playing a different animation, or no animation, if the activity is
@@ -545,7 +546,7 @@ class NavigationBarApps extends LinearLayout {

        if (newUserSerialNumber != mCurrentUserSerialNumber) {
            mCurrentUserSerialNumber = newUserSerialNumber;
            sAppsModel.setCurrentUser(newUserSerialNumber);
            sAppsModel.setCurrentUser(currentUserId);
            recreateAppButtons();
        }
    }
+21 −25
Original line number Diff line number Diff line
@@ -16,18 +16,16 @@

package com.android.systemui.statusbar.phone;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -52,7 +50,7 @@ class NavigationBarAppsModel {
    private final static String VERSION_PREF = "version";

    // Current version number for preferences.
    private final static int CURRENT_VERSION = 2;
    private final static int CURRENT_VERSION = 3;

    // Preference name for the number of app icons.
    private final static String APP_COUNT_PREF = "app_count";
@@ -68,18 +66,23 @@ class NavigationBarAppsModel {
    // user serial of the third app of the logged-in user.
    private final static char USER_SEPARATOR = '|';

    final Context mContext;
    private final Context mContext;
    private final UserManager mUserManager;
    private final SharedPreferences mPrefs;

    // Apps are represented as an ordered list of app infos.
    private final List<AppInfo> mApps = new ArrayList<AppInfo>();

    // Id of the current user.
    private int mCurrentUserId = -1;

    // Serial number of the current user.
    private long mCurrentUserSerialNumber = AppInfo.USER_UNSPECIFIED;
    private long mCurrentUserSerialNumber = -1;

    public NavigationBarAppsModel(Context context) {
        mContext = context;
        mPrefs = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);

        int version = mPrefs.getInt(VERSION_PREF, -1);
        if (version != CURRENT_VERSION) {
@@ -94,8 +97,9 @@ class NavigationBarAppsModel {
    /**
     * Reinitializes the model for a new user.
     */
    public void setCurrentUser(long userSerialNumber) {
        mCurrentUserSerialNumber = userSerialNumber;
    public void setCurrentUser(int userId) {
        mCurrentUserId = userId;
        mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(new UserHandle(userId));

        mApps.clear();

@@ -115,11 +119,8 @@ class NavigationBarAppsModel {
     * Removes prefs for users that don't exist on the device.
     */
    private void removePrefsForDeletedUsers() {
        UserManager userManager =
                (UserManager) mContext.getSystemService(Context.USER_SERVICE);

        // Build a set of string representations of serial numbers of the device users.
        final List<UserInfo> users = userManager.getUsers();
        final List<UserInfo> users = mUserManager.getUsers();
        final int userCount = users.size();

        final Set<String> userSerials = new HashSet<String> ();
@@ -207,14 +208,14 @@ class NavigationBarAppsModel {
                continue;
            }
            ComponentName componentName = ComponentName.unflattenFromString(prefValue);
            long userSerialNumber = mPrefs.getLong(prefUserForApp(i), AppInfo.USER_UNSPECIFIED);
            mApps.add(new AppInfo(componentName, userSerialNumber));
            long userSerialNumber = mPrefs.getLong(prefUserForApp(i), -1);
            if (userSerialNumber == -1) {
                Slog.w(TAG, "Couldn't find pref " + prefUserForApp(i));
                // Couldn't find the saved state. Just skip this item.
                continue;
            }
            mApps.add(new AppInfo(componentName, userSerialNumber));
        }

    @VisibleForTesting
    protected int getCurrentUser() {
        return ActivityManager.getCurrentUser();
    }

    /** Adds the first few apps from the owner profile. Used for demo purposes. */
@@ -222,16 +223,15 @@ class NavigationBarAppsModel {
        // Get a list of all app activities.
        final Intent queryIntent = new Intent(Intent.ACTION_MAIN, null);
        queryIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        final int currentUser = getCurrentUser();

        final List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(
                queryIntent, 0 /* flags */, currentUser);
                queryIntent, 0 /* flags */, mCurrentUserId);
        final int appCount = apps.size();
        for (int i = 0; i < NUM_INITIAL_APPS && i < appCount; i++) {
            ResolveInfo ri = apps.get(i);
            ComponentName componentName = new ComponentName(
                    ri.activityInfo.packageName, ri.activityInfo.name);
            mApps.add(new AppInfo(componentName, AppInfo.USER_UNSPECIFIED));
            mApps.add(new AppInfo(componentName, mCurrentUserSerialNumber));
        }

        savePrefs();
@@ -239,10 +239,6 @@ class NavigationBarAppsModel {

    /** Returns a pref prefixed with the serial number of the current user. */
    private String userPrefixed(String pref) {
        if (mCurrentUserSerialNumber == AppInfo.USER_UNSPECIFIED) {
            throw new RuntimeException("Current user is not yet set");
        }

        return Long.toString(mCurrentUserSerialNumber) + USER_SEPARATOR + pref;
    }

+6 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -231,7 +232,11 @@ class NavigationBarRecents extends LinearLayout {
            }

            if (DEBUG) Slog.d(TAG, "Start drag with " + intent);
            NavigationBarApps.startAppDrag(icon, new AppInfo (intent.getComponent(), AppInfo.USER_UNSPECIFIED));

            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            long userSerialNumber = userManager.getSerialNumberForUser(new UserHandle(task.userId));
            NavigationBarApps.startAppDrag(
                    icon, new AppInfo(intent.getComponent(), userSerialNumber));
            return true;
        }
    }
+25 −31
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;

@@ -73,15 +74,12 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {

        when(mMockUserManager.getUsers()).thenReturn(new ArrayList<UserInfo>());
        // Assume the version pref is present and equal to the current version.
        when(mMockPrefs.getInt("version", -1)).thenReturn(2);
        when(mMockPrefs.getInt("version", -1)).thenReturn(3);
        when(mMockPrefs.edit()).thenReturn(mMockEdit);

        mModel = new NavigationBarAppsModel(context) {
            @Override
            protected int getCurrentUser() {
                return 0;
            }
        };
        when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(22L);

        mModel = new NavigationBarAppsModel(context);
    }

    /** Initializes the model from SharedPreferences for a few app activites. */
@@ -95,25 +93,23 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        when(mMockPrefs.getString("22|app_2", null)).thenReturn("package2/class2");
        when(mMockPrefs.getLong("22|app_user_2", -1)).thenReturn(239L);

        mModel.setCurrentUser(22L);
        mModel.setCurrentUser(2);
    }

    /** Tests initializing the model from SharedPreferences. */
    public void testInitializeFromPrefs() {
        initializeModelFromPrefs();
        assertEquals(3, mModel.getAppCount());
        assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
        assertEquals(-1L, mModel.getApp(0).getUserSerialNumber());
        assertEquals("package1/class1", mModel.getApp(1).getComponentName().flattenToString());
        assertEquals(45L, mModel.getApp(1).getUserSerialNumber());
        assertEquals("package2/class2", mModel.getApp(2).getComponentName().flattenToString());
        assertEquals(239L, mModel.getApp(2).getUserSerialNumber());
        assertEquals(2, mModel.getAppCount());
        assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
        assertEquals(45L, mModel.getApp(0).getUserSerialNumber());
        assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
        assertEquals(239L, mModel.getApp(1).getUserSerialNumber());
    }

    /** Tests initializing the model when the SharedPreferences aren't available. */
    public void testInitializeDefaultApps() {
        // Assume the user's app count pref isn't available.
        when(mMockPrefs.getInt("0|app_count", -1)).thenReturn(-1);
        when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);

        // Assume some installed activities.
        ActivityInfo ai1 = new ActivityInfo();
@@ -127,16 +123,16 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        ResolveInfo ri2 = new ResolveInfo();
        ri2.activityInfo = ai2;
        when(mMockPackageManager
                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), eq(0)))
                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), eq(2)))
                .thenReturn(Arrays.asList(ri1, ri2));

        // Setting the user should load the installed activities.
        mModel.setCurrentUser(0L);
        mModel.setCurrentUser(2);
        assertEquals(2, mModel.getAppCount());
        assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
        assertEquals(-1L, mModel.getApp(0).getUserSerialNumber());
        assertEquals(22L, mModel.getApp(0).getUserSerialNumber());
        assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
        assertEquals(-1L, mModel.getApp(1).getUserSerialNumber());
        assertEquals(22L, mModel.getApp(1).getUserSerialNumber());
    }

    /** Tests initializing the model if one of the prefs is missing. */
@@ -150,7 +146,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        when(mMockPrefs.getString("22|app_1", null)).thenReturn(null);

        // Initializing the model should load from prefs and skip the missing one.
        mModel.setCurrentUser(22L);
        mModel.setCurrentUser(2);
        assertEquals(1, mModel.getAppCount());
        assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
        assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
@@ -161,13 +157,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        initializeModelFromPrefs();

        mModel.savePrefs();
        verify(mMockEdit).putInt("22|app_count", 3);
        verify(mMockEdit).putString("22|app_0", "package0/class0");
        verify(mMockEdit).putLong("22|app_user_0", -1L);
        verify(mMockEdit).putString("22|app_1", "package1/class1");
        verify(mMockEdit).putLong("22|app_user_1", 45L);
        verify(mMockEdit).putString("22|app_2", "package2/class2");
        verify(mMockEdit).putLong("22|app_user_2", 239L);
        verify(mMockEdit).putInt("22|app_count", 2);
        verify(mMockEdit).putString("22|app_0", "package1/class1");
        verify(mMockEdit).putLong("22|app_user_0", 45L);
        verify(mMockEdit).putString("22|app_1", "package2/class2");
        verify(mMockEdit).putLong("22|app_user_1", 239L);
        verify(mMockEdit).apply();
        verifyNoMoreInteractions(mMockEdit);
    }
@@ -179,7 +173,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {

        new NavigationBarAppsModel(getContext());
        verify(mMockEdit).clear();
        verify(mMockEdit).putInt("version", 2);
        verify(mMockEdit).putInt("version", 3);
        verify(mMockEdit).apply();
        verifyNoMoreInteractions(mMockEdit);
    }
@@ -200,7 +194,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {

        // Assume the user's app count pref isn't available. This will trigger clearing deleted
        // users' prefs.
        when(mMockPrefs.getInt("0|app_count", -1)).thenReturn(-1);
        when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);

        final Map allPrefs = new HashMap<String, Object>();
        allPrefs.put("version", null);
@@ -212,7 +206,7 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        when(mMockPrefs.getAll()).thenReturn(allPrefs);

        // Setting the user should remove prefs for deleted users.
        mModel.setCurrentUser(0L);
        mModel.setCurrentUser(2);
        verify(mMockEdit).remove("some_strange_pref");
        verify(mMockEdit).remove("");
        verify(mMockEdit).remove("|");