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

Commit bd91e2f3 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Update PRE_BOOT_COMPLETED for FBE.

Now that CE data isn't available until after a user is unlocked, we
need to delay the PRE_BOOT_COMPLETED broadcasts.  This is done by
adding a new RUNNING_UNLOCKING user state to the UserController
lifecycle.

We now track the last fingerprint a user was logged in under, and we
dispatch PRE_BOOT receivers when that fingerprint changes.  To work
around battery pull issues, we only persist the updated fingerprint
once all PRE_BOOT receivers have finished.  This is less granular
than the original solution, but it's still correct.  We only consider
a user as "logged in" once it transitions into the RUNNING_UNLOCKED
state.

When starting a process, track if the user was "unlocked" when
started, so that we only spin up unaware providers in processes
started before user unlock.

Add generic IProgressListener to communicate PRE_BOOT progress and
strings up to lock screen.  For now, LockSettingsService just blocks
until finished, but it could display these strings in the future.

Bug: 27220885
Change-Id: I349439776b885acd32f6a578d8951ffd95640be2
parent 40e1135e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ LOCAL_SRC_FILES += \
	core/java/android/os/INetworkManagementService.aidl \
	core/java/android/os/IPermissionController.aidl \
	core/java/android/os/IProcessInfoService.aidl \
	core/java/android/os/IProgressListener.aidl \
	core/java/android/os/IPowerManager.aidl \
	core/java/android/os/IRecoverySystem.aidl \
	core/java/android/os/IRecoverySystemProgressListener.aidl \
+1 −1
Original line number Diff line number Diff line
@@ -1141,7 +1141,7 @@ public class Am extends BaseCommand {
        int userId = Integer.parseInt(nextArgRequired());
        byte[] token = argToBytes(nextArgRequired());
        byte[] secret = argToBytes(nextArgRequired());
        boolean success = mAm.unlockUser(userId, token, secret);
        boolean success = mAm.unlockUser(userId, token, secret, null);
        if (success) {
            System.out.println("Success: user unlocked");
        } else {
+7 −2
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
import android.os.IProgressListener;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -2122,7 +2123,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            int userId = data.readInt();
            byte[] token = data.createByteArray();
            byte[] secret = data.createByteArray();
            boolean result = unlockUser(userId, token, secret);
            IProgressListener listener = IProgressListener.Stub
                    .asInterface(data.readStrongBinder());
            boolean result = unlockUser(userId, token, secret, listener);
            reply.writeNoException();
            reply.writeInt(result ? 1 : 0);
            return true;
@@ -5707,13 +5710,15 @@ class ActivityManagerProxy implements IActivityManager
        return result;
    }

    public boolean unlockUser(int userId, byte[] token, byte[] secret) throws RemoteException {
    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(userId);
        data.writeByteArray(token);
        data.writeByteArray(secret);
        data.writeStrongInterface(listener);
        mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
        reply.readException();
        boolean result = reply.readInt() != 0;
+3 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
import android.os.IInterface;
import android.os.IProgressListener;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -461,7 +462,8 @@ public interface IActivityManager extends IInterface {
    // Multi-user APIs
    public boolean switchUser(int userid) throws RemoteException;
    public boolean startUserInBackground(int userid) throws RemoteException;
    public boolean unlockUser(int userid, byte[] token, byte[] secret) throws RemoteException;
    public boolean unlockUser(int userid, byte[] token, byte[] secret, IProgressListener listener)
            throws RemoteException;
    public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
    public UserInfo getCurrentUser() throws RemoteException;
    public boolean isUserRunning(int userid, int flags) throws RemoteException;
+8 −5
Original line number Diff line number Diff line
@@ -2856,12 +2856,15 @@ public class Intent implements Parcelable, Cloneable {
            "com.google.android.c2dm.intent.RECEIVE";

    /**
     * Broadcast Action: hook for permforming cleanup after a system update.
     * Broadcast Action: This is broadcast once when the user is booting after a
     * system update. It can be used to perform cleanup or upgrades after a
     * system update.
     * <p>
     * This broadcast is sent after the {@link #ACTION_LOCKED_BOOT_COMPLETED}
     * broadcast but before the {@link #ACTION_BOOT_COMPLETED} broadcast. It's
     * only sent when the {@link Build#FINGERPRINT} has changed, and it's only
     * sent to receivers in the system image.
     *
     * The broadcast is sent when the system is booting, before the
     * BOOT_COMPLETED broadcast.  It is only sent to receivers in the system
     * image.  A receiver for this should do its work and then disable itself
     * so that it does not get run again at the next boot.
     * @hide
     */
    public static final String ACTION_PRE_BOOT_COMPLETED =
Loading