Merge "Let prefetch jobs run for apps with active widgets."
This commit is contained in:
committed by
Android (Google) Code Review
commit
1409c8350b
@@ -28,6 +28,7 @@ import android.annotation.NonNull;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
import android.app.usage.UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -63,6 +64,13 @@ public class PrefetchController extends StateController {
|
||||
private final PcConstants mPcConstants;
|
||||
private final PcHandler mHandler;
|
||||
|
||||
// Note: when determining prefetch bit satisfaction, we mark the bit as satisfied for apps with
|
||||
// active widgets assuming that any prefetch jobs are being used for the widget. However, we
|
||||
// don't have a callback telling us when widget status changes, which is incongruent with the
|
||||
// aforementioned assumption. This inconsistency _should_ be fine since any jobs scheduled
|
||||
// before the widget is activated are definitely not for the widget and don't have to be updated
|
||||
// to "satisfied=true".
|
||||
private AppWidgetManager mAppWidgetManager;
|
||||
private final UsageStatsManagerInternal mUsageStatsManagerInternal;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -117,6 +125,11 @@ public class PrefetchController extends StateController {
|
||||
.registerLaunchTimeChangedListener(mEstimatedLaunchTimeChangedListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemServicesReady() {
|
||||
mAppWidgetManager = mContext.getSystemService(AppWidgetManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@GuardedBy("mLock")
|
||||
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
|
||||
@@ -298,11 +311,23 @@ public class PrefetchController extends StateController {
|
||||
// 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)
|
||||
// 3. The app is not open but has an active widget (we can't tell if a widget displays
|
||||
// status/data, so this assumes the prefetch job is to update the data displayed on
|
||||
// the widget).
|
||||
final boolean appIsOpen = mTopUids.get(jobStatus.getSourceUid());
|
||||
final boolean satisfied;
|
||||
if (!appIsOpen) {
|
||||
satisfied = willBeLaunchedSoonLocked(
|
||||
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), now);
|
||||
final int userId = jobStatus.getSourceUserId();
|
||||
final String pkgName = jobStatus.getSourcePackageName();
|
||||
satisfied = willBeLaunchedSoonLocked(userId, pkgName, now)
|
||||
// At the time of implementation, isBoundWidgetPackage() results in a process ID
|
||||
// check and then a lookup into a map. Calling the method here every time
|
||||
// is based on the assumption that widgets won't change often and
|
||||
// AppWidgetManager won't be a bottleneck, so having a local cache won't provide
|
||||
// huge performance gains. If anything changes, we should reconsider having a
|
||||
// local cache.
|
||||
|| (mAppWidgetManager != null
|
||||
&& mAppWidgetManager.isBoundWidgetPackage(pkgName, userId));
|
||||
} else {
|
||||
satisfied = mService.isCurrentlyRunningLocked(jobStatus);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.app.AlarmManager;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
import android.app.usage.UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
@@ -168,12 +169,15 @@ public class PrefetchControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private JobStatus createJobStatus(String testTag, int jobId) {
|
||||
JobInfo jobInfo = new JobInfo.Builder(jobId,
|
||||
private JobInfo createJobInfo(int jobId) {
|
||||
return new JobInfo.Builder(jobId,
|
||||
new ComponentName(mContext, "TestPrefetchJobService"))
|
||||
.setPrefetch(true)
|
||||
.build();
|
||||
return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo);
|
||||
}
|
||||
|
||||
private JobStatus createJobStatus(String testTag, int jobId) {
|
||||
return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, createJobInfo(jobId));
|
||||
}
|
||||
|
||||
private static JobStatus createJobStatus(String testTag, String packageName, int callingUid,
|
||||
@@ -330,6 +334,32 @@ public class PrefetchControllerTest {
|
||||
assertTrue(jobRunning.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintSatisfiedWhenWidget() {
|
||||
final JobStatus jobNonWidget = createJobStatus("testConstraintSatisfiedWhenWidget", 1);
|
||||
final JobStatus jobWidget = createJobStatus("testConstraintSatisfiedWhenWidget", 2);
|
||||
|
||||
when(mUsageStatsManagerInternal
|
||||
.getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID))
|
||||
.thenReturn(sSystemClock.millis() + 100 * HOUR_IN_MILLIS);
|
||||
|
||||
final AppWidgetManager appWidgetManager = mock(AppWidgetManager.class);
|
||||
when(mContext.getSystemService(AppWidgetManager.class)).thenReturn(appWidgetManager);
|
||||
mPrefetchController.onSystemServicesReady();
|
||||
|
||||
when(appWidgetManager.isBoundWidgetPackage(SOURCE_PACKAGE, SOURCE_USER_ID))
|
||||
.thenReturn(false);
|
||||
trackJobs(jobNonWidget);
|
||||
verify(mUsageStatsManagerInternal, timeout(DEFAULT_WAIT_MS))
|
||||
.getEstimatedPackageLaunchTime(SOURCE_PACKAGE, SOURCE_USER_ID);
|
||||
assertFalse(jobNonWidget.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
|
||||
|
||||
when(appWidgetManager.isBoundWidgetPackage(SOURCE_PACKAGE, SOURCE_USER_ID))
|
||||
.thenReturn(true);
|
||||
trackJobs(jobWidget);
|
||||
assertTrue(jobWidget.isConstraintSatisfied(JobStatus.CONSTRAINT_PREFETCH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEstimatedLaunchTimeChangedToLate() {
|
||||
setDeviceConfigLong(PcConstants.KEY_LAUNCH_TIME_THRESHOLD_MS, 7 * HOUR_IN_MILLIS);
|
||||
|
||||
Reference in New Issue
Block a user