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

Commit abeaa2d0 authored by Kevin Jeon's avatar Kevin Jeon Committed by Android (Google) Code Review
Browse files

Merge changes I029a09e7,I8ff127ec into main

* changes:
  Move getResources() off of boot critical path
  Flag for moving VIMS init resource work
parents 65635381 57899a3e
Loading
Loading
Loading
Loading
+28 −11
Original line number Original line Diff line number Diff line
@@ -32,8 +32,10 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;


@@ -72,26 +74,39 @@ public final class SystemServerInitThreadPool implements Dumpable {
                "system-server-init-thread", Process.THREAD_PRIORITY_FOREGROUND);
                "system-server-init-thread", Process.THREAD_PRIORITY_FOREGROUND);
    }
    }


    private static SystemServerInitThreadPool getInstance() {
        SystemServerInitThreadPool instance;
        synchronized (LOCK) {
            Preconditions.checkState(sInstance != null, "Cannot get " + TAG
                    + " - it has been shut down");
            instance = sInstance;
        }
        return instance;
    }

    /**
    /**
     * Submits a task for execution.
     * Submits a task for execution and returns a Future that returns null on success.
     *
     *
     * @throws IllegalStateException if it hasn't been started or has been shut down already.
     * @throws IllegalStateException if it hasn't been started or has been shut down already.
     */
     */
    public static @NonNull Future<?> submit(@NonNull Runnable runnable,
    public static @NonNull Future<?> submit(@NonNull Runnable runnable,
            @NonNull String description) {
            @NonNull String description) {
        Objects.requireNonNull(description, "description cannot be null");
        Objects.requireNonNull(description, "description cannot be null");

        return getInstance().submitTask(Executors.callable(runnable), description);
        SystemServerInitThreadPool instance;
        synchronized (LOCK) {
            Preconditions.checkState(sInstance != null, "Cannot get " + TAG
                    + " - it has been shut down");
            instance = sInstance;
    }
    }


        return instance.submitTask(runnable, description);
    /**
     * Submits a task for execution and returns a Future containing the Callable's result.
     *
     * @throws IllegalStateException if it hasn't been started or has been shut down already.
     */
    public static <T> @NonNull Future<T> submit(@NonNull Callable<T> callable,
            @NonNull String description) {
        Objects.requireNonNull(description, "description cannot be null");
        return getInstance().submitTask(callable, description);
    }
    }


    private @NonNull Future<?> submitTask(@NonNull Runnable runnable,
    private <T> @NonNull Future<T> submitTask(@NonNull Callable<T> callable,
            @NonNull String description) {
            @NonNull String description) {
        synchronized (mPendingTasks) {
        synchronized (mPendingTasks) {
            Preconditions.checkState(!mShutDown, TAG + " already shut down");
            Preconditions.checkState(!mShutDown, TAG + " already shut down");
@@ -103,8 +118,9 @@ public final class SystemServerInitThreadPool implements Dumpable {
            if (IS_DEBUGGABLE) {
            if (IS_DEBUGGABLE) {
                Slog.d(TAG, "Started executing " + description);
                Slog.d(TAG, "Started executing " + description);
            }
            }
            T result = null;
            try {
            try {
                runnable.run();
                result = callable.call();
            } catch (RuntimeException e) {
            } catch (RuntimeException e) {
                Slog.e(TAG, "Failure in " + description + ": " + e, e);
                Slog.e(TAG, "Failure in " + description + ": " + e, e);
                traceLog.traceEnd();
                traceLog.traceEnd();
@@ -117,6 +133,7 @@ public final class SystemServerInitThreadPool implements Dumpable {
                Slog.d(TAG, "Finished executing " + description);
                Slog.d(TAG, "Finished executing " + description);
            }
            }
            traceLog.traceEnd();
            traceLog.traceEnd();
            return result;
        });
        });
    }
    }


