Loading core/res/AndroidManifest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -6923,6 +6923,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> Loading services/core/java/com/android/server/BinaryTransparencyService.java +83 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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"; Loading Loading @@ -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)); } } Loading @@ -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."); Loading Loading
core/res/AndroidManifest.xml +4 −0 Original line number Diff line number Diff line Loading @@ -6923,6 +6923,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> Loading
services/core/java/com/android/server/BinaryTransparencyService.java +83 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading @@ -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"; Loading Loading @@ -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)); } } Loading @@ -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."); Loading