Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83a1f6a9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add new Factory reset protection policy APIs"

parents fda69f3a 011f5c6e
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -6764,6 +6764,7 @@ package android.app.admin {
    method @NonNull public java.util.List<java.lang.String> getDelegatedScopes(@Nullable android.content.ComponentName, @NonNull String);
    method public CharSequence getDeviceOwnerLockScreenInfo();
    method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName);
    method @Nullable public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName);
    method @Nullable public String getGlobalPrivateDnsHost(@NonNull android.content.ComponentName);
    method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName);
    method @NonNull public java.util.List<byte[]> getInstalledCaCerts(@Nullable android.content.ComponentName);
@@ -6882,6 +6883,7 @@ package android.app.admin {
    method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
    method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
    method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
    method public void setFactoryResetProtectionPolicy(@NonNull android.content.ComponentName, @Nullable android.app.admin.FactoryResetProtectionPolicy);
    method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName);
    method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
    method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String);
@@ -7116,6 +7118,21 @@ package android.app.admin {
    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DnsEvent> CREATOR;
  }
  public final class FactoryResetProtectionPolicy implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public java.util.List<java.lang.String> getFactoryResetProtectionAccounts();
    method public boolean isFactoryResetProtectionDisabled();
    method public void writeToParcel(@NonNull android.os.Parcel, @Nullable int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FactoryResetProtectionPolicy> CREATOR;
  }
  public static class FactoryResetProtectionPolicy.Builder {
    ctor public FactoryResetProtectionPolicy.Builder();
    method @NonNull public android.app.admin.FactoryResetProtectionPolicy build();
    method @NonNull public android.app.admin.FactoryResetProtectionPolicy.Builder setFactoryResetProtectionAccounts(@NonNull java.util.List<java.lang.String>);
    method @NonNull public android.app.admin.FactoryResetProtectionPolicy.Builder setFactoryResetProtectionDisabled(boolean);
  }
  public class FreezePeriod {
    ctor public FreezePeriod(java.time.MonthDay, java.time.MonthDay);
    method public java.time.MonthDay getEnd();
+1 −0
Original line number Diff line number Diff line
@@ -816,6 +816,7 @@ package android.app.admin {
    field public static final String ACTION_PROVISION_FINALIZATION = "android.app.action.PROVISION_FINALIZATION";
    field public static final String ACTION_PROVISION_FINANCED_DEVICE = "android.app.action.PROVISION_FINANCED_DEVICE";
    field public static final String ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE = "android.app.action.PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE";
    field public static final String ACTION_RESET_PROTECTION_POLICY_CHANGED = "android.app.action.RESET_PROTECTION_POLICY_CHANGED";
    field public static final String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
    field public static final String ACTION_STATE_USER_SETUP_COMPLETE = "android.app.action.STATE_USER_SETUP_COMPLETE";
    field public static final String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
+64 −0
Original line number Diff line number Diff line
@@ -1410,6 +1410,16 @@ public class DevicePolicyManager {
    public static final String ACTION_DEVICE_OWNER_CHANGED
            = "android.app.action.DEVICE_OWNER_CHANGED";
    /**
     * Broadcast action: sent when the factory reset protection (FRP) policy is changed.
     *
     * @see #setFactoryResetProtectionPolicy
     * @hide
     */
    @SystemApi
    public static final String ACTION_RESET_PROTECTION_POLICY_CHANGED =
            "android.app.action.RESET_PROTECTION_POLICY_CHANGED";
    /**
     * The ComponentName of the administrator component.
     *
@@ -4328,6 +4338,60 @@ public class DevicePolicyManager {
        }
    }
    /**
     * Callable by device owner or profile owner of an organization-owned device, to set a
     * factory reset protection (FRP) policy. When a new policy is set, the system
     * notifies the FRP management agent of a policy change by broadcasting
     * {@code ACTION_RESET_PROTECTION_POLICY_CHANGED}.
     *
     * @param admin  Which {@link DeviceAdminReceiver} this request is associated with.
     * @param policy the new FRP policy, or {@code null} to clear the current policy.
     * @throws SecurityException if {@code admin} is not a device owner or a profile owner of
     *                           an organization-owned device.
     * @throws UnsupportedOperationException if factory reset protection is not
     *                           supported on the device.
     */
    public void setFactoryResetProtectionPolicy(@NonNull ComponentName admin,
            @Nullable FactoryResetProtectionPolicy policy) {
        throwIfParentInstance("setFactoryResetProtectionPolicy");
        if (mService != null) {
            try {
                mService.setFactoryResetProtectionPolicy(admin, policy);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }
    /**
     * Callable by device owner or profile owner of an organization-owned device, to retrieve
     * the current factory reset protection (FRP) policy set previously by
     * {@link #setFactoryResetProtectionPolicy}.
     * <p>
     * This method can also be called by the FRP management agent on device, in which case,
     * it can pass {@code null} as the ComponentName.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with or
     *              {@code null} if called by the FRP management agent on device.
     * @return The current FRP policy object or {@code null} if no policy is set.
     * @throws SecurityException if {@code admin} is not a device owner, a profile owner of
     *                           an organization-owned device or the FRP management agent.
     * @throws UnsupportedOperationException if factory reset protection is not
     *                           supported on the device.
     */
    public @Nullable FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(
            @Nullable ComponentName admin) {
        throwIfParentInstance("getFactoryResetProtectionPolicy");
        if (mService != null) {
            try {
                return mService.getFactoryResetProtectionPolicy(admin);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return null;
    }
    /**
     * Called by an application that is administering the device to set the
     * global proxy and exclusion list.
+19 −0
Original line number Diff line number Diff line
/*
 * 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;

parcelable FactoryResetProtectionPolicy;
+237 −0
Original line number Diff line number Diff line
/*
 * 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.Log;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

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.
 * <p>
 * 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)}}.
 *
 * @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_DISABLED =
            "factory_reset_protection_disabled";
    private static final String ATTR_VALUE = "value";

    private final List<String> mFactoryResetProtectionAccounts;
    private final boolean mFactoryResetProtectionDisabled;

    private FactoryResetProtectionPolicy(List<String> factoryResetProtectionAccounts,
            boolean factoryResetProtectionDisabled) {
        mFactoryResetProtectionAccounts = factoryResetProtectionAccounts;
        mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
    }

    /**
     * Get the list of accounts that can provision a device which has been factory reset.
     */
    public @NonNull List<String> getFactoryResetProtectionAccounts() {
        return mFactoryResetProtectionAccounts;
    }

    /**
     * Return whether factory reset protection for the device is disabled or not.
     */
    public boolean isFactoryResetProtectionDisabled() {
        return mFactoryResetProtectionDisabled;
    }

    /**
     * Builder class for {@link FactoryResetProtectionPolicy} objects.
     */
    public static class Builder {
        private List<String> mFactoryResetProtectionAccounts;
        private boolean mFactoryResetProtectionDisabled;

        /**
         * Initialize a new Builder to construct a {@link FactoryResetProtectionPolicy}.
         */
        public Builder() {
        };

        /**
         * Sets which accounts can unlock a device that has been factory reset.
         * <p>
         * Once set, the consumer unlock flow will be disabled and only accounts in this list
         * can unlock factory reset protection after untrusted factory reset.
         * <p>
         * 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<String> factoryResetProtectionAccounts) {
            mFactoryResetProtectionAccounts = new ArrayList<>(factoryResetProtectionAccounts);
            return this;
        }

        /**
         * Sets whether factory reset protection is disabled or not.
         * <p>
         * 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}
         *
         * @param factoryResetProtectionDisabled Whether the policy is disabled or not.
         * @return the same Builder instance.
         */
        @NonNull
        public Builder setFactoryResetProtectionDisabled(boolean factoryResetProtectionDisabled) {
            mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
            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,
                    mFactoryResetProtectionDisabled);
        }
    }

    @Override
    public String toString() {
        return "FactoryResetProtectionPolicy{"
                + "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
                + ", mFactoryResetProtectionDisabled=" + mFactoryResetProtectionDisabled
                + '}';
    }

    @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(mFactoryResetProtectionDisabled);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final @NonNull Creator<FactoryResetProtectionPolicy> CREATOR =
            new Creator<FactoryResetProtectionPolicy>() {

                @Override
                public FactoryResetProtectionPolicy createFromParcel(Parcel in) {
                    List<String> factoryResetProtectionAccounts = new ArrayList<>();
                    int accountsCount = in.readInt();
                    for (int i = 0; i < accountsCount; i++) {
                        factoryResetProtectionAccounts.add(in.readString());
                    }
                    boolean factoryResetProtectionDisabled = in.readBoolean();

                    return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
                            factoryResetProtectionDisabled);
                }

                @Override
                public FactoryResetProtectionPolicy[] newArray(int size) {
                    return new FactoryResetProtectionPolicy[size];
                }
    };

    /**
     * Restore a previously saved FactoryResetProtectionPolicy from XML.
     * <p>
     * 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 XmlPullParser parser) {
        try {
            boolean factoryResetProtectionDisabled = Boolean.parseBoolean(
                    parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_DISABLED));

            List<String> factoryResetProtectionAccounts = new ArrayList<>();
            int outerDepth = parser.getDepth();
            int type;
            while ((type = parser.next()) != END_DOCUMENT
                    && (type != END_TAG || parser.getDepth() > outerDepth)) {
                if (type == END_TAG || type == TEXT) {
                    continue;
                }
                if (!parser.getName().equals(KEY_FACTORY_RESET_PROTECTION_ACCOUNT)) {
                    continue;
                }
                factoryResetProtectionAccounts.add(
                        parser.getAttributeValue(null, ATTR_VALUE));
            }

            return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
                    factoryResetProtectionDisabled);
        } catch (XmlPullParserException | IOException e) {
            Log.w(LOG_TAG, "Reading from xml failed", e);
        }
        return null;
    }

    /**
     * @hide
     */
    public void writeToXml(@NonNull XmlSerializer out) throws IOException {
        out.attribute(null, KEY_FACTORY_RESET_PROTECTION_DISABLED,
                Boolean.toString(mFactoryResetProtectionDisabled));
        for (String account : mFactoryResetProtectionAccounts) {
            out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
            out.attribute(null, ATTR_VALUE, account);
            out.endTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
        }
    }

}
Loading