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

Commit 14f885bc authored by Dario Freni's avatar Dario Freni
Browse files

Unblock broadcasts when systemReady() finished.

Also, move the onBootCompleted logic entirely to ApexManager since it's
the only component which reacts to the event after this change.

Change-Id: Iebc0b9e105352a1a975ac08fea17b3912ba5806d
Fix: 125001733
Test: atest apex_e2e_tests
parent 8e95f0bf
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -22,6 +22,10 @@ import android.apex.ApexInfo;
import android.apex.ApexInfoList;
import android.apex.ApexInfoList;
import android.apex.ApexSessionInfo;
import android.apex.ApexSessionInfo;
import android.apex.IApexService;
import android.apex.IApexService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.PackageParserException;
@@ -49,17 +53,29 @@ import java.util.stream.Collectors;
class ApexManager {
class ApexManager {
    static final String TAG = "ApexManager";
    static final String TAG = "ApexManager";
    private final IApexService mApexService;
    private final IApexService mApexService;
    private final Context mContext;
    private final Object mLock = new Object();
    private final Object mLock = new Object();
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private Map<String, PackageInfo> mActivePackagesCache;
    private Map<String, PackageInfo> mActivePackagesCache;


    ApexManager() {
    ApexManager(Context context) {
        try {
        try {
            mApexService = IApexService.Stub.asInterface(
            mApexService = IApexService.Stub.asInterface(
                ServiceManager.getServiceOrThrow("apexservice"));
                ServiceManager.getServiceOrThrow("apexservice"));
        } catch (ServiceNotFoundException e) {
        } catch (ServiceNotFoundException e) {
            throw new IllegalStateException("Required service apexservice not available");
            throw new IllegalStateException("Required service apexservice not available");
        }
        }
        mContext = context;
    }

    void systemReady() {
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                onBootCompleted();
                mContext.unregisterReceiver(this);
            }
        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
    }
    }


    private void populateActivePackagesCacheIfNeeded() {
    private void populateActivePackagesCacheIfNeeded() {
+14 −19
Original line number Original line Diff line number Diff line
@@ -28,10 +28,8 @@ import android.app.NotificationManager;
import android.app.PackageDeleteObserver;
import android.app.PackageDeleteObserver;
import android.app.PackageInstallObserver;
import android.app.PackageInstallObserver;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.IntentSender.SendIntentException;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
@@ -141,7 +139,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements


    private final Callbacks mCallbacks;
    private final Callbacks mCallbacks;


    private volatile boolean mBootCompleted = false;
    private volatile boolean mOkToSendBroadcasts = false;


    /**
    /**
     * File storing persisted {@link #mSessions} metadata.
     * File storing persisted {@link #mSessions} metadata.
@@ -209,26 +207,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        mStagingManager = new StagingManager(pm, this, am);
        mStagingManager = new StagingManager(pm, this, am);
    }
    }


    private void onBootCompleted()  {
    boolean okToSendBroadcasts()  {
        mBootCompleted = true;
        return mOkToSendBroadcasts;
        // Tell APEX manager about it as well
        mApexManager.onBootCompleted();
    }

    boolean isBootCompleted()  {
        return mBootCompleted;
    }
    }


    public void systemReady() {
    public void systemReady() {
        mAppOps = mContext.getSystemService(AppOpsManager.class);
        mAppOps = mContext.getSystemService(AppOpsManager.class);


        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                onBootCompleted();
                mContext.unregisterReceiver(this);
            }
        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
        synchronized (mSessions) {
        synchronized (mSessions) {
            readSessionsLocked();
            readSessionsLocked();


@@ -271,6 +256,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        for (PackageInstallerSession session : stagedSessionsToRestore) {
        for (PackageInstallerSession session : stagedSessionsToRestore) {
            mStagingManager.restoreSession(session);
            mStagingManager.restoreSession(session);
        }
        }
        // Broadcasts are not sent while we restore sessions on boot, since no processes would be
        // ready to listen to them. From now on, we greedily assume that broadcasts requests are
        // safe to send out. The worst that can happen is that a broadcast is attempted before
        // ActivityManagerService completes its own systemReady(), in which case it will be rejected
        // with an otherwise harmless exception.
        // A more appropriate way to do this would be to wait until the correct  boot phase is
        // reached, but since we are not a SystemService we can't override onBootPhase.
        // Waiting on the BOOT_COMPLETED broadcast can take several minutes, so that's not a viable
        // way either.
        mOkToSendBroadcasts = true;
    }
    }


    @GuardedBy("mSessions")
    @GuardedBy("mSessions")
@@ -1189,7 +1184,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements


        public void onStagedSessionChanged(PackageInstallerSession session) {
        public void onStagedSessionChanged(PackageInstallerSession session) {
            writeSessionsAsync();
            writeSessionsAsync();
            if (mBootCompleted) {
            if (mOkToSendBroadcasts) {
                mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),
                mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),
                        session.userId);
                        session.userId);
            }
            }
+1 −1
Original line number Original line Diff line number Diff line
@@ -1999,7 +1999,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {


        // Send broadcast to default launcher only if it's a new install
        // Send broadcast to default launcher only if it's a new install
        final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
        final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
        if (success && isNewInstall && mPm.mInstallerService.isBootCompleted()) {
        if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()) {
            mPm.sendSessionCommitBroadcast(generateInfo(), userId);
            mPm.sendSessionCommitBroadcast(generateInfo(), userId);
        }
        }


+2 −1
Original line number Original line Diff line number Diff line
@@ -3101,7 +3101,7 @@ public class PackageManagerService extends IPackageManager.Stub
                }
                }
            }
            }
            mApexManager = new ApexManager();
            mApexManager = new ApexManager(context);
            mInstallerService = new PackageInstallerService(context, this, mApexManager);
            mInstallerService = new PackageInstallerService(context, this, mApexManager);
            final Pair<ComponentName, String> instantAppResolverComponent =
            final Pair<ComponentName, String> instantAppResolverComponent =
                    getInstantAppResolverLPr();
                    getInstantAppResolverLPr();
@@ -20706,6 +20706,7 @@ public class PackageManagerService extends IPackageManager.Stub
        storage.registerListener(mStorageListener);
        storage.registerListener(mStorageListener);
        mInstallerService.systemReady();
        mInstallerService.systemReady();
        mApexManager.systemReady();
        mPackageDexOptimizer.systemReady();
        mPackageDexOptimizer.systemReady();
        getStorageManagerInternal().addExternalStoragePolicy(
        getStorageManagerInternal().addExternalStoragePolicy(