blob: 954db0459f99969a138a0e73a9f533bccb18ba8d [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";
Alex Johnston0f20b0e2020-02-13 16:54:35 +000056 private static final String KEY_FACTORY_RESET_PROTECTION_ENABLED =
57 "factory_reset_protection_enabled";
Alex Johnston011f5c62019-12-18 17:05:57 +000058 private static final String ATTR_VALUE = "value";
59
60 private final List<String> mFactoryResetProtectionAccounts;
Alex Johnston0f20b0e2020-02-13 16:54:35 +000061 private final boolean mFactoryResetProtectionEnabled;
Alex Johnston011f5c62019-12-18 17:05:57 +000062
63 private FactoryResetProtectionPolicy(List<String> factoryResetProtectionAccounts,
Alex Johnston0f20b0e2020-02-13 16:54:35 +000064 boolean factoryResetProtectionEnabled) {
Alex Johnston011f5c62019-12-18 17:05:57 +000065 mFactoryResetProtectionAccounts = factoryResetProtectionAccounts;
Alex Johnston0f20b0e2020-02-13 16:54:35 +000066 mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
Alex Johnston011f5c62019-12-18 17:05:57 +000067 }
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 /**
Alex Johnston0f20b0e2020-02-13 16:54:35 +000077 * Return whether factory reset protection for the device is enabled or not.
Alex Johnston011f5c62019-12-18 17:05:57 +000078 */
Alex Johnston0f20b0e2020-02-13 16:54:35 +000079 public boolean isFactoryResetProtectionEnabled() {
80 return mFactoryResetProtectionEnabled;
Alex Johnston011f5c62019-12-18 17:05:57 +000081 }
82
83 /**
84 * Builder class for {@link FactoryResetProtectionPolicy} objects.
85 */
86 public static class Builder {
87 private List<String> mFactoryResetProtectionAccounts;
Alex Johnston0f20b0e2020-02-13 16:54:35 +000088 private boolean mFactoryResetProtectionEnabled;
Alex Johnston011f5c62019-12-18 17:05:57 +000089
90 /**
91 * Initialize a new Builder to construct a {@link FactoryResetProtectionPolicy}.
92 */
93 public Builder() {
Alex Johnston0f20b0e2020-02-13 16:54:35 +000094 mFactoryResetProtectionEnabled = true;
Alex Johnston011f5c62019-12-18 17:05:57 +000095 };
96
97 /**
98 * Sets which accounts can unlock a device that has been factory reset.
99 * <p>
100 * Once set, the consumer unlock flow will be disabled and only accounts in this list
101 * can unlock factory reset protection after untrusted factory reset.
102 * <p>
103 * It's up to the FRP management agent to interpret the {@code String} as account it
104 * supports. Please consult their relevant documentation for details.
105 *
106 * @param factoryResetProtectionAccounts list of accounts.
107 * @return the same Builder instance.
108 */
109 @NonNull
110 public Builder setFactoryResetProtectionAccounts(
111 @NonNull List<String> factoryResetProtectionAccounts) {
112 mFactoryResetProtectionAccounts = new ArrayList<>(factoryResetProtectionAccounts);
113 return this;
114 }
115
116 /**
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000117 * Sets whether factory reset protection is enabled or not.
Alex Johnston011f5c62019-12-18 17:05:57 +0000118 * <p>
119 * Once disabled, factory reset protection will not kick in all together when the device
120 * goes through untrusted factory reset. This applies to both the consumer unlock flow and
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000121 * the admin account overrides via {@link #setFactoryResetProtectionAccounts}. By default,
122 * factory reset protection is enabled.
Alex Johnston011f5c62019-12-18 17:05:57 +0000123 *
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000124 * @param factoryResetProtectionEnabled Whether the policy is enabled or not.
Alex Johnston011f5c62019-12-18 17:05:57 +0000125 * @return the same Builder instance.
126 */
127 @NonNull
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000128 public Builder setFactoryResetProtectionEnabled(boolean factoryResetProtectionEnabled) {
129 mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
Alex Johnston011f5c62019-12-18 17:05:57 +0000130 return this;
131 }
132
133 /**
134 * Combines all of the attributes that have been set on this {@code Builder}
135 *
136 * @return a new {@link FactoryResetProtectionPolicy} object.
137 */
138 @NonNull
139 public FactoryResetProtectionPolicy build() {
140 return new FactoryResetProtectionPolicy(mFactoryResetProtectionAccounts,
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000141 mFactoryResetProtectionEnabled);
Alex Johnston011f5c62019-12-18 17:05:57 +0000142 }
143 }
144
145 @Override
146 public String toString() {
147 return "FactoryResetProtectionPolicy{"
148 + "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000149 + ", mFactoryResetProtectionEnabled=" + mFactoryResetProtectionEnabled
Alex Johnston011f5c62019-12-18 17:05:57 +0000150 + '}';
151 }
152
153 @Override
154 public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
155 int accountsCount = mFactoryResetProtectionAccounts.size();
156 dest.writeInt(accountsCount);
157 for (String account: mFactoryResetProtectionAccounts) {
158 dest.writeString(account);
159 }
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000160 dest.writeBoolean(mFactoryResetProtectionEnabled);
Alex Johnston011f5c62019-12-18 17:05:57 +0000161 }
162
163 @Override
164 public int describeContents() {
165 return 0;
166 }
167
168 public static final @NonNull Creator<FactoryResetProtectionPolicy> CREATOR =
169 new Creator<FactoryResetProtectionPolicy>() {
170
171 @Override
172 public FactoryResetProtectionPolicy createFromParcel(Parcel in) {
173 List<String> factoryResetProtectionAccounts = new ArrayList<>();
174 int accountsCount = in.readInt();
175 for (int i = 0; i < accountsCount; i++) {
176 factoryResetProtectionAccounts.add(in.readString());
177 }
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000178 boolean factoryResetProtectionEnabled = in.readBoolean();
Alex Johnston011f5c62019-12-18 17:05:57 +0000179
180 return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000181 factoryResetProtectionEnabled);
Alex Johnston011f5c62019-12-18 17:05:57 +0000182 }
183
184 @Override
185 public FactoryResetProtectionPolicy[] newArray(int size) {
186 return new FactoryResetProtectionPolicy[size];
187 }
188 };
189
190 /**
191 * Restore a previously saved FactoryResetProtectionPolicy from XML.
192 * <p>
193 * No validation is required on the reconstructed policy since the XML was previously
194 * created by the system server from a validated policy.
195 * @hide
196 */
197 @Nullable
198 public static FactoryResetProtectionPolicy readFromXml(@NonNull XmlPullParser parser) {
199 try {
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000200 boolean factoryResetProtectionEnabled = Boolean.parseBoolean(
201 parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_ENABLED));
Alex Johnston011f5c62019-12-18 17:05:57 +0000202
203 List<String> factoryResetProtectionAccounts = new ArrayList<>();
204 int outerDepth = parser.getDepth();
205 int type;
206 while ((type = parser.next()) != END_DOCUMENT
207 && (type != END_TAG || parser.getDepth() > outerDepth)) {
208 if (type == END_TAG || type == TEXT) {
209 continue;
210 }
211 if (!parser.getName().equals(KEY_FACTORY_RESET_PROTECTION_ACCOUNT)) {
212 continue;
213 }
214 factoryResetProtectionAccounts.add(
215 parser.getAttributeValue(null, ATTR_VALUE));
216 }
217
218 return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000219 factoryResetProtectionEnabled);
Alex Johnston011f5c62019-12-18 17:05:57 +0000220 } catch (XmlPullParserException | IOException e) {
221 Log.w(LOG_TAG, "Reading from xml failed", e);
222 }
223 return null;
224 }
225
226 /**
227 * @hide
228 */
229 public void writeToXml(@NonNull XmlSerializer out) throws IOException {
Alex Johnston0f20b0e2020-02-13 16:54:35 +0000230 out.attribute(null, KEY_FACTORY_RESET_PROTECTION_ENABLED,
231 Boolean.toString(mFactoryResetProtectionEnabled));
Alex Johnston011f5c62019-12-18 17:05:57 +0000232 for (String account : mFactoryResetProtectionAccounts) {
233 out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
234 out.attribute(null, ATTR_VALUE, account);
235 out.endTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
236 }
237 }
238
239}