summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libartservice/service/java/com/android/server/art/ArtManagerLocal.java21
-rw-r--r--libartservice/service/java/com/android/server/art/BackgroundDexoptJob.java11
-rw-r--r--libartservice/service/java/com/android/server/art/BackgroundDexoptJobService.java14
-rw-r--r--libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java87
-rw-r--r--libartservice/service/java/com/android/server/art/model/ArtServiceJobInterface.java30
-rw-r--r--libartservice/service/javatests/com/android/server/art/BackgroundDexoptJobTest.java3
6 files changed, 157 insertions, 9 deletions
diff --git a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
index 69cba7d860..d4e3c59f45 100644
--- a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
+++ b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
@@ -1024,6 +1024,17 @@ public final class ArtManagerLocal {
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(
@@ -1354,6 +1365,7 @@ public final class ArtManagerLocal {
@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
@@ -1443,6 +1455,15 @@ public final class ArtManagerLocal {
@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() {
return Objects.requireNonNull(mContext.getSystemService(UserManager.class));
}
diff --git a/libartservice/service/java/com/android/server/art/BackgroundDexoptJob.java b/libartservice/service/java/com/android/server/art/BackgroundDexoptJob.java
index 9aeb2828fb..289c7cd235 100644
--- a/libartservice/service/java/com/android/server/art/BackgroundDexoptJob.java
+++ b/libartservice/service/java/com/android/server/art/BackgroundDexoptJob.java
@@ -41,6 +41,7 @@ import com.android.internal.annotations.GuardedBy;
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;
@@ -59,7 +60,7 @@ import java.util.function.Consumer;
/** @hide */
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-public class BackgroundDexoptJob {
+public class BackgroundDexoptJob implements ArtServiceJobInterface {
private static final String TAG = ArtManagerLocal.TAG;
/**
@@ -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);
@@ -89,6 +90,7 @@ public class BackgroundDexoptJob {
}
/** Handles {@link BackgroundDexoptJobService#onStartJob(JobParameters)}. */
+ @Override
public boolean onStartJob(
@NonNull BackgroundDexoptJobService jobService, @NonNull JobParameters params) {
start().thenAcceptAsync(result -> {
@@ -113,6 +115,7 @@ public class BackgroundDexoptJob {
}
/** Handles {@link BackgroundDexoptJobService#onStopJob(JobParameters)}. */
+ @Override
public boolean onStopJob(@NonNull JobParameters params) {
synchronized (this) {
mLastStopReason = Optional.of(params.getStopReason());
@@ -124,7 +127,7 @@ public class BackgroundDexoptJob {
/** 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");
}
@@ -164,7 +167,7 @@ public class BackgroundDexoptJob {
/** 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");
}
diff --git a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobService.java b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobService.java
index 41425ee5cc..8bcc4b98be 100644
--- a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobService.java
+++ b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobService.java
@@ -24,6 +24,7 @@ import android.os.Build;
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
@@ -35,16 +36,21 @@ import com.android.server.LocalManagerRegistry;
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);
}
}
diff --git a/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java
new file mode 100644
index 0000000000..74bf913e62
--- /dev/null
+++ b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java
@@ -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;
+ }
+ }
+}
diff --git a/libartservice/service/java/com/android/server/art/model/ArtServiceJobInterface.java b/libartservice/service/java/com/android/server/art/model/ArtServiceJobInterface.java
new file mode 100644
index 0000000000..569996c566
--- /dev/null
+++ b/libartservice/service/java/com/android/server/art/model/ArtServiceJobInterface.java
@@ -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);
+}
diff --git a/libartservice/service/javatests/com/android/server/art/BackgroundDexoptJobTest.java b/libartservice/service/javatests/com/android/server/art/BackgroundDexoptJobTest.java
index c61461d0c9..85ae079c77 100644
--- a/libartservice/service/javatests/com/android/server/art/BackgroundDexoptJobTest.java
+++ b/libartservice/service/javatests/com/android/server/art/BackgroundDexoptJobTest.java
@@ -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;
@@ -103,7 +104,7 @@ public class BackgroundDexoptJobTest {
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 -> {