diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java
index 393f368..788bfe4 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/PrefetchController.java
@@ -25,6 +25,7 @@
 import android.annotation.CurrentTimeMillisLong;
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
+import android.app.job.JobInfo;
 import android.app.usage.UsageStatsManagerInternal;
 import android.app.usage.UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener;
 import android.content.Context;
@@ -38,6 +39,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArrayMap;
+import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
@@ -71,6 +73,9 @@
      */
     @GuardedBy("mLock")
     private final SparseArrayMap<String, Long> mEstimatedLaunchTimes = new SparseArrayMap<>();
+    /** Cached list of UIDs in the TOP state. */
+    @GuardedBy("mLock")
+    private final SparseBooleanArray mTopUids = new SparseBooleanArray();
     private final ThresholdAlarmListener mThresholdAlarmListener;
 
     /**
@@ -98,6 +103,7 @@
 
     private static final int MSG_RETRIEVE_ESTIMATED_LAUNCH_TIME = 0;
     private static final int MSG_PROCESS_UPDATED_ESTIMATED_LAUNCH_TIME = 1;
+    private static final int MSG_PROCESS_TOP_STATE_CHANGE = 2;
 
     public PrefetchController(JobSchedulerService service) {
         super(service);
@@ -165,6 +171,22 @@
         mThresholdAlarmListener.removeAlarmsForUserId(userId);
     }
 
+    @GuardedBy("mLock")
+    @Override
+    public void onUidBiasChangedLocked(int uid, int newBias) {
+        final boolean isNowTop = newBias == JobInfo.BIAS_TOP_APP;
+        final boolean wasTop = mTopUids.get(uid);
+        if (isNowTop) {
+            mTopUids.put(uid, true);
+        } else {
+            // Delete entries of non-top apps so the set doesn't get too large.
+            mTopUids.delete(uid);
+        }
+        if (isNowTop != wasTop) {
+            mHandler.obtainMessage(MSG_PROCESS_TOP_STATE_CHANGE, uid, 0).sendToTarget();
+        }
+    }
+
     /** Return the app's next estimated launch time. */
     @GuardedBy("mLock")
     @CurrentTimeMillisLong
@@ -205,6 +227,35 @@
         return changed;
     }
 
+    private void maybeUpdateConstraintForUid(int uid) {
+        synchronized (mLock) {
+            final ArraySet<String> pkgs = mService.getPackagesForUidLocked(uid);
+            if (pkgs == null) {
+                return;
+            }
+            final int userId = UserHandle.getUserId(uid);
+            final ArraySet<JobStatus> changedJobs = new ArraySet<>();
+            final long now = sSystemClock.millis();
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            for (int p = pkgs.size() - 1; p >= 0; --p) {
+                final String pkgName = pkgs.valueAt(p);
+                final ArraySet<JobStatus> jobs = mTrackedJobs.get(userId, pkgName);
+                if (jobs == null) {
+                    continue;
+                }
+                for (int i = 0; i < jobs.size(); i++) {
+                    final JobStatus js = jobs.valueAt(i);
+                    if (updateConstraintLocked(js, now, nowElapsed)) {
+                        changedJobs.add(js);
+                    }
+                }
+            }
+            if (changedJobs.size() > 0) {
+                mStateChangedListener.onControllerStateChanged(changedJobs);
+            }
+        }
+    }
+
     private void processUpdatedEstimatedLaunchTime(int userId, @NonNull String pkgName,
             @CurrentTimeMillisLong long newEstimatedLaunchTime) {
         if (DEBUG) {
@@ -244,9 +295,18 @@
     @GuardedBy("mLock")
     private boolean updateConstraintLocked(@NonNull JobStatus jobStatus,
             @CurrentTimeMillisLong long now, @ElapsedRealtimeLong long nowElapsed) {
-        return jobStatus.setPrefetchConstraintSatisfied(nowElapsed,
-                willBeLaunchedSoonLocked(
-                        jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), now));
+        // Mark a prefetch constraint as satisfied in the following scenarios:
+        //   1. The app is not open but it will be launched soon
+        //   2. The app is open and the job is already running (so we let it finish)
+        final boolean appIsOpen = mTopUids.get(jobStatus.getSourceUid());
+        final boolean satisfied;
+        if (!appIsOpen) {
+            satisfied = willBeLaunchedSoonLocked(
+                    jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), now);
+        } else {
+            satisfied = mService.isCurrentlyRunningLocked(jobStatus);
+        }
+        return jobStatus.setPrefetchConstraintSatisfied(nowElapsed, satisfied);
     }
 
     @GuardedBy("mLock")
@@ -399,6 +459,11 @@
                     processUpdatedEstimatedLaunchTime(args.argi1, (String) args.arg1, args.argl1);
                     args.recycle();
                     break;
+
+                case MSG_PROCESS_TOP_STATE_CHANGE:
+                    final int uid = msg.arg1;
+                    maybeUpdateConstraintForUid(uid);
+                    break;
             }
         }
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
index e5b2d14..b17ff53b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
@@ -47,8 +47,11 @@
 import android.content.Context;
 import android.content.pm.ServiceInfo;
 import android.os.Looper;
+import android.os.Process;
 import android.os.SystemClock;
 import android.provider.DeviceConfig;
