blob: ed7477936f9cd31bd22cb39780ef76b051ada592 [file] [log] [blame]
Alex Johnston011f5c62019-12-18 17:05:57 +00001/*
2 * Copyright (C) 2019 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 static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
20import static org.xmlpull.v1.XmlPullParser.END_TAG;
21import static org.xmlpull.v1.XmlPullParser.TEXT;
22
23import android.annotation.NonNull;
24import android.annotation.Nullable;
25import android.content.ComponentName;
26import android.os.Parcel;
27import android.os.Parcelable;
28import android.util.Log;
29
30import org.xmlpull.v1.XmlPullParser;
31import org.xmlpull.v1.XmlPullParserException;
32import org.xmlpull.v1.XmlSerializer;
33
34import java.io.IOException;
35import java.util.ArrayList;
36import java.util.List;
37
38/**
39 * The factory reset protection policy determines which accounts can unlock a device that
40 * has gone through untrusted factory reset.
41 * <p>
42 * Only a device owner or profile owner of an organization-owned device can set a factory
43 * reset protection policy for the device by calling the {@code DevicePolicyManager} method
44 * {@link DevicePolicyManager#setFactoryResetProtectionPolicy(ComponentName,
45 * FactoryResetProtectionPolicy)}}.
46 *
47 * @see DevicePolicyManager#setFactoryResetProtectionPolicy
48 * @see DevicePolicyManager#getFactoryResetProtectionPolicy
49 */
50public final class FactoryResetProtectionPolicy implements Parcelable {
51
52 private static final String LOG_TAG = "FactoryResetProtectionPolicy";
53
54 private static final String KEY_FACTORY_RESET_PROTECTION_ACCOUNT =
55 "factory_reset_protection_account";
56 private static final String KEY_FACTORY_RESET_PROTECTION_DISABLED =
57 "factory_reset_protection_disabled";
58 private static final String ATTR_VALUE = "value";
59
60 private final List<String> mFactoryResetProtectionAccounts;
61 private final boolean mFactoryResetProtectionDisabled;
62
63 private FactoryResetProtectionPolicy(List<String> factoryResetProtectionAccounts,
64 boolean factoryResetProtectionDisabled) {
65 mFactoryResetProtectionAccounts = factoryResetProtectionAccounts;
66 mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
67 }
68
69 /**
70 * Get the list of accounts that can provision a device which has been factory reset.
71 */
72 public @NonNull List<String> getFactoryResetProtectionAccounts() {
73 return mFactoryResetProtectionAccounts;
74 }
75
76 /**
77 * Return whether factory reset protection for the device is disabled or not.
78 */
79 public boolean isFactoryResetProtectionDisabled() {
80 return mFactoryResetProtectionDisabled;
81 }
82
83 /**
84 * Builder class for {@link FactoryResetProtectionPolicy} objects.
85 */
86 public static class Builder {
87 private List<String> mFactoryResetProtectionAccounts;
88 private boolean mFactoryResetProtectionDisabled;
89
90 /**
91 * Initialize a new Builder to construct a {@link FactoryResetProtectionPolicy}.
92 */
93 public Builder() {
94 };
95
96 /**
97 * Sets which accounts can unlock a device that has been factory reset.
98 * <p>
99 * Once set, the consumer unlock flow will be disabled and only accounts in this list
100 * can unlock factory reset protection after untrusted factory reset.
101 * <p>
102 * It's up to the FRP management agent to interpret the {@code String} as account it
103 * supports. Please consult their relevant documentation for details.
104 *
105 * @param factoryResetProtectionAccounts list of accounts.
106 * @return the same Builder instance.
107 */
108 @NonNull
109 public Builder setFactoryResetProtectionAccounts(
110 @NonNull List<String> factoryResetProtectionAccounts) {
111 mFactoryResetProtectionAccounts = new ArrayList<>(factoryResetProtectionAccounts);
112 return this;
113 }
114
115 /**
116 * Sets whether factory reset protection is disabled or not.
117 * <p>
118 * Once disabled, factory reset protection will not kick in all together when the device
119 * goes through untrusted factory reset. This applies to both the consumer unlock flow and
120 * the admin account overrides via {@link #setFactoryResetProtectionAccounts}
121 *
122 * @param factoryResetProtectionDisabled Whether the policy is disabled or not.
123 * @return the same Builder instance.
124 */
125 @NonNull
126 public Builder setFactoryResetProtectionDisabled(boolean factoryResetProtectionDisabled) {
127 mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
128 return this;
129 }
130
131 /**
132 * Combines all of the attributes that have been set on this {@code Builder}
133 *
134 * @return a new {@link FactoryResetProtectionPolicy} object.
135 */
136 @NonNull
137 public FactoryResetProtectionPolicy build() {
138 return new FactoryResetProtectionPolicy(mFactoryResetProtectionAccounts,
139 mFactoryResetProtectionDisabled);
140 }
141 }
142
143 @Override
144 public String toString() {
145 return "FactoryResetProtectionPolicy{"
146 + "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
147 + ", mFactoryResetProtectionDisabled=" + mFactoryResetProtectionDisabled
148 + '}';
149 }
150
151 @Override
152 public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
153 int accountsCount = mFactoryResetProtectionAccounts.size();
154 dest.writeInt(accountsCount);
155 for (String account: mFactoryResetProtectionAccounts) {
156 dest.writeString(account);
157 }
158 dest.writeBoolean(mFactoryResetProtectionDisabled);
159 }
160
161 @Override
162 public int describeContents() {
163 return 0;
164 }
165
166 public static final @NonNull Creator<FactoryResetProtectionPolicy> CREATOR =
167 new Creator<FactoryResetProtectionPolicy>() {
168
169 @Override
170 public FactoryResetProtectionPolicy createFromParcel(Parcel in) {
171 List<String> factoryResetProtectionAccounts = new ArrayList<>();
172 int accountsCount = in.readInt();
173 for (int i = 0; i < accountsCount; i++) {
174 factoryResetProtectionAccounts.add(in.readString());
175 }
176 boolean factoryResetProtectionDisabled = in.readBoolean();
177
178 return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
179 factoryResetProtectionDisabled);
180 }
181
182 @Override
183 public FactoryResetProtectionPolicy[] newArray(int size) {
184 return new FactoryResetProtectionPolicy[size];
185 }
186 };
187
188 /**
189 * Restore a previously saved FactoryResetProtectionPolicy from XML.
190 * <p>
191 * No validation is required on the reconstructed policy since the XML was previously
192 * created by the system server from a validated policy.
193 * @hide
194 */
195 @Nullable
196 public static FactoryResetProtectionPolicy readFromXml(@NonNull XmlPullParser parser) {
197 try {
198 boolean factoryResetProtectionDisabled = Boolean.parseBoolean(
199 parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_DISABLED));
200
201 List<String> factoryResetProtectionAccounts = new ArrayList<>();
202 int outerDepth = parser.getDepth();
203 int type;
204 while ((type = parser.next()) != END_DOCUMENT
205 && (type != END_TAG || parser.getDepth() > outerDepth)) {
206 if (type == END_TAG || type == TEXT) {
207 continue;
208 }
209 if (!parser.getName().equals(KEY_FACTORY_RESET_PROTECTION_ACCOUNT)) {
210 continue;
211 }
212 factoryResetProtectionAccounts.add(
213 parser.getAttributeValue(null, ATTR_VALUE));
214 }
215
216 return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
217 factoryResetProtectionDisabled);
218 } catch (XmlPullParserException | IOException e) {
219 Log.w(LOG_TAG, "Reading from xml failed", e);
220 }
221 return null;
222 }
223
224 /**
225 * @hide
226 */
227 public void writeToXml(@NonNull XmlSerializer out) throws IOException {
228 out.attribute(null, KEY_FACTORY_RESET_PROTECTION_DISABLED,
229 Boolean.toString(mFactoryResetProtectionDisabled));
230 for (String account : mFactoryResetProtectionAccounts) {
231 out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
232 out.attribute(null, ATTR_VALUE, account);
233 out.endTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
234 }
235 }
236
237}