blob: abcd92bbeb64ea4dafedd42fc815d9adcf5f519e [file] [log] [blame]
/*
* Copyright 2016, 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 com.android.managedprovisioning.model;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.accounts.Account;
import android.content.Context;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import com.android.internal.annotations.Immutable;
import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
import com.android.managedprovisioning.common.Utils;
/**
* Provisioning parameters for Device Owner and Profile Owner provisioning.
*/
public final class ProvisioningParams implements Parcelable {
public static final long DEFAULT_LOCAL_TIME = -1;
public static final Integer DEFAULT_MAIN_COLOR = null;
public static final boolean DEFAULT_STARTED_BY_TRUSTED_SOURCE = false;
public static final boolean DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED = false;
public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION = false;
public static final boolean DEFAULT_SKIP_USER_SETUP = true;
// Intent extra used internally for passing data between activities and service.
public static final String EXTRA_PROVISIONING_PARAMS = "provisioningParams";
public static final Parcelable.Creator<ProvisioningParams> CREATOR
= new Parcelable.Creator<ProvisioningParams>() {
@Override
public ProvisioningParams createFromParcel(Parcel in) {
return new ProvisioningParams(in);
}
@Override
public ProvisioningParams[] newArray(int size) {
return new ProvisioningParams[size];
}
};
@Nullable
public final String timeZone;
public final long localTime;
@Nullable
public final Locale locale;
/** WiFi configuration. */
@Nullable
public final WifiInfo wifiInfo;
/**
* Package name of the device admin package.
*
* <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
* non-null.
*/
@Deprecated
public final String deviceAdminPackageName;
/**
* {@link ComponentName} of the device admin package.
*
* <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
* non-null.
*/
public final ComponentName deviceAdminComponentName;
/** {@link Account} that should be migrated to the managed profile. */
@Nullable
public final Account accountToMigrate;
/** Provisioning action comes along with the provisioning data. */
public final String provisioningAction;
/**
* The main color theme used in managed profile only.
*
* <p>{@code null} means the default value.
*/
@Nullable
public final Integer mainColor;
/** The download information of device admin package. */
@Nullable
public final PackageDownloadInfo deviceAdminDownloadInfo;
/**
* Custom key-value pairs from enterprise mobility management which are passed to device admin
* package after provisioning.
*
* <p>Note that {@link ProvisioningParams} is not immutable because this field is mutable.
*/
@Nullable
public final PersistableBundle adminExtrasBundle;
/**
* True iff provisioning flow was started by a trusted app. This includes Nfc bump and QR code.
*/
public final boolean startedByTrustedSource;
/** True if all system apps should be enabled after provisioning. */
public final boolean leaveAllSystemAppsEnabled;
/** True if device encryption should be skipped. */
public final boolean skipEncryption;
/** True if user setup can be skipped. */
public final boolean skipUserSetup;
// TODO (stevenckng): This shouldn't belong here. Remove this logic from ProvisioningParams.
private ComponentName inferedDeviceAdminComponentName;
private final Utils mUtils = new Utils();
public String inferDeviceAdminPackageName() {
if (deviceAdminComponentName != null) {
return deviceAdminComponentName.getPackageName();
}
return deviceAdminPackageName;
}
// This should not be called if the app has not been installed yet.
public ComponentName inferDeviceAdminComponentName(Context c)
throws IllegalProvisioningArgumentException {
if (inferedDeviceAdminComponentName == null) {
inferedDeviceAdminComponentName = mUtils.findDeviceAdmin(
deviceAdminPackageName, deviceAdminComponentName, c);
}
return inferedDeviceAdminComponentName;
}
private ProvisioningParams(Builder builder) {
timeZone = builder.mTimeZone;
localTime = builder.mLocalTime;
locale = builder.mLocale;
wifiInfo = builder.mWifiInfo;
deviceAdminComponentName = builder.mDeviceAdminComponentName;
deviceAdminPackageName = builder.mDeviceAdminPackageName;
deviceAdminDownloadInfo = builder.mDeviceAdminDownloadInfo;
adminExtrasBundle = builder.mAdminExtrasBundle;
startedByTrustedSource = builder.mStartedByTrustedSource;
leaveAllSystemAppsEnabled = builder.mLeaveAllSystemAppsEnabled;
skipEncryption = builder.mSkipEncryption;
accountToMigrate = builder.mAccountToMigrate;
provisioningAction = checkNotNull(builder.mProvisioningAction);
mainColor = builder.mMainColor;
skipUserSetup = builder.mSkipUserSetup;
validateFields();
}
private ProvisioningParams(Parcel in) {
timeZone = in.readString();
localTime = in.readLong();
locale = (Locale) in.readSerializable();
wifiInfo = (WifiInfo) in.readParcelable(WifiInfo.class.getClassLoader());
deviceAdminPackageName = in.readString();
deviceAdminComponentName = (ComponentName)
in.readParcelable(null /* use default classloader */);
deviceAdminDownloadInfo =
(PackageDownloadInfo) in.readParcelable(PackageDownloadInfo.class.getClassLoader());
adminExtrasBundle = in.readParcelable(null /* use default classloader */);
startedByTrustedSource = in.readInt() == 1;
leaveAllSystemAppsEnabled = in.readInt() == 1;
skipEncryption = in.readInt() == 1;
accountToMigrate = (Account) in.readParcelable(null /* use default classloader */);
provisioningAction = checkNotNull(in.readString());
if (in.readInt() != 0) {
mainColor = in.readInt();
} else {
mainColor = null;
}
skipUserSetup = in.readInt() == 1;
validateFields();
}
private void validateFields() {
checkArgument(deviceAdminPackageName != null || deviceAdminComponentName != null);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(timeZone);
out.writeLong(localTime);
out.writeSerializable(locale);
out.writeParcelable(wifiInfo, 0 /* default */ );
out.writeString(deviceAdminPackageName);
out.writeParcelable(deviceAdminComponentName, 0 /* default */);
out.writeParcelable(deviceAdminDownloadInfo, 0 /* default */);
out.writeParcelable(adminExtrasBundle, 0 /* default */);
out.writeInt(startedByTrustedSource ? 1 : 0);
out.writeInt(leaveAllSystemAppsEnabled ? 1 : 0);
out.writeInt(skipEncryption ? 1 : 0);
out.writeParcelable(accountToMigrate, 0 /* default */);
out.writeString(provisioningAction);
if (mainColor != null) {
out.writeInt(1);
out.writeInt(mainColor);
} else {
out.writeInt(0);
}
out.writeInt(skipUserSetup ? 1 : 0);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ProvisioningParams that = (ProvisioningParams) o;
return localTime == that.localTime
&& startedByTrustedSource == that.startedByTrustedSource
&& leaveAllSystemAppsEnabled == that.leaveAllSystemAppsEnabled
&& skipEncryption == that.skipEncryption
&& skipUserSetup == that.skipUserSetup
&& Objects.equals(timeZone, that.timeZone)
&& Objects.equals(locale, that.locale)
&& Objects.equals(wifiInfo, that.wifiInfo)
&& Objects.equals(deviceAdminPackageName, that.deviceAdminPackageName)
&& Objects.equals(deviceAdminComponentName, that.deviceAdminComponentName)
&& Objects.equals(accountToMigrate, that.accountToMigrate)
&& Objects.equals(provisioningAction, that.provisioningAction)
&& Objects.equals(mainColor, that.mainColor)
&& Objects.equals(deviceAdminDownloadInfo, that.deviceAdminDownloadInfo)
&& isPersistableBundleEquals(adminExtrasBundle, that.adminExtrasBundle)
&& Objects.equals(
inferedDeviceAdminComponentName, that.inferedDeviceAdminComponentName);
}
/**
* Compares two {@link PersistableBundle} objects are equals.
*/
private static boolean isPersistableBundleEquals(
PersistableBundle obj1, PersistableBundle obj2) {
if (obj1 == obj2) {
return true;
}
if (obj1 == null || obj2 == null || obj1.size() != obj2.size()) {
return false;
}
Set<String> keys = obj1.keySet();
for (String key : keys) {
Object val1 = obj1.get(key);
Object val2 = obj2.get(key);
if (!isPersistableBundleSupportedValueEquals(val1, val2)) {
return false;
}
}
return true;
}
/**
* Compares two values which type is supported by {@link PersistableBundle}.
*
* <p>If the type isn't supported. The equality is done by {@link Object#equals(Object)}.
*/
private static boolean isPersistableBundleSupportedValueEquals(Object val1, Object val2) {
if (val1 == val2) {
return true;
} else if (val1 == null || val2 == null || !val1.getClass().equals(val2.getClass())) {
return false;
} else if (val1 instanceof PersistableBundle && val2 instanceof PersistableBundle) {
return isPersistableBundleEquals((PersistableBundle) val1, (PersistableBundle) val2);
} else if (val1 instanceof int[]) {
return Arrays.equals((int[]) val1, (int[]) val2);
} else if (val1 instanceof long[]) {
return Arrays.equals((long[]) val1, (long[]) val2);
} else if (val1 instanceof double[]) {
return Arrays.equals((double[]) val1, (double[]) val2);
} else if (val1 instanceof boolean[]) {
return Arrays.equals((boolean[]) val1, (boolean[]) val2);
} else if (val1 instanceof String[]) {
return Arrays.equals((String[]) val1, (String[]) val2);
} else {
return Objects.equals(val1, val2);
}
}
public final static class Builder {
private String mTimeZone;
private long mLocalTime = DEFAULT_LOCAL_TIME;
private Locale mLocale;
private WifiInfo mWifiInfo;
private String mDeviceAdminPackageName;
private ComponentName mDeviceAdminComponentName;
private Account mAccountToMigrate;
private String mProvisioningAction;
private Integer mMainColor = DEFAULT_MAIN_COLOR;
private PackageDownloadInfo mDeviceAdminDownloadInfo;
private PersistableBundle mAdminExtrasBundle;
private boolean mStartedByTrustedSource = DEFAULT_STARTED_BY_TRUSTED_SOURCE;
private boolean mLeaveAllSystemAppsEnabled = DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED;
private boolean mSkipEncryption = DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION;
private boolean mSkipUserSetup = DEFAULT_SKIP_USER_SETUP;
public Builder setTimeZone(String timeZone) {
mTimeZone = timeZone;
return this;
}
public Builder setLocalTime(long localTime) {
mLocalTime = localTime;
return this;
}
public Builder setLocale(Locale locale) {
mLocale = locale;
return this;
}
public Builder setWifiInfo(WifiInfo wifiInfo) {
mWifiInfo = wifiInfo;
return this;
}
@Deprecated
public Builder setDeviceAdminPackageName(String deviceAdminPackageName) {
mDeviceAdminPackageName = deviceAdminPackageName;
return this;
}
public Builder setDeviceAdminComponentName(ComponentName deviceAdminComponentName) {
mDeviceAdminComponentName = deviceAdminComponentName;
return this;
}
public Builder setAccountToMigrate(Account accountToMigrate) {
mAccountToMigrate = accountToMigrate;
return this;
}
public Builder setProvisioningAction(String provisioningAction) {
mProvisioningAction = provisioningAction;
return this;
}
public Builder setMainColor(Integer mainColor) {
mMainColor = mainColor;
return this;
}
public Builder setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo) {
mDeviceAdminDownloadInfo = deviceAdminDownloadInfo;
return this;
}
public Builder setAdminExtrasBundle(PersistableBundle adminExtrasBundle) {
mAdminExtrasBundle = adminExtrasBundle;
return this;
}
public Builder setStartedByTrustedSource(boolean startedByTrustedSource) {
mStartedByTrustedSource = startedByTrustedSource;
return this;
}
public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) {
mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
return this;
}
public Builder setSkipEncryption(boolean skipEncryption) {
mSkipEncryption = skipEncryption;
return this;
}
public Builder setSkipUserSetup(boolean skipUserSetup) {
mSkipUserSetup = skipUserSetup;
return this;
}
public ProvisioningParams build() {
return new ProvisioningParams(this);
}
public static Builder builder() {
return new Builder();
}
}
}