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

Commit 8027a4ff authored by Rubin Xu's avatar Rubin Xu
Browse files

Add setOtaPolicy/getOtaPolicy API in DPMS

Allow device owners to set OTA policy for automatically accept/postpone
incoming OTA system updates. This class only provides the setting
and getting of OTA policy, the actual OTA subsystem should handle
and respect the policy stored here.

Bug: 19650524
Change-Id: I9b64949fab42097429b7da649039c13f42c10fd1
parent 8cc578c3
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -5663,6 +5663,7 @@ package android.app.admin {
    method public int getKeyguardDisabledFeatures(android.content.ComponentName);
    method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
    method public long getMaximumTimeToLock(android.content.ComponentName);
    method public android.app.admin.OtaPolicy getOtaPolicy();
    method public long getPasswordExpiration(android.content.ComponentName);
    method public long getPasswordExpirationTimeout(android.content.ComponentName);
    method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -5714,6 +5715,7 @@ package android.app.admin {
    method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
    method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
    method public void setMaximumTimeToLock(android.content.ComponentName, long);
    method public void setOtaPolicy(android.content.ComponentName, android.app.admin.OtaPolicy);
    method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
    method public void setPasswordHistoryLength(android.content.ComponentName, int);
    method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -5743,6 +5745,7 @@ package android.app.admin {
    method public void wipeData(int);
    field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
    field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
    field public static final java.lang.String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";
    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
    field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
    field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
@@ -5810,6 +5813,23 @@ package android.app.admin {
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
  }
  public class OtaPolicy {
    ctor public OtaPolicy();
    method public int getInstallWindowEnd();
    method public int getInstallWindowStart();
    method public int getPolicyType();
    method public void setAutomaticInstallPolicy();
    method public void setPostponeInstallPolicy();
    method public void setWindowedInstallPolicy(int, int) throws android.app.admin.OtaPolicy.InvalidWindowException;
    field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1
    field public static final int TYPE_INSTALL_WINDOWED = 2; // 0x2
    field public static final int TYPE_POSTPONE = 3; // 0x3
  }
  public static class OtaPolicy.InvalidWindowException extends java.lang.Exception {
    ctor public OtaPolicy.InvalidWindowException(java.lang.String);
  }
}
package android.app.backup {
+20 −0
Original line number Diff line number Diff line
@@ -5762,6 +5762,7 @@ package android.app.admin {
    method public int getKeyguardDisabledFeatures(android.content.ComponentName);
    method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
    method public long getMaximumTimeToLock(android.content.ComponentName);
    method public android.app.admin.OtaPolicy getOtaPolicy();
    method public long getPasswordExpiration(android.content.ComponentName);
    method public long getPasswordExpirationTimeout(android.content.ComponentName);
    method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -5818,6 +5819,7 @@ package android.app.admin {
    method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
    method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
    method public void setMaximumTimeToLock(android.content.ComponentName, long);
    method public void setOtaPolicy(android.content.ComponentName, android.app.admin.OtaPolicy);
    method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
    method public void setPasswordHistoryLength(android.content.ComponentName, int);
    method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -5847,6 +5849,7 @@ package android.app.admin {
    method public void wipeData(int);
    field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
    field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
    field public static final java.lang.String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";
    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
    field public static final java.lang.String ACTION_SEND_DEVICE_INITIALIZER_STATUS = "android.app.action.SEND_DEVICE_INITIALIZER_STATUS";
    field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
@@ -5919,6 +5922,23 @@ package android.app.admin {
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
  }
  public class OtaPolicy {
    ctor public OtaPolicy();
    method public int getInstallWindowEnd();
    method public int getInstallWindowStart();
    method public int getPolicyType();
    method public void setAutomaticInstallPolicy();
    method public void setPostponeInstallPolicy();
    method public void setWindowedInstallPolicy(int, int) throws android.app.admin.OtaPolicy.InvalidWindowException;
    field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1
    field public static final int TYPE_INSTALL_WINDOWED = 2; // 0x2
    field public static final int TYPE_POSTPONE = 3; // 0x3
  }
  public static class OtaPolicy.InvalidWindowException extends java.lang.Exception {
    ctor public OtaPolicy.InvalidWindowException(java.lang.String);
  }
}
package android.app.backup {
+53 −0
Original line number Diff line number Diff line
@@ -753,6 +753,14 @@ public class DevicePolicyManager {
     */
    public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;

    /**
     * Broadcast action: notify that a new local OTA policy has been set by the device owner.
     * The new policy can be retrieved by {@link #getOtaPolicy()}.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";


    /**
     * Return true if the given administrator component is currently
     * active (enabled) in the system.
@@ -4067,4 +4075,49 @@ public class DevicePolicyManager {
            Log.w(TAG, "Could not send device initializer status", re);
        }
    }

    /*
     * Called by device owners to set a local OTA update policy. When a new OTA policy is set,
     * {@link #ACTION_OTA_POLICY_CHANGED} is broadcasted.
     *
     * @param who Which {@link DeviceAdminReceiver} this request is associated with. All components
     * in the device owner package can set OTA policies and the most recent policy takes effect.
     * @param policy the new OTA policy, or null to clear the current policy.
     * @see OtaPolicy
     */
    public void setOtaPolicy(ComponentName who, OtaPolicy policy) {
        if (mService != null) {
            try {
                if (policy != null) {
                    mService.setOtaPolicy(who, policy.getPolicyBundle());
                } else {
                    mService.setOtaPolicy(who, null);
                }
            } catch (RemoteException re) {
                Log.w(TAG, "Error calling setOtaPolicy", re);
            }
        }
    }

    /**
     * Retrieve a local OTA update policy set previously by {@link #setOtaPolicy}.
     *
     * @return The current OTA policy object, or null if no policy is set or the system does not
     * support managed OTA.
     */
    public OtaPolicy getOtaPolicy() {
        if (mService != null) {
            try {
                PersistableBundle bundle = mService.getOtaPolicy();
                if (bundle != null) {
                    return new OtaPolicy(bundle);
                } else {
                    return null;
                }
            } catch (RemoteException re) {
                Log.w(TAG, "Error calling getOtaPolicy", re);
            }
        }
        return null;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -215,4 +215,6 @@ interface IDevicePolicyManager {
    void setUserIcon(in ComponentName admin, in Bitmap icon);

    void sendDeviceInitializerStatus(int statusCode, String description);
    void setOtaPolicy(in ComponentName who, in PersistableBundle policy);
    PersistableBundle getOtaPolicy();
}
+179 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.admin;

import android.annotation.IntDef;
import android.os.PersistableBundle;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A class that represents a local OTA policy set by the device owner.
 *
 * @see DevicePolicyManager#setOtaPolicy
 * @see DevicePolicyManager#getOtaPolicy
 */
public class OtaPolicy {

    /** @hide */
    @IntDef({
        TYPE_INSTALL_AUTOMATIC,
        TYPE_INSTALL_WINDOWED,
        TYPE_POSTPONE})
    @Retention(RetentionPolicy.SOURCE)
    @interface OtaPolicyType {}

    /**
     * Install OTA update automatically as soon as one is available.
     */
    public static final int TYPE_INSTALL_AUTOMATIC = 1;

    /**
     * Install OTA update automatically within a daily maintenance window, for a maximum of two-week
     * period. After that period the OTA will be installed automatically.
     */
    public static final int TYPE_INSTALL_WINDOWED = 2;

    /**
     * Incoming OTA will be blocked for a maximum of two weeks, after which it will be installed
     * automatically.
     */
    public static final int TYPE_POSTPONE = 3;

    private static final String KEY_POLICY_TYPE = "policy_type";
    private static final String KEY_INSTALL_WINDOW_START = "install_window_start";
    private static final String KEY_INSTALL_WINDOW_END = "install_window_end";

    private PersistableBundle mPolicy;

    public  OtaPolicy() {
        mPolicy = new PersistableBundle();
    }

    /**
     * Construct an OtaPolicy object from a bundle.
     * @hide
     */
    public OtaPolicy(PersistableBundle in) {
        mPolicy = new PersistableBundle(in);
    }

    /**
     * Retrieve the underlying bundle where the policy is stored.
     * @hide
     */
    public PersistableBundle getPolicyBundle() {
        return new PersistableBundle(mPolicy);
    }

    /**
     * Set the OTA policy to: install OTA update automatically as soon as one is available.
     */
    public void setAutomaticInstallPolicy() {
        mPolicy.clear();
        mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_AUTOMATIC);
    }

    /**
     * Set the OTA policy to: new OTA update will only be installed automatically when the system
     * clock is inside a daily maintenance window. If the start and end times are the same, the
     * window is considered to include the WHOLE 24 hours, that is, OTAs can install at any time. If
     * the given window in invalid, a {@link OtaPolicy.InvalidWindowException} will be thrown. If
     * start time is later than end time, the window is considered spanning midnight, i.e. end time
     * donates a time on the next day. The maintenance window will last for two weeks, after which
     * the OTA will be installed automatically.
     *
     * @param startTime the start of the maintenance window, measured as the number of minutes from
     * midnight in the device's local time. Must be in the range of [0, 1440).
     * @param endTime the end of the maintenance window, measured as the number of minutes from
     * midnight in the device's local time. Must be in the range of [0, 1440).
     */
    public void setWindowedInstallPolicy(int startTime, int endTime) throws InvalidWindowException{
        if (startTime < 0 || startTime >= 1440 || endTime < 0 || endTime >= 1440) {
            throw new InvalidWindowException("startTime and endTime must be inside [0, 1440)");
        }
        mPolicy.clear();
        mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_WINDOWED);
        mPolicy.putInt(KEY_INSTALL_WINDOW_START, startTime);
        mPolicy.putInt(KEY_INSTALL_WINDOW_END, endTime);
    }

    /**
     * Set the OTA policy to: block installation for a maximum period of two weeks. After the
     * block expires the OTA will be installed automatically.
     */
    public void setPostponeInstallPolicy() {
        mPolicy.clear();
        mPolicy.putInt(KEY_POLICY_TYPE, TYPE_POSTPONE);
    }

    /**
     * Returns the type of OTA policy.
     *
     * @return an integer, either one of {@link #TYPE_INSTALL_AUTOMATIC},
     * {@link #TYPE_INSTALL_WINDOWED} and {@link #TYPE_POSTPONE}, or -1 if no policy has been set.
     */
    @OtaPolicyType
    public int getPolicyType() {
        return mPolicy.getInt(KEY_POLICY_TYPE, -1);
    }

    /**
     * Get the start of the maintenance window.
     *
     * @return the start of the maintenance window measured as the number of minutes from midnight,
     * or -1 if the policy does not have a maintenance window.
     */
    public int getInstallWindowStart() {
        if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
            return mPolicy.getInt(KEY_INSTALL_WINDOW_START, -1);
        } else {
            return -1;
        }
    }

    /**
     * Get the end of the maintenance window.
     *
     * @return the end of the maintenance window measured as the number of minutes from midnight,
     * or -1 if the policy does not have a maintenance window.
     */
    public int getInstallWindowEnd() {
        if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
            return mPolicy.getInt(KEY_INSTALL_WINDOW_END, -1);
        } else {
            return -1;
        }
    }

    @Override
    public String toString() {
        return mPolicy.toString();
    }

    /**
     * Exception thrown by {@link OtaPolicy#setWindowedInstallPolicy(int, int)} in case the
     * specified window is invalid.
     */
    public static class InvalidWindowException extends Exception {
        public InvalidWindowException(String reason) {
            super(reason);
        }
    }
}
Loading