/* * Copyright (C) 2019 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 static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.TEXT; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; import android.util.IndentingPrintWriter; import android.util.Log; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * The factory reset protection policy determines which accounts can unlock a device that * has gone through untrusted factory reset. *
* Only a device owner or profile owner of an organization-owned device can set a factory * reset protection policy for the device by calling the {@code DevicePolicyManager} method * {@link DevicePolicyManager#setFactoryResetProtectionPolicy(ComponentName, * FactoryResetProtectionPolicy)}}. *
* Normally factory reset protection does not kick in if the device is factory reset via Settings.
* This is also the case when a device owner sets factory reset protection policy. However,
* when a profile owner of an organization-owned device sets factory reset protection policy that
* locks the device to specific accounts, the policy will take effect even if factory reset is
* performed from Settings.
*
* @see DevicePolicyManager#setFactoryResetProtectionPolicy
* @see DevicePolicyManager#getFactoryResetProtectionPolicy
*/
public final class FactoryResetProtectionPolicy implements Parcelable {
private static final String LOG_TAG = "FactoryResetProtectionPolicy";
private static final String KEY_FACTORY_RESET_PROTECTION_ACCOUNT =
"factory_reset_protection_account";
private static final String KEY_FACTORY_RESET_PROTECTION_ENABLED =
"factory_reset_protection_enabled";
private static final String ATTR_VALUE = "value";
private final List
* Once set, the consumer unlock flow will be disabled and only accounts in this list
* can unlock factory reset protection after untrusted factory reset.
*
* It's up to the FRP management agent to interpret the {@code String} as account it
* supports. Please consult their relevant documentation for details.
*
* @param factoryResetProtectionAccounts list of accounts.
* @return the same Builder instance.
*/
@NonNull
public Builder setFactoryResetProtectionAccounts(
@NonNull List
* Once disabled, factory reset protection will not kick in all together when the device
* goes through untrusted factory reset. This applies to both the consumer unlock flow and
* the admin account overrides via {@link #setFactoryResetProtectionAccounts}. By default,
* factory reset protection is enabled.
*
* @param factoryResetProtectionEnabled Whether the policy is enabled or not.
* @return the same Builder instance.
*/
@NonNull
public Builder setFactoryResetProtectionEnabled(boolean factoryResetProtectionEnabled) {
mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
return this;
}
/**
* Combines all of the attributes that have been set on this {@code Builder}
*
* @return a new {@link FactoryResetProtectionPolicy} object.
*/
@NonNull
public FactoryResetProtectionPolicy build() {
return new FactoryResetProtectionPolicy(mFactoryResetProtectionAccounts,
mFactoryResetProtectionEnabled);
}
}
@Override
public String toString() {
return "FactoryResetProtectionPolicy{"
+ "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
+ ", mFactoryResetProtectionEnabled=" + mFactoryResetProtectionEnabled
+ '}';
}
@Override
public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
int accountsCount = mFactoryResetProtectionAccounts.size();
dest.writeInt(accountsCount);
for (String account: mFactoryResetProtectionAccounts) {
dest.writeString(account);
}
dest.writeBoolean(mFactoryResetProtectionEnabled);
}
@Override
public int describeContents() {
return 0;
}
public static final @NonNull Creator
* No validation is required on the reconstructed policy since the XML was previously
* created by the system server from a validated policy.
* @hide
*/
@Nullable
public static FactoryResetProtectionPolicy readFromXml(@NonNull TypedXmlPullParser parser) {
try {
boolean factoryResetProtectionEnabled = parser.getAttributeBoolean(null,
KEY_FACTORY_RESET_PROTECTION_ENABLED, false);
List
* When a device has a non-empty factory reset protection policy, trusted factory reset
* via Settings will no longer remove factory reset protection from the device.
* @hide
*/
public boolean isNotEmpty() {
return !mFactoryResetProtectionAccounts.isEmpty() && mFactoryResetProtectionEnabled;
}
/**
* @hide
*/
public void dump(IndentingPrintWriter pw) {
pw.print("factoryResetProtectionEnabled=");
pw.println(mFactoryResetProtectionEnabled);
pw.print("factoryResetProtectionAccounts=");
pw.increaseIndent();
for (int i = 0; i < mFactoryResetProtectionAccounts.size(); i++) {
pw.println(mFactoryResetProtectionAccounts.get(i));
}
pw.decreaseIndent();
}
}