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

Commit c5ca82e2 authored by Kai Li's avatar Kai Li Committed by Android (Google) Code Review
Browse files

Merge "Warm up Content Capture's BackgroundThread in ActivityThread." into main

parents 1271d1cd 7d21811b
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -238,6 +238,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.ApplicationSharedMemory;
import com.android.internal.os.ApplicationSharedMemory;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.DebugStore;
import com.android.internal.os.DebugStore;
@@ -7794,6 +7795,16 @@ public final class ActivityThread extends ClientTransactionHandler


            // Propagate Content Capture options
            // Propagate Content Capture options
            app.setContentCaptureOptions(data.contentCaptureOptions);
            app.setContentCaptureOptions(data.contentCaptureOptions);
            if (android.view.contentcapture.flags.Flags.warmUpBackgroundThreadForContentCapture()
                    && data.contentCaptureOptions != null) {
                if (data.contentCaptureOptions.enableReceiver
                        && !data.contentCaptureOptions.lite) {
                    // Warm up the background thread when:
                    // 1) app is launched with content capture enabled, and
                    // 2) the app is NOT launched with content capture lite enabled.
                    BackgroundThread.startIfNeeded();
                }
            }
            sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);
            sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);


            mInitialApplication = app;
            mInitialApplication = app;
+10 −0
Original line number Original line Diff line number Diff line
@@ -34,3 +34,13 @@ flag {
        purpose: PURPOSE_BUGFIX
        purpose: PURPOSE_BUGFIX
    }
    }
}
}

flag {
    name: "warm_up_background_thread_for_content_capture"
    namespace: "system_performance"
    description: "Feature flag to warm up the background thread for content capture"
    bug: "408273598"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+20 −4
Original line number Original line Diff line number Diff line
@@ -40,10 +40,17 @@ public final class BackgroundThread extends HandlerThread {
        super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
        super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
    }
    }


    private static void ensureThreadLocked() {
    private static void ensureThreadStartedLocked() {
        if (sInstance == null) {
        if (sInstance == null) {
            sInstance = new BackgroundThread();
            sInstance = new BackgroundThread();
            sInstance.start();
            sInstance.start();
        }
    }

    private static void ensureThreadReadyLocked() {
        ensureThreadStartedLocked();
        if (sHandler == null) {
            // This will block until the looper is initialized on the background thread.
            final Looper looper = sInstance.getLooper();
            final Looper looper = sInstance.getLooper();
            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
            looper.setSlowLogThresholdMs(
            looper.setSlowLogThresholdMs(
@@ -54,10 +61,19 @@ public final class BackgroundThread extends HandlerThread {
        }
        }
    }
    }


    /**
     * Starts the thread if needed, but doesn't block on thread initialization or readiness.
     */
    public static void startIfNeeded() {
        synchronized (BackgroundThread.class) {
            ensureThreadStartedLocked();
        }
    }

    @NonNull
    @NonNull
    public static BackgroundThread get() {
    public static BackgroundThread get() {
        synchronized (BackgroundThread.class) {
        synchronized (BackgroundThread.class) {
            ensureThreadLocked();
            ensureThreadReadyLocked();
            return sInstance;
            return sInstance;
        }
        }
    }
    }
@@ -65,7 +81,7 @@ public final class BackgroundThread extends HandlerThread {
    @NonNull
    @NonNull
    public static Handler getHandler() {
    public static Handler getHandler() {
        synchronized (BackgroundThread.class) {
        synchronized (BackgroundThread.class) {
            ensureThreadLocked();
            ensureThreadReadyLocked();
            return sHandler;
            return sHandler;
        }
        }
    }
    }
@@ -73,7 +89,7 @@ public final class BackgroundThread extends HandlerThread {
    @NonNull
    @NonNull
    public static Executor getExecutor() {
    public static Executor getExecutor() {
        synchronized (BackgroundThread.class) {
        synchronized (BackgroundThread.class) {
            ensureThreadLocked();
            ensureThreadReadyLocked();
            return sHandlerExecutor;
            return sHandlerExecutor;
        }
        }
    }
    }
+18 −0
Original line number Original line Diff line number Diff line
@@ -51,4 +51,22 @@ public class BackgroundThreadTest {
        boolean success = done.block(5000);
        boolean success = done.block(5000);
        assertThat(success).isTrue();
        assertThat(success).isTrue();
    }
    }

    @Test
    public void test_startIfNeeded() {
        BackgroundThread.startIfNeeded();

        BackgroundThread thread = BackgroundThread.get();
        assertThat(thread.getLooper()).isNotEqualTo(Looper.getMainLooper());
    }

    @Test
    public void test_startIfNeededMultipleTimes() {
        BackgroundThread.startIfNeeded();
        BackgroundThread.startIfNeeded();
        BackgroundThread.startIfNeeded();

        BackgroundThread thread = BackgroundThread.get();
        assertThat(thread.getLooper()).isNotEqualTo(Looper.getMainLooper());
    }
}
}