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

Commit 19f29166 authored by Neda Topoljanac's avatar Neda Topoljanac Committed by Rubin Xu
Browse files

Managed System Updates API

Adding API to install a system update from a file on the device.

Test: manual in TestDPC, CTS tests for negative cases: atest com.android.cts.devicepolicy.DeviceOwnerTest#testInstallUpdate

Fixes: 116511569

Change-Id: I34b5c6344301a9d2d64c98dedc4ed5e4a75c57d1
parent 0961c3e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -92,6 +92,7 @@ java_defaults {
        "core/java/android/app/IWallpaperManagerCallback.aidl",
        "core/java/android/app/IWallpaperManagerCallback.aidl",
        "core/java/android/app/admin/IDeviceAdminService.aidl",
        "core/java/android/app/admin/IDeviceAdminService.aidl",
        "core/java/android/app/admin/IDevicePolicyManager.aidl",
        "core/java/android/app/admin/IDevicePolicyManager.aidl",
        "core/java/android/app/admin/StartInstallingUpdateCallback.aidl",
        "core/java/android/app/trust/IStrongAuthTracker.aidl",
        "core/java/android/app/trust/IStrongAuthTracker.aidl",
        "core/java/android/app/trust/ITrustManager.aidl",
        "core/java/android/app/trust/ITrustManager.aidl",
        "core/java/android/app/trust/ITrustListener.aidl",
        "core/java/android/app/trust/ITrustListener.aidl",
+11 −0
Original line number Original line Diff line number Diff line
@@ -6598,6 +6598,7 @@ package android.app.admin {
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, int);
    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, int);
    method public void installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallUpdateCallback);
    method public boolean isActivePasswordSufficient();
    method public boolean isActivePasswordSufficient();
    method public boolean isAdminActive(android.content.ComponentName);
    method public boolean isAdminActive(android.content.ComponentName);
    method public boolean isAffiliatedUser();
    method public boolean isAffiliatedUser();
@@ -6840,6 +6841,16 @@ package android.app.admin {
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
  }
  }
  public static abstract class DevicePolicyManager.InstallUpdateCallback {
    ctor public DevicePolicyManager.InstallUpdateCallback();
    method public void onInstallUpdateError(int, java.lang.String);
    field public static final int UPDATE_ERROR_BATTERY_LOW = 5; // 0x5
    field public static final int UPDATE_ERROR_FILE_NOT_FOUND = 4; // 0x4
    field public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2; // 0x2
    field public static final int UPDATE_ERROR_UNKNOWN = 1; // 0x1
    field public static final int UPDATE_ERROR_UPDATE_FILE_INVALID = 3; // 0x3
  }
  public static abstract interface DevicePolicyManager.OnClearApplicationUserDataListener {
  public static abstract interface DevicePolicyManager.OnClearApplicationUserDataListener {
    method public abstract void onApplicationUserDataCleared(java.lang.String, boolean);
    method public abstract void onApplicationUserDataCleared(java.lang.String, boolean);
  }
  }
