Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45878bfb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Schedule binary measurement job at boot completed."

parents 1ff5096a d76b7bf6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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>
+83 −3
Original line number Diff line number Diff line
@@ -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.");