1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app.admin; 18 19import android.annotation.IntDef; 20import android.os.Parcel; 21import android.os.Parcelable; 22import android.os.PersistableBundle; 23 24import org.xmlpull.v1.XmlPullParser; 25import org.xmlpull.v1.XmlPullParserException; 26import org.xmlpull.v1.XmlSerializer; 27 28import java.io.IOException; 29import java.lang.annotation.Retention; 30import java.lang.annotation.RetentionPolicy; 31 32/** 33 * A class that represents a local system update policy set by the device owner. 34 * 35 * @see DevicePolicyManager#setSystemUpdatePolicy 36 * @see DevicePolicyManager#getSystemUpdatePolicy 37 */ 38public class SystemUpdatePolicy implements Parcelable { 39 40 /** @hide */ 41 @IntDef({ 42 TYPE_INSTALL_AUTOMATIC, 43 TYPE_INSTALL_WINDOWED, 44 TYPE_POSTPONE}) 45 @Retention(RetentionPolicy.SOURCE) 46 @interface SystemUpdatePolicyType {} 47 48 /** 49 * Unknown policy type, used only internally. 50 */ 51 private static final int TYPE_UNKNOWN = -1; 52 /** 53 * Install system update automatically as soon as one is available. 54 */ 55 public static final int TYPE_INSTALL_AUTOMATIC = 1; 56 57 /** 58 * Install system update automatically within a daily maintenance window, for a maximum of 30 59 * days. After the expiration the policy will no longer be effective and the system should 60 * revert back to its normal behavior as if no policy were set. The only exception is 61 * {@link #TYPE_INSTALL_AUTOMATIC} which should still take effect to install system update 62 * immediately. 63 */ 64 public static final int TYPE_INSTALL_WINDOWED = 2; 65 66 /** 67 * Incoming system update will be blocked for a maximum of 30 days, after which the system 68 * should revert back to its normal behavior as if no policy were set. The only exception is 69 * {@link #TYPE_INSTALL_AUTOMATIC} which should still take effect to install system update 70 * immediately. 71 */ 72 public static final int TYPE_POSTPONE = 3; 73 74 private static final String KEY_POLICY_TYPE = "policy_type"; 75 private static final String KEY_INSTALL_WINDOW_START = "install_window_start"; 76 private static final String KEY_INSTALL_WINDOW_END = "install_window_end"; 77 /** 78 * The upper boundary of the daily maintenance window: 24 * 60 minutes. 79 */ 80 private static final int WINDOW_BOUNDARY = 24 * 60; 81 82 @SystemUpdatePolicyType 83 private int mPolicyType; 84 85 private int mMaintenanceWindowStart; 86 private int mMaintenanceWindowEnd; 87 88 89 private SystemUpdatePolicy() { 90 mPolicyType = TYPE_UNKNOWN; 91 } 92 93 /** 94 * Create a policy object and set it to install update automatically as soon as one is 95 * available. 96 * 97 * @see #TYPE_INSTALL_AUTOMATIC 98 */ 99 public static SystemUpdatePolicy createAutomaticInstallPolicy() { 100 SystemUpdatePolicy policy = new SystemUpdatePolicy(); 101 policy.mPolicyType = TYPE_INSTALL_AUTOMATIC; 102 return policy; 103 } 104 105 /** 106 * Create a policy object and set it to: new system update will only be installed automatically 107 * when the system clock is inside a daily maintenance window. If the start and end times are 108 * the same, the window is considered to include the WHOLE 24 hours, that is, updates can 109 * install at any time. If the given window in invalid, a {@link IllegalArgumentException} will 110 * be thrown. If start time is later than end time, the window is considered spanning midnight, 111 * i.e. end time donates a time on the next day. The maintenance window will last for 30 days, 112 * after which the system should revert back to its normal behavior as if no policy were set. 113 * 114 * @param startTime the start of the maintenance window, measured as the number of minutes from 115 * midnight in the device's local time. Must be in the range of [0, 1440). 116 * @param endTime the end of the maintenance window, measured as the number of minutes from 117 * midnight in the device's local time. Must be in the range of [0, 1440). 118 * @see #TYPE_INSTALL_WINDOWED 119 */ 120 public static SystemUpdatePolicy createWindowedInstallPolicy(int startTime, int endTime) { 121 if (startTime < 0 || startTime >= WINDOW_BOUNDARY 122 || endTime < 0 || endTime >= WINDOW_BOUNDARY) { 123 throw new IllegalArgumentException("startTime and endTime must be inside [0, 1440)"); 124 } 125 SystemUpdatePolicy policy = new SystemUpdatePolicy(); 126 policy.mPolicyType = TYPE_INSTALL_WINDOWED; 127 policy.mMaintenanceWindowStart = startTime; 128 policy.mMaintenanceWindowEnd = endTime; 129 return policy; 130 } 131 132 /** 133 * Create a policy object and set it to block installation for a maximum period of 30 days. 134 * After expiration the system should revert back to its normal behavior as if no policy were 135 * set. 136 * 137 * @see #TYPE_POSTPONE 138 */ 139 public static SystemUpdatePolicy createPostponeInstallPolicy() { 140 SystemUpdatePolicy policy = new SystemUpdatePolicy(); 141 policy.mPolicyType = TYPE_POSTPONE; 142 return policy; 143 } 144 145 /** 146 * Returns the type of system update policy. 147 * 148 * @return an integer, either one of {@link #TYPE_INSTALL_AUTOMATIC}, 149 * {@link #TYPE_INSTALL_WINDOWED} and {@link #TYPE_POSTPONE}, or -1 if no policy has been set. 150 */ 151 @SystemUpdatePolicyType 152 public int getPolicyType() { 153 return mPolicyType; 154 } 155 156 /** 157 * Get the start of the maintenance window. 158 * 159 * @return the start of the maintenance window measured as the number of minutes from midnight, 160 * or -1 if the policy does not have a maintenance window. 161 */ 162 public int getInstallWindowStart() { 163 if (mPolicyType == TYPE_INSTALL_WINDOWED) { 164 return mMaintenanceWindowStart; 165 } else { 166 return -1; 167 } 168 } 169 170 /** 171 * Get the end of the maintenance window. 172 * 173 * @return the end of the maintenance window measured as the number of minutes from midnight, 174 * or -1 if the policy does not have a maintenance window. 175 */ 176 public int getInstallWindowEnd() { 177 if (mPolicyType == TYPE_INSTALL_WINDOWED) { 178 return mMaintenanceWindowEnd; 179 } else { 180 return -1; 181 } 182 } 183 184 /** 185 * Return if this object represents a valid policy. 186 * @hide 187 */ 188 public boolean isValid() { 189 if (mPolicyType == TYPE_INSTALL_AUTOMATIC || mPolicyType == TYPE_POSTPONE) { 190 return true; 191 } else if (mPolicyType == TYPE_INSTALL_WINDOWED) { 192 return mMaintenanceWindowStart >= 0 && mMaintenanceWindowStart < WINDOW_BOUNDARY 193 && mMaintenanceWindowEnd >= 0 && mMaintenanceWindowEnd < WINDOW_BOUNDARY; 194 } else { 195 return false; 196 } 197 } 198 199 @Override 200 public String toString() { 201 return String.format("SystemUpdatePolicy (type: %d, windowStart: %d, windowEnd: %d)", 202 mPolicyType, mMaintenanceWindowStart, mMaintenanceWindowEnd); 203 } 204 205 @Override 206 public int describeContents() { 207 return 0; 208 } 209 210 @Override 211 public void writeToParcel(Parcel dest, int flags) { 212 dest.writeInt(mPolicyType); 213 dest.writeInt(mMaintenanceWindowStart); 214 dest.writeInt(mMaintenanceWindowEnd); 215 } 216 217 public static final Parcelable.Creator<SystemUpdatePolicy> CREATOR = 218 new Parcelable.Creator<SystemUpdatePolicy>() { 219 220 @Override 221 public SystemUpdatePolicy createFromParcel(Parcel source) { 222 SystemUpdatePolicy policy = new SystemUpdatePolicy(); 223 policy.mPolicyType = source.readInt(); 224 policy.mMaintenanceWindowStart = source.readInt(); 225 policy.mMaintenanceWindowEnd = source.readInt(); 226 return policy; 227 } 228 229 @Override 230 public SystemUpdatePolicy[] newArray(int size) { 231 return new SystemUpdatePolicy[size]; 232 } 233 }; 234 235 236 /** 237 * @hide 238 */ 239 public static SystemUpdatePolicy restoreFromXml(XmlPullParser parser) { 240 try { 241 SystemUpdatePolicy policy = new SystemUpdatePolicy(); 242 String value = parser.getAttributeValue(null, KEY_POLICY_TYPE); 243 if (value != null) { 244 policy.mPolicyType = Integer.parseInt(value); 245 246 value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_START); 247 if (value != null) { 248 policy.mMaintenanceWindowStart = Integer.parseInt(value); 249 } 250 value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_END); 251 if (value != null) { 252 policy.mMaintenanceWindowEnd = Integer.parseInt(value); 253 } 254 return policy; 255 } 256 } catch (NumberFormatException e) { 257 // Fail through 258 } 259 return null; 260 } 261 262 /** 263 * @hide 264 */ 265 public void saveToXml(XmlSerializer out) throws IOException { 266 out.attribute(null, KEY_POLICY_TYPE, Integer.toString(mPolicyType)); 267 out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart)); 268 out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd)); 269 } 270} 271 272