+import android.util.ArraySet;
+import android.util.SparseArray;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -85,6 +88,7 @@
     private PcConstants mPcConstants;
     private DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder;
     private EstimatedLaunchTimeChangedListener mEstimatedLaunchTimeChangedListener;
+    private SparseArray<ArraySet<String>> mPackagesForUid = new SparseArray<>();
 
     private MockitoSession mMockingSession;
     @Mock
@@ -125,6 +129,10 @@
                         -> mDeviceConfigPropertiesBuilder.build())
                 .when(() -> DeviceConfig.getProperties(
                         eq(DeviceConfig.NAMESPACE_JOB_SCHEDULER), ArgumentMatchers.<String>any()));
+        // Used in PrefetchController.maybeUpdateConstraintForUid
+        when(mJobSchedulerService.getPackagesForUidLocked(anyInt()))
+                .thenAnswer(invocationOnMock
+                        -> mPackagesForUid.get(invocationOnMock.getArgument(0)));
 
         // Freeze the clocks at 24 hours after this moment in time. Several tests create sessions
         // in the past, and PrefetchController sometimes floors values at 0, so if the test time
@@ -146,6 +154,8 @@
         mPrefetchController = new PrefetchController(mJobSchedulerService);
         mPcConstants = mPrefetchController.getPcConstants();
 
+        setUidBias(Process.myUid(), JobInfo.BIAS_DEFAULT);
+
         verify(mUsageStatsManagerInternal)
                 .registerLaunchTimeChangedListener(eltListenerCaptor.capture());
         mEstimatedLaunchTimeChangedListener = eltListenerCaptor.getValue();
@@ -185,6 +195,12 @@
         return Clock.offset(clock, Duration.ofMillis(incrementMs));
     }
 
+    private void setUidBias(int uid, int bias) {
+        synchronized (mPrefetchController.mLock) {
+            mPrefetchController.onUidBiasChangedLocked(uid, bias);
+        }
+    }
+
     private void setDeviceConfigLong(String key, long val) {
         mDeviceConfigPropertiesBuilder.setLong(key, val);
         synchronized (mPrefetchController.mLock) {
@@ -196,6 +212,12 @@
 
     private void trackJobs(JobStatus... jobs) {
         for (JobStatus job : jobs) {
+            ArraySet<String> pkgs = mPackagesForUid.get(job.getSourceUid());
+            if (pkgs == null) {
+                pkgs = new ArraySet<>();
+                mPackagesForUid.put(job.getSourceUid(), pkgs);
+            }
+            pkgs.add(job.getSourcePackageName());
             synchronized (mPrefetchController.mLock) {
                 mPrefetchController.maybeStartTrackingJobLocked(job, null);
             }
@@ -269,10 +291,46 @@
         trackJobs(job);
         verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS))
                 .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID);
+        verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS)).onControllerStateChanged(any());
         assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
     }
 
     @Test
+    public void testConstraintSatisfiedWhenTop() {
+        final JobStatus jobPending = createJobStatus("testConstraintSatisfiedWhenTop", 1);
+        final JobStatus jobRunning = createJobStatus("testConstraintSatisfiedWhenTop", 2);
+        final int uid = jobPending.getSourceUid();
+
+        when(mJobSchedulerService.isCurrentlyRunningLocked(jobPending)).thenReturn(false);
+        when(mJobSchedulerService.isCurrentlyRunningLocked(jobRunning)).thenReturn(true);
+
+        InOrder inOrder = inOrder(mJobSchedulerService);
+
+        when(mUsageStatsManagerInternal
+                .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID))
+                .thenReturn(sSystemClock.millis() + 10 * MINUTE_IN_MILLIS);
+        trackJobs(jobPending, jobRunning);
+        verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS))
+                .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID);
+        inOrder.verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS))
+                .onControllerStateChanged(any());
+        assertTrue(jobPending.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+        assertTrue(jobRunning.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+        setUidBias(uid, JobInfo.BIAS_TOP_APP);
+        // Processing happens on the handler, so wait until we're sure the change has been processed
+        inOrder.verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS))
+                .onControllerStateChanged(any());
+        // Already running job should continue but pending job must wait.
+        assertFalse(jobPending.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+        assertTrue(jobRunning.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+        setUidBias(uid, JobInfo.BIAS_DEFAULT);
+        inOrder.verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS))
+                .onControllerStateChanged(any());
+        assertTrue(jobPending.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+        assertTrue(jobRunning.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
+    }
+
+    @Test
     public void testEstimatedLaunchTimeChangedToLate() {
         setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS);
         when(mUsageStatsManagerInternal
@@ -285,6 +343,7 @@
         trackJobs(jobStatus);
         inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS))
                 .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID);
+        verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS)).onControllerStateChanged(any());
         assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
 
         mEstimatedLaunchTimeChangedListener.onEstimatedLaunchTimeChanged(SOURCE_USER_ID,
@@ -315,6 +374,7 @@
 
         inOrder.verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS).times(0))
                 .getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID);
+        verify(mJobSchedulerService, timeout(DEFAULT_WAIT_MS)).onControllerStateChanged(any());
         assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
     }
 }
