Merge "Schedule binary measurement job at boot completed." into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0a69364a40
@@ -6926,6 +6926,10 @@
|
|||||||
android:permission="android.permission.BIND_JOB_SERVICE">
|
android:permission="android.permission.BIND_JOB_SERVICE">
|
||||||
</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"
|
<service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@@ -18,14 +18,22 @@ package com.android.server;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
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.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ModuleInfo;
|
import android.content.pm.ModuleInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
|
import android.os.ServiceManager;
|
||||||
import android.os.ShellCallback;
|
import android.os.ShellCallback;
|
||||||
import android.os.ShellCommand;
|
import android.os.ShellCommand;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
@@ -42,6 +50,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,6 +58,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class BinaryTransparencyService extends SystemService {
|
public class BinaryTransparencyService extends SystemService {
|
||||||
private static final String TAG = "TransparencyService";
|
private static final String TAG = "TransparencyService";
|
||||||
|
private static final String EXTRA_SERVICE = "service";
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String VBMETA_DIGEST_UNINITIALIZED = "vbmeta-digest-uninitialized";
|
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
|
// we are only interested in doing things at PHASE_BOOT_COMPLETED
|
||||||
if (phase == 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.");
|
Slog.i(TAG, "Boot completed. Getting VBMeta Digest.");
|
||||||
getVBMetaDigestInformation();
|
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
|
@NonNull
|
||||||
private List<PackageInfo> getInstalledApexs() {
|
private List<PackageInfo> getInstalledApexs() {
|
||||||
List<PackageInfo> results = new ArrayList<PackageInfo>();
|
List<PackageInfo> results = new ArrayList<>();
|
||||||
PackageManager pm = mContext.getPackageManager();
|
PackageManager pm = mContext.getPackageManager();
|
||||||
if (pm == null) {
|
if (pm == null) {
|
||||||
Slog.e(TAG, "Error obtaining an instance of PackageManager.");
|
Slog.e(TAG, "Error obtaining an instance of PackageManager.");
|
||||||
|
|||||||
Reference in New Issue
Block a user