summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--services/core/java/com/android/server/BinaryTransparencyService.java86
2 files changed, 87 insertions, 3 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 73cdaba24789..d7744e377f12 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6926,6 +6926,10 @@
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+ <service android:name="com.android.server.BinaryTransparencyService$UpdateMeasurementsJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE">
+ </service>
+
<service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
android:exported="false">
<intent-filter>
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 6986d3bbe585..1f8ef8226c32 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -18,14 +18,22 @@ package com.android.server;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemProperties;
@@ -42,6 +50,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executors;
import java.util.stream.Collectors;
/**
@@ -49,6 +58,7 @@ import java.util.stream.Collectors;
*/
public class BinaryTransparencyService extends SystemService {
private static final String TAG = "TransparencyService";
+ private static final String EXTRA_SERVICE = "service";
@VisibleForTesting
static final String VBMETA_DIGEST_UNINITIALIZED = "vbmeta-digest-uninitialized";
@@ -365,10 +375,80 @@ public class BinaryTransparencyService extends SystemService {
// we are only interested in doing things at PHASE_BOOT_COMPLETED
if (phase == PHASE_BOOT_COMPLETED) {
- // due to potentially long computation that holds up boot time, apex sha computations
- // are deferred to first call
Slog.i(TAG, "Boot completed. Getting VBMeta Digest.");
getVBMetaDigestInformation();
+
+ // due to potentially long computation that holds up boot time, computations for
+ // SHA256 digests of APEX and Module packages are scheduled here,
+ // but only executed when device is idle.
+ Slog.i(TAG, "Scheduling APEX and Module measurements to be updated.");
+ UpdateMeasurementsJobService.scheduleBinaryMeasurements(mContext,
+ BinaryTransparencyService.this);
+ }
+ }
+
+ /**
+ * JobService to update binary measurements and update internal cache.
+ */
+ public static class UpdateMeasurementsJobService extends JobService {
+ private static final int COMPUTE_APEX_MODULE_SHA256_JOB_ID =
+ BinaryTransparencyService.UpdateMeasurementsJobService.class.hashCode();
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ Slog.d(TAG, "Job to update binary measurements started.");
+ if (params.getJobId() != COMPUTE_APEX_MODULE_SHA256_JOB_ID) {
+ return false;
+ }
+
+ // we'll still update the measurements via threads to be mindful of low-end devices
+ // where this operation might take longer than expected, and so that we don't block
+ // system_server's main thread.
+ Executors.defaultThreadFactory().newThread(() -> {
+ // since we can't call updateBinaryMeasurements() directly, calling
+ // getApexInfo() achieves the same effect, and we simply discard the return
+ // value
+
+ IBinder b = ServiceManager.getService(Context.BINARY_TRANSPARENCY_SERVICE);
+ IBinaryTransparencyService iBtsService =
+ IBinaryTransparencyService.Stub.asInterface(b);
+ try {
+ iBtsService.getApexInfo();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Updating binary measurements was interrupted.", e);
+ return;
+ }
+ jobFinished(params, false);
+ }).start();
+
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ return false;
+ }
+
+ @SuppressLint("DefaultLocale")
+ static void scheduleBinaryMeasurements(Context context, BinaryTransparencyService service) {
+ Slog.i(TAG, "Scheduling APEX & Module SHA256 digest computation job");
+ final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+ if (jobScheduler == null) {
+ Slog.e(TAG, "Failed to obtain an instance of JobScheduler.");
+ return;
+ }
+
+ final JobInfo jobInfo = new JobInfo.Builder(COMPUTE_APEX_MODULE_SHA256_JOB_ID,
+ new ComponentName(context, UpdateMeasurementsJobService.class))
+ .setRequiresDeviceIdle(true)
+ .build();
+ if (jobScheduler.schedule(jobInfo) != JobScheduler.RESULT_SUCCESS) {
+ Slog.e(TAG, "Failed to schedule job to update binary measurements.");
+ return;
+ }
+ Slog.d(TAG, String.format(
+ "Job %d to update binary measurements scheduled successfully.",
+ COMPUTE_APEX_MODULE_SHA256_JOB_ID));
}
}
@@ -380,7 +460,7 @@ public class BinaryTransparencyService extends SystemService {
@NonNull
private List<PackageInfo> getInstalledApexs() {
- List<PackageInfo> results = new ArrayList<PackageInfo>();
+ List<PackageInfo> results = new ArrayList<>();
PackageManager pm = mContext.getPackageManager();
if (pm == null) {
Slog.e(TAG, "Error obtaining an instance of PackageManager.");