+14 −3
Original line number Original line Diff line number Diff line
@@ -2017,6 +2017,13 @@ public final class SystemServer implements Dumpable {
            dpms = mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
            dpms = mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
            t.traceEnd();
            t.traceEnd();


            // If this flag is disabled, this service is started later.
            if (android.server.Flags.voiceinteractionmanagerserviceGetResourcesInInitThread()) {
                t.traceBegin("StartVoiceRecognitionManager");
                mSystemServiceManager.startService(VoiceInteractionManagerService.class);
                t.traceEnd();
            }

            t.traceBegin("StartStatusBarManagerService");
            t.traceBegin("StartStatusBarManagerService");
            try {
            try {
                statusBar = new StatusBarManagerService(context);
                statusBar = new StatusBarManagerService(context);
@@ -2528,9 +2535,13 @@ public final class SystemServer implements Dumpable {
            // FEATURE_VOICE_RECOGNIZERS feature is set, because it needs to take care
            // FEATURE_VOICE_RECOGNIZERS feature is set, because it needs to take care
            // of initializing various settings.  It will internally modify its behavior
            // of initializing various settings.  It will internally modify its behavior
            // based on that feature.
            // based on that feature.
            //
            // If this flag is enabled, this service will have begun initializing earlier.
            if (!android.server.Flags.voiceinteractionmanagerserviceGetResourcesInInitThread()) {
                t.traceBegin("StartVoiceRecognitionManager");
                t.traceBegin("StartVoiceRecognitionManager");
                mSystemServiceManager.startService(VoiceInteractionManagerService.class);
                mSystemServiceManager.startService(VoiceInteractionManagerService.class);
                t.traceEnd();
                t.traceEnd();
            }


            if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
            if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
                t.traceBegin("StartGestureLauncher");
                t.traceBegin("StartGestureLauncher");
+7 −0
Original line number Original line Diff line number Diff line
@@ -81,3 +81,10 @@ flag {
     bug: "396154116"
     bug: "396154116"
     is_exported: true
     is_exported: true
}
}

flag {
    name: "voiceinteractionmanagerservice_get_resources_in_init_thread"
    namespace: "system_performance"
    description: "Move VoiceInteractionManagerService getResources away from the boot critical path"
    bug: "406841419"
}
 No newline at end of file
+24 −3
Original line number Original line Diff line number Diff line
@@ -110,6 +110,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.SoundTriggerInternal;
import com.android.server.SoundTriggerInternal;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.SystemService;
import com.android.server.UiThread;
import com.android.server.UiThread;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerInternal;
@@ -127,8 +128,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Locale;
import java.util.Locale;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;


/**
/**
 * SystemService that publishes an IVoiceInteractionManagerService.
 * SystemService that publishes an IVoiceInteractionManagerService.
@@ -346,6 +348,13 @@ public class VoiceInteractionManagerService extends SystemService {
        public void onPreCreatedUserConversion(int userId) {
        public void onPreCreatedUserConversion(int userId) {
            Slogf.d(TAG, "onPreCreatedUserConversion(%d): calling onRoleHoldersChanged() again",
            Slogf.d(TAG, "onPreCreatedUserConversion(%d): calling onRoleHoldersChanged() again",
                    userId);
                    userId);
            if (mServiceStub.mRoleObserver == null) {
                try {
                    mServiceStub.mRoleObserver = mServiceStub.mRoleObserverFuture.get();
                } catch (ExecutionException | InterruptedException e) {
                    Slogf.wtf(TAG, "Unable to get role observer for user %d", userId);
                }
            }
            mServiceStub.mRoleObserver.onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT,
            mServiceStub.mRoleObserver.onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT,
                                                UserHandle.of(userId));
                                                UserHandle.of(userId));
        }
        }
@@ -416,11 +425,23 @@ public class VoiceInteractionManagerService extends SystemService {


        private final boolean mEnableService;
        private final boolean mEnableService;
        // TODO(b/226201975): remove reference once RoleService supports pre-created users
        // TODO(b/226201975): remove reference once RoleService supports pre-created users
        private final RoleObserver mRoleObserver;
        private final Future<RoleObserver> mRoleObserverFuture;
        private RoleObserver mRoleObserver;


        VoiceInteractionManagerServiceStub() {
        VoiceInteractionManagerServiceStub() {
            mEnableService = shouldEnableService(mContext);
            mEnableService = shouldEnableService(mContext);

            // If this flag is enabled, initialize in SystemServerInitThreadPool. This is intended
            // to avoid blocking system_server start on loading resources.
            if (android.server.Flags.voiceinteractionmanagerserviceGetResourcesInInitThread()) {
                mRoleObserver = null;
                mRoleObserverFuture = SystemServerInitThreadPool.submit(() -> {
                    return new RoleObserver(mContext.getMainExecutor());
                }, "RoleObserver");
            } else {
                mRoleObserver = new RoleObserver(mContext.getMainExecutor());
                mRoleObserver = new RoleObserver(mContext.getMainExecutor());
                mRoleObserverFuture = null;
            }
        }
        }


        void handleUserStop(String packageName, int userHandle) {
        void handleUserStop(String packageName, int userHandle) {