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

Commit 620c61dc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Initial implementation of system service optimizations for different type of users."

parents 736e4ceb e5434c30
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -16,11 +16,17 @@

package android.content.pm;

import android.annotation.IntDef;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.DebugUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Per-user information.
@@ -119,10 +125,31 @@ public class UserInfo implements Parcelable {
     */
    public static final int FLAG_SYSTEM = 0x00000800;

    /**
     * @hide
     */
    @IntDef(flag = true, prefix = "FLAG_", value = {
            FLAG_PRIMARY,
            FLAG_ADMIN,
            FLAG_GUEST,
            FLAG_RESTRICTED,
            FLAG_INITIALIZED,
            FLAG_MANAGED_PROFILE,
            FLAG_DISABLED,
            FLAG_QUIET_MODE,
            FLAG_EPHEMERAL,
            FLAG_DEMO,
            FLAG_FULL,
            FLAG_SYSTEM
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface UserInfoFlag {
    }

    public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;

    @UnsupportedAppUsage
    public int id;
    public @UserIdInt int id;
    @UnsupportedAppUsage
    public int serialNumber;
    @UnsupportedAppUsage
@@ -130,7 +157,7 @@ public class UserInfo implements Parcelable {
    @UnsupportedAppUsage
    public String iconPath;
    @UnsupportedAppUsage
    public int flags;
    public @UserInfoFlag int flags;
    @UnsupportedAppUsage
    public long creationTime;
    @UnsupportedAppUsage
@@ -214,6 +241,10 @@ public class UserInfo implements Parcelable {
        return (flags & FLAG_DEMO) == FLAG_DEMO;
    }

    public boolean isFull() {
        return (flags & FLAG_FULL) == FLAG_FULL;
    }

    /**
     * Returns true if the user is a split system user.
     * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
@@ -290,13 +321,23 @@ public class UserInfo implements Parcelable {

    @Override
    public String toString() {
        // NOTE:  do not change this string, it's used by 'pm list users', which in turn is
        // used and parsed by TestDevice. In other words, if you change it, you'd have to change
        // TestDevice, TestDeviceTest, and possibly others....
        return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}";
    }

    /** @hide */
    public static String flagsToString(int flags) {
        return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int parcelableFlags) {
        dest.writeInt(id);
        dest.writeString(name);
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package android.os;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
@@ -224,4 +225,10 @@ public abstract class UserManagerInternal {

    /** @return a specific user restriction that's in effect currently. */
    public abstract boolean hasUserRestriction(String restriction, int userId);

    /**
     * Gets an {@link UserInfo} for the given {@code userId}, or {@code null} if not
     * found.
     */
    public abstract @Nullable UserInfo getUserInfo(@UserIdInt int userId);
}
+68 −11
Original line number Diff line number Diff line
@@ -18,12 +18,17 @@ package com.android.server;

import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.UserManager;

import com.android.server.pm.UserManagerService;

/**
 * The base class for services running in the system process. Override and implement
 * the lifecycle event callback methods as needed.
@@ -144,12 +149,30 @@ public abstract class SystemService {
     */
    public void onBootPhase(int phase) {}

    /**
     * @deprecated subclasses should extend {@link #onStartUser(int, int)} instead (which by default
     * calls this method).
     */
    @Deprecated
    public void onStartUser(@UserIdInt int userHandle) {}

    /**
     * Called when a new user is starting, for system services to initialize any per-user
     * state they maintain for running users.
     * @param userHandle The identifier of the user.
     *
     * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
     * referenced by {@link UserManagerService} and hence should not be modified.
     */
    public void onStartUser(@NonNull UserInfo userInfo) {
        onStartUser(userInfo.id);
    }

    /**
     * @deprecated subclasses should extend {@link #onUnlockUser(int, int)} instead (which by
     * default calls this method).
     */
    public void onStartUser(int userHandle) {}
    @Deprecated
    public void onUnlockUser(@UserIdInt int userHandle) {}

    /**
     * Called when an existing user is in the process of being unlocked. This
@@ -163,17 +186,38 @@ public abstract class SystemService {
     * {@link UserManager#isUserUnlockingOrUnlocked(int)} to handle both of
     * these states.
     *
     * @param userHandle The identifier of the user.
     * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
     * referenced by {@link UserManagerService} and hence should not be modified.
     */
    public void onUnlockUser(int userHandle) {}
    public void onUnlockUser(@NonNull UserInfo userInfo) {
        onUnlockUser(userInfo.id);
    }

    /**
     * @deprecated subclasses should extend {@link #onSwitchUser(int, int)} instead (which by
     * default calls this method).
     */
    @Deprecated
    public void onSwitchUser(@UserIdInt int userHandle) {}

    /**
     * Called when switching to a different foreground user, for system services that have
     * special behavior for whichever user is currently in the foreground.  This is called
     * before any application processes are aware of the new user.
     * @param userHandle The identifier of the user.
     *
     * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
     * referenced by {@link UserManagerService} and hence should not be modified.
     */
    public void onSwitchUser(@NonNull UserInfo userInfo) {
        onSwitchUser(userInfo.id);
    }

    /**
     * @deprecated subclasses should extend {@link #onStopUser(int, int)} instead (which by default
     * calls this method).
     */
    public void onSwitchUser(int userHandle) {}
    @Deprecated
    public void onStopUser(@UserIdInt int userHandle) {}

    /**
     * Called when an existing user is stopping, for system services to finalize any per-user
@@ -183,9 +227,19 @@ public abstract class SystemService {
     *
     * <p>NOTE: This is the last callback where the callee may access the target user's CE storage.
     *
     * @param userHandle The identifier of the user.
     * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
     * referenced by {@link UserManagerService} and hence should not be modified.
     */
    public void onStopUser(int userHandle) {}
    public void onStopUser(@NonNull UserInfo userInfo) {
        onStopUser(userInfo.id);
    }

    /**
     * @deprecated subclasses should extend {@link #onCleanupUser(int, int)} instead (which by
     * default calls this method).
     */
    @Deprecated
    public void onCleanupUser(@UserIdInt int userHandle) {}

    /**
     * Called when an existing user is stopping, for system services to finalize any per-user
@@ -193,11 +247,14 @@ public abstract class SystemService {
     * teardown of the user is complete.
     *
     * <p>NOTE: When this callback is called, the CE storage for the target user may not be
     * accessible already.  Use {@link #onStopUser} instead if you need to access the CE storage.
     * accessible already.  Use {@link #onCleanupUser} instead if you need to access the CE storage.
     *
     * @param userHandle The identifier of the user.
     * @param userInfo The information about the user. <b>NOTE: </b> this is a "live" object
     * referenced by {@link UserManagerService} and hence should not be modified.
     */
    public void onCleanupUser(int userHandle) {}
    public void onCleanupUser(@NonNull UserInfo userInfo) {
        onCleanupUser(userInfo.id);
    }

    /**
     * Publish the service so it is accessible to other services and apps.
+33 −6
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package com.android.server;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserManagerInternal;
import android.util.Slog;

import com.android.server.utils.TimingsTraceAndSlog;
@@ -53,6 +55,8 @@ public class SystemServiceManager {

    private int mCurrentPhase = -1;

    private UserManagerInternal mUserManagerInternal;

    SystemServiceManager(Context context) {
        mContext = context;
    }
@@ -186,12 +190,31 @@ public class SystemServiceManager {
        return mCurrentPhase >= SystemService.PHASE_BOOT_COMPLETED;
    }

    /**
     * Called at the beginning of {@code ActivityManagerService.systemReady()}.
     */
    public void preSystemReady() {
        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
    }

    private @NonNull UserInfo getUserInfo(@UserIdInt int userHandle) {
        if (mUserManagerInternal == null) {
            throw new IllegalStateException("mUserManagerInternal not set yet");
        }
        final UserInfo userInfo = mUserManagerInternal.getUserInfo(userHandle);
        if (userInfo == null) {
            throw new IllegalStateException("No UserInfo for " + userHandle);
        }
        return userInfo;
    }

    /**
     * Starts the given user.
     */
    public void startUser(@NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
    public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
        t.traceBegin("ssm.startUser-" + userHandle);
        Slog.i(TAG, "Calling onStartUser u" + userHandle);
        final UserInfo userInfo = getUserInfo(userHandle);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
@@ -199,7 +222,7 @@ public class SystemServiceManager {
            t.traceBegin("onStartUser-" + userHandle + " " + serviceName);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onStartUser(userHandle);
                service.onStartUser(userInfo);
            } catch (Exception ex) {
                Slog.wtf(TAG, "Failure reporting start of user " + userHandle
                        + " to service " + service.getClass().getName(), ex);
@@ -217,6 +240,7 @@ public class SystemServiceManager {
        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
        t.traceBegin("ssm.unlockUser-" + userHandle);
        Slog.i(TAG, "Calling onUnlockUser u" + userHandle);
        final UserInfo userInfo = getUserInfo(userHandle);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
@@ -224,7 +248,7 @@ public class SystemServiceManager {
            t.traceBegin("onUnlockUser-" + userHandle + " " + serviceName);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onUnlockUser(userHandle);
                service.onUnlockUser(userInfo);
            } catch (Exception ex) {
                Slog.wtf(TAG, "Failure reporting unlock of user " + userHandle
                        + " to service " + serviceName, ex);
@@ -242,6 +266,7 @@ public class SystemServiceManager {
        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
        t.traceBegin("ssm.switchUser-" + userHandle);
        Slog.i(TAG, "Calling switchUser u" + userHandle);
        final UserInfo userInfo = getUserInfo(userHandle);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
@@ -249,7 +274,7 @@ public class SystemServiceManager {
            t.traceBegin("onSwitchUser-" + userHandle + " " + serviceName);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onSwitchUser(userHandle);
                service.onSwitchUser(userInfo);
            } catch (Exception ex) {
                Slog.wtf(TAG, "Failure reporting switch of user " + userHandle
                        + " to service " + serviceName, ex);
@@ -267,6 +292,7 @@ public class SystemServiceManager {
        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
        t.traceBegin("ssm.stopUser-" + userHandle);
        Slog.i(TAG, "Calling onStopUser u" + userHandle);
        final UserInfo userInfo = getUserInfo(userHandle);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
@@ -274,7 +300,7 @@ public class SystemServiceManager {
            t.traceBegin("onStopUser-" + userHandle + " " + serviceName);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onStopUser(userHandle);
                service.onStopUser(userInfo);
            } catch (Exception ex) {
                Slog.wtf(TAG, "Failure reporting stop of user " + userHandle
                        + " to service " + serviceName, ex);
@@ -292,6 +318,7 @@ public class SystemServiceManager {
        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
        t.traceBegin("ssm.cleanupUser-" + userHandle);
        Slog.i(TAG, "Calling onCleanupUser u" + userHandle);
        final UserInfo userInfo = getUserInfo(userHandle);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
@@ -299,7 +326,7 @@ public class SystemServiceManager {
            t.traceBegin("onCleanupUser-" + userHandle + " " + serviceName);
            long time = SystemClock.elapsedRealtime();
            try {
                service.onCleanupUser(userHandle);
                service.onCleanupUser(userInfo);
            } catch (Exception ex) {
                Slog.wtf(TAG, "Failure reporting cleanup of user " + userHandle
                        + " to service " + serviceName, ex);
+1 −0
Original line number Diff line number Diff line
@@ -8990,6 +8990,7 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
        t.traceBegin("PhaseActivityManagerReady");
        mSystemServiceManager.preSystemReady();
        synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
Loading