Skip to content

Commit

Permalink
Add PreRebootDexoptJob.
Browse files Browse the repository at this point in the history
Refactoring and boilerplate changes.

Bug: 311377497
Test: m
Change-Id: Ibe9870bc60918c572ce75aa46bd885d2bc71fe00
  • Loading branch information
jiakaiz-g committed Feb 9, 2024
1 parent cd98d6a commit 5d72ab3
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,17 @@ BackgroundDexoptJob getBackgroundDexoptJob() {
return mInjector.getBackgroundDexoptJob();
}

/**
* Should be used by {@link BackgroundDexoptJobService} ONLY.
*
* @hide
*/
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@NonNull
PreRebootDexoptJob getPreRebootDexoptJob() {
return mInjector.getPreRebootDexoptJob();
}

@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Nullable
private DexoptResult maybeDowngradePackages(
Expand Down Expand Up @@ -1354,6 +1365,7 @@ public static class Injector {
@Nullable private final PackageManagerLocal mPackageManagerLocal;
@Nullable private final Config mConfig;
@Nullable private BackgroundDexoptJob mBgDexoptJob = null;
@Nullable private PreRebootDexoptJob mPrDexoptJob = null;

/** For compatibility with S and T. New code should not use this. */
@Deprecated
Expand Down Expand Up @@ -1441,6 +1453,15 @@ public synchronized BackgroundDexoptJob getBackgroundDexoptJob() {
return mBgDexoptJob;
}

@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@NonNull
public synchronized PreRebootDexoptJob getPreRebootDexoptJob() {
if (mPrDexoptJob == null) {
mPrDexoptJob = new PreRebootDexoptJob(mContext);
}
return mPrDexoptJob;
}

@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@NonNull
public UserManager getUserManager() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalManagerRegistry;
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.ArtServiceJobInterface;
import com.android.server.art.model.Config;
import com.android.server.art.model.DexoptResult;
import com.android.server.art.model.OperationProgress;
Expand All @@ -59,7 +60,7 @@

/** @hide */
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public class BackgroundDexoptJob {
public class BackgroundDexoptJob implements ArtServiceJobInterface {
private static final String TAG = ArtManagerLocal.TAG;

/**
Expand All @@ -68,7 +69,7 @@ public class BackgroundDexoptJob {
*/
private static final String JOB_PKG_NAME = Utils.PLATFORM_PACKAGE_NAME;
/** An arbitrary number. Must be unique among all jobs owned by the system uid. */
private static final int JOB_ID = 27873780;
public static final int JOB_ID = 27873780;

@VisibleForTesting public static final long JOB_INTERVAL_MS = TimeUnit.DAYS.toMillis(1);

Expand All @@ -89,6 +90,7 @@ public BackgroundDexoptJob(@NonNull Injector injector) {
}

/** Handles {@link BackgroundDexoptJobService#onStartJob(JobParameters)}. */
@Override
public boolean onStartJob(
@NonNull BackgroundDexoptJobService jobService, @NonNull JobParameters params) {
start().thenAcceptAsync(result -> {
Expand All @@ -113,6 +115,7 @@ public boolean onStartJob(
}

/** Handles {@link BackgroundDexoptJobService#onStopJob(JobParameters)}. */
@Override
public boolean onStopJob(@NonNull JobParameters params) {
synchronized (this) {
mLastStopReason = Optional.of(params.getStopReason());
Expand All @@ -124,7 +127,7 @@ public boolean onStopJob(@NonNull JobParameters params) {

/** Handles {@link ArtManagerLocal#scheduleBackgroundDexoptJob()}. */
public @ScheduleStatus int schedule() {
if (this != BackgroundDexoptJobService.getJob()) {
if (this != BackgroundDexoptJobService.getJob(JOB_ID)) {
throw new IllegalStateException("This job cannot be scheduled");
}

Expand Down Expand Up @@ -164,7 +167,7 @@ public boolean onStopJob(@NonNull JobParameters params) {

/** Handles {@link ArtManagerLocal#unscheduleBackgroundDexoptJob()}. */
public void unschedule() {
if (this != BackgroundDexoptJobService.getJob()) {
if (this != BackgroundDexoptJobService.getJob(JOB_ID)) {
throw new IllegalStateException("This job cannot be unscheduled");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import androidx.annotation.RequiresApi;

import com.android.server.LocalManagerRegistry;
import com.android.server.art.model.ArtServiceJobInterface;

/**
* Entry point for the callback from the job scheduler. This class is instantiated by the system
Expand All @@ -35,16 +36,21 @@
public class BackgroundDexoptJobService extends JobService {
@Override
public boolean onStartJob(@NonNull JobParameters params) {
return getJob().onStartJob(this, params);
return getJob(params.getJobId()).onStartJob(this, params);
}

@Override
public boolean onStopJob(@NonNull JobParameters params) {
return getJob().onStopJob(params);
return getJob(params.getJobId()).onStopJob(params);
}

@NonNull
static BackgroundDexoptJob getJob() {
return LocalManagerRegistry.getManager(ArtManagerLocal.class).getBackgroundDexoptJob();
static ArtServiceJobInterface getJob(int jobId) {
if (jobId == BackgroundDexoptJob.JOB_ID) {
return LocalManagerRegistry.getManager(ArtManagerLocal.class).getBackgroundDexoptJob();
} else if (jobId == PreRebootDexoptJob.JOB_ID) {
return LocalManagerRegistry.getManager(ArtManagerLocal.class).getPreRebootDexoptJob();
}
throw new IllegalArgumentException("Unknown job ID " + jobId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.android.server.art;

import static com.android.server.art.model.ArtFlags.ScheduleStatus;

import android.annotation.NonNull;
import android.app.job.JobParameters;
import android.content.Context;
import android.os.Build;

import androidx.annotation.RequiresApi;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.ArtServiceJobInterface;

/** @hide */
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public class PreRebootDexoptJob implements ArtServiceJobInterface {
private static final String TAG = ArtManagerLocal.TAG;

/**
* "android" is the package name for a <service> declared in
* frameworks/base/core/res/AndroidManifest.xml
*/
private static final String JOB_PKG_NAME = Utils.PLATFORM_PACKAGE_NAME;
/** An arbitrary number. Must be unique among all jobs owned by the system uid. */
public static final int JOB_ID = 27873781;

@NonNull private final Injector mInjector;

public PreRebootDexoptJob(@NonNull Context context) {
this(new Injector(context));
}

@VisibleForTesting
public PreRebootDexoptJob(@NonNull Injector injector) {
mInjector = injector;
}

@Override
public boolean onStartJob(
@NonNull BackgroundDexoptJobService jobService, @NonNull JobParameters params) {
// "true" means the job will continue running until `jobFinished` is called.
return false;
}

@Override
public boolean onStopJob(@NonNull JobParameters params) {
// "true" means to execute again in the same interval with the default retry policy.
return true;
}

public @ScheduleStatus int schedule() {
// TODO(b/311377497): Schedule the job.
return ArtFlags.SCHEDULE_SUCCESS;
}

/**
* Injector pattern for testing purpose.
*
* @hide
*/
@VisibleForTesting
public static class Injector {
@NonNull private final Context mContext;

Injector(@NonNull Context context) {
mContext = context;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.android.server.art.model;

import android.annotation.NonNull;
import android.app.job.JobParameters;

import com.android.server.art.BackgroundDexoptJobService;

/** @hide */
public interface ArtServiceJobInterface {
boolean onStartJob(
@NonNull BackgroundDexoptJobService jobService, @NonNull JobParameters params);

boolean onStopJob(@NonNull JobParameters params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.android.server.art;

import static com.android.server.art.BackgroundDexoptJob.JOB_ID;
import static com.android.server.art.model.Config.Callback;
import static com.android.server.art.model.DexoptResult.DexoptResultStatus;
import static com.android.server.art.model.DexoptResult.PackageDexoptResult;
Expand Down Expand Up @@ -103,7 +104,7 @@ public void setUp() throws Exception {
lenient().when(mInjector.getJobScheduler()).thenReturn(mJobScheduler);

mBackgroundDexoptJob = new BackgroundDexoptJob(mInjector);
lenient().when(BackgroundDexoptJobService.getJob()).thenReturn(mBackgroundDexoptJob);
lenient().when(BackgroundDexoptJobService.getJob(JOB_ID)).thenReturn(mBackgroundDexoptJob);

lenient()
.doAnswer(invocation -> {
Expand Down

0 comments on commit 5d72ab3

Please sign in to comment.