/* * 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.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A class that represents a local system update policy set by the device owner. * * @see DevicePolicyManager#setSystemUpdatePolicy * @see DevicePolicyManager#getSystemUpdatePolicy */ public class SystemUpdatePolicy implements Parcelable { /** @hide */ @IntDef({ TYPE_INSTALL_AUTOMATIC, TYPE_INSTALL_WINDOWED, TYPE_POSTPONE}) @Retention(RetentionPolicy.SOURCE) @interface SystemUpdatePolicyType {} /** * Unknown policy type, used only internally. */ private static final int TYPE_UNKNOWN = -1; /** * Install system update automatically as soon as one is available. */ public static final int TYPE_INSTALL_AUTOMATIC = 1; /** * Install system update automatically within a daily maintenance window, for a maximum of 30 * days. After the expiration the policy will no longer be effective and the system should * revert back to its normal behavior as if no policy were set. The only exception is * {@link #TYPE_INSTALL_AUTOMATIC} which should still take effect to install system update * immediately. */ public static final int TYPE_INSTALL_WINDOWED = 2; /** * Incoming system update will be blocked for a maximum of 30 days, after which the system * should revert back to its normal behavior as if no policy were set. The only exception is * {@link #TYPE_INSTALL_AUTOMATIC} which should still take effect to install system update * immediately. */ 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"; /** * The upper boundary of the daily maintenance window: 24 * 60 minutes. */ private static final int WINDOW_BOUNDARY = 24 * 60; @SystemUpdatePolicyType private int mPolicyType; private int mMaintenanceWindowStart; private int mMaintenanceWindowEnd; private SystemUpdatePolicy() { mPolicyType = TYPE_UNKNOWN; } /** * Create a policy object and set it to install update automatically as soon as one is * available. * * @see #TYPE_INSTALL_AUTOMATIC */ public static SystemUpdatePolicy createAutomaticInstallPolicy() { SystemUpdatePolicy policy = new SystemUpdatePolicy(); policy.mPolicyType = TYPE_INSTALL_AUTOMATIC; return policy; } /** * Create a policy object and set it to: new system 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, updates can * install at any time. If the given window in invalid, a {@link IllegalArgumentException} 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 30 days, * after which the system should revert back to its normal behavior as if no policy were set. * * @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). * @see #TYPE_INSTALL_WINDOWED */ public static SystemUpdatePolicy createWindowedInstallPolicy(int startTime, int endTime) { if (startTime < 0 || startTime >= WINDOW_BOUNDARY || endTime < 0 || endTime >= WINDOW_BOUNDARY) { throw new IllegalArgumentException("startTime and endTime must be inside [0, 1440)"); } SystemUpdatePolicy policy = new SystemUpdatePolicy(); policy.mPolicyType = TYPE_INSTALL_WINDOWED; policy.mMaintenanceWindowStart = startTime; policy.mMaintenanceWindowEnd = endTime; return policy; } /** * Create a policy object and set it to block installation for a maximum period of 30 days. * After expiration the system should revert back to its normal behavior as if no policy were * set. * * @see #TYPE_POSTPONE */ public static SystemUpdatePolicy createPostponeInstallPolicy() { SystemUpdatePolicy policy = new SystemUpdatePolicy(); policy.mPolicyType = TYPE_POSTPONE; return policy; } /** * Returns the type of system update 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. */ @SystemUpdatePolicyType public int getPolicyType() { return mPolicyType; } /** * 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 (mPolicyType == TYPE_INSTALL_WINDOWED) { return mMaintenanceWindowStart; } 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 (mPolicyType == TYPE_INSTALL_WINDOWED) { return mMaintenanceWindowEnd; } else { return -1; } } /** * Return if this object represents a valid policy. * @hide */ public boolean isValid() { if (mPolicyType == TYPE_INSTALL_AUTOMATIC || mPolicyType == TYPE_POSTPONE) { return true; } else if (mPolicyType == TYPE_INSTALL_WINDOWED) { return mMaintenanceWindowStart >= 0 && mMaintenanceWindowStart < WINDOW_BOUNDARY && mMaintenanceWindowEnd >= 0 && mMaintenanceWindowEnd < WINDOW_BOUNDARY; } else { return false; } } @Override public String toString() { return String.format("SystemUpdatePolicy (type: %d, windowStart: %d, windowEnd: %d)", mPolicyType, mMaintenanceWindowStart, mMaintenanceWindowEnd); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mPolicyType); dest.writeInt(mMaintenanceWindowStart); dest.writeInt(mMaintenanceWindowEnd); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public SystemUpdatePolicy createFromParcel(Parcel source) { SystemUpdatePolicy policy = new SystemUpdatePolicy(); policy.mPolicyType = source.readInt(); policy.mMaintenanceWindowStart = source.readInt(); policy.mMaintenanceWindowEnd = source.readInt(); return policy; } @Override public SystemUpdatePolicy[] newArray(int size) { return new SystemUpdatePolicy[size]; } }; /** * @hide */ public static SystemUpdatePolicy restoreFromXml(XmlPullParser parser) { try { SystemUpdatePolicy policy = new SystemUpdatePolicy(); String value = parser.getAttributeValue(null, KEY_POLICY_TYPE); if (value != null) { policy.mPolicyType = Integer.parseInt(value); value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_START); if (value != null) { policy.mMaintenanceWindowStart = Integer.parseInt(value); } value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_END); if (value != null) { policy.mMaintenanceWindowEnd = Integer.parseInt(value); } return policy; } } catch (NumberFormatException e) { // Fail through } return null; } /** * @hide */ public void saveToXml(XmlSerializer out) throws IOException { out.attribute(null, KEY_POLICY_TYPE, Integer.toString(mPolicyType)); out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart)); out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd)); } }