+2 −2
Original line number Original line Diff line number Diff line
@@ -441,10 +441,10 @@ package android.app {
  }
  }


  public class KeyguardManager {
  public class KeyguardManager {
    method public void setPrivateNotificationsAllowed(boolean);
    method public boolean getPrivateNotificationsAllowed();
    method public android.content.Intent createConfirmFactoryResetCredentialIntent(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence);
    method public android.content.Intent createConfirmFactoryResetCredentialIntent(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence);
    method public boolean getPrivateNotificationsAllowed();
    method public void requestDismissKeyguard(android.app.Activity, java.lang.CharSequence, android.app.KeyguardManager.KeyguardDismissCallback);
    method public void requestDismissKeyguard(android.app.Activity, java.lang.CharSequence, android.app.KeyguardManager.KeyguardDismissCallback);
    method public void setPrivateNotificationsAllowed(boolean);
  }
  }


  public class Notification implements android.os.Parcelable {
  public class Notification implements android.os.Parcelable {
+100 −1
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ import android.net.ProxyInfo;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
import android.os.Bundle;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.Process;
@@ -87,6 +88,7 @@ import com.android.internal.util.Preconditions;
import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.org.conscrypt.TrustedCertificateStore;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -1929,6 +1931,48 @@ public class DevicePolicyManager {
     */
     */
    public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
    public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;


    /**
     * Callback used in {@link #installSystemUpdate} to indicate that there was an error while
     * trying to install an update.
     */
    public abstract static class InstallUpdateCallback {
        /** Represents an unknown error while trying to install an update. */
        public static final int UPDATE_ERROR_UNKNOWN = 1;

        /** Represents the update file being intended for different OS version. */
        public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2;

        /**
         * Represents the update file being wrong, i.e. payloads are mismatched, wrong compressions
         * method.
         */
        public static final int UPDATE_ERROR_UPDATE_FILE_INVALID = 3;

        /** Represents that the file could not be found. */
        public static final int UPDATE_ERROR_FILE_NOT_FOUND = 4;

        /** Represents the battery being too low to apply an update. */
        public static final int UPDATE_ERROR_BATTERY_LOW = 5;

        /** Method invoked when there was an error while installing an update. */
        public void onInstallUpdateError(
                @InstallUpdateCallbackErrorConstants int errorCode, String errorMessage) {
        }
    }

    /**
     * @hide
     */
    @IntDef(prefix = { "UPDATE_ERROR_" }, value = {
            InstallUpdateCallback.UPDATE_ERROR_UNKNOWN,
            InstallUpdateCallback.UPDATE_ERROR_INCORRECT_OS_VERSION,
            InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID,
            InstallUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND,
            InstallUpdateCallback.UPDATE_ERROR_BATTERY_LOW
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface InstallUpdateCallbackErrorConstants {}

    /**
    /**
     * Return true if the given administrator component is currently active (enabled) in the system.
     * Return true if the given administrator component is currently active (enabled) in the system.
     *
     *
@@ -6796,7 +6840,6 @@ public class DevicePolicyManager {
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface CreateAndManageUserFlags {}
    public @interface CreateAndManageUserFlags {}



    /**
    /**
     * Called by a device owner to create a user with the specified name and a given component of
     * Called by a device owner to create a user with the specified name and a given component of
     * the calling package as profile owner. The UserHandle returned by this method should not be
     * the calling package as profile owner. The UserHandle returned by this method should not be
@@ -9826,6 +9869,62 @@ public class DevicePolicyManager {
        }
        }
    }
    }


    /**
     * Called by device owner to install a system update from the given file. The device will be
     * rebooted in order to finish installing the update. Note that if the device is rebooted, this
     * doesn't necessarily mean that the update has been applied successfully. The caller should
     * additionally check the system version with {@link android.os.Build#FINGERPRINT} or {@link
     * android.os.Build.VERSION}. If an error occurs during processing the OTA before the reboot,
     * the caller will be notified by {@link InstallUpdateCallback}. If device does not have
     * sufficient battery level, the installation will fail with error {@link
     * InstallUpdateCallback#UPDATE_ERROR_BATTERY_LOW}.
     *
     * @param admin The {@link DeviceAdminReceiver} that this request is associated with.
     * @param updateFilePath An Uri of the file that contains the update. The file should be
     * readable by the calling app.
     * @param executor The executor through which the callback should be invoked.
     * @param callback A callback object that will inform the caller when installing an update
     * fails.
     */
    public void installSystemUpdate(
            @NonNull ComponentName admin, @NonNull Uri updateFilePath,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull InstallUpdateCallback callback) {
        throwIfParentInstance("installUpdate");
        if (mService == null) {
            return;
        }
        try (ParcelFileDescriptor fileDescriptor = mContext.getContentResolver()
                    .openFileDescriptor(updateFilePath, "r")) {
            mService.installUpdateFromFile(
                    admin, fileDescriptor, new StartInstallingUpdateCallback.Stub() {
                        @Override
                        public void onStartInstallingUpdateError(
                                int errorCode, String errorMessage) {
                            executeCallback(errorCode, errorMessage, executor, callback);
                        }
                    });
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        } catch (FileNotFoundException e) {
            Log.w(TAG, e);
            executeCallback(
                    InstallUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND, Log.getStackTraceString(e),
                    executor, callback);
        } catch (IOException e) {
            Log.w(TAG, e);
            executeCallback(
                    InstallUpdateCallback.UPDATE_ERROR_UNKNOWN, Log.getStackTraceString(e),
                    executor, callback);
        }
    }

    private void executeCallback(int errorCode, String errorMessage,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull InstallUpdateCallback callback) {
        executor.execute(() -> callback.onInstallUpdateError(errorCode, errorMessage));
    }

    /**
    /**
     * Returns the system-wide Private DNS mode.
     * Returns the system-wide Private DNS mode.
     *
     *
+3 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ package android.app.admin;
import android.app.admin.NetworkEvent;
import android.app.admin.NetworkEvent;
import android.app.IApplicationThread;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.IServiceConnection;
import android.app.admin.StartInstallingUpdateCallback;
import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdatePolicy;
import android.app.admin.SystemUpdatePolicy;
import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordMetrics;
@@ -419,4 +420,6 @@ interface IDevicePolicyManager {
    String getGlobalPrivateDnsHost(in ComponentName admin);
    String getGlobalPrivateDnsHost(in ComponentName admin);


    void grantDeviceIdsAccessToProfileOwner(in ComponentName who, int userId);
    void grantDeviceIdsAccessToProfileOwner(in ComponentName who, int userId);

    void installUpdateFromFile(in ComponentName admin, in ParcelFileDescriptor updateFileDescriptor, in StartInstallingUpdateCallback listener);
}
}
Loading