Home | History | Annotate | Download | only in model
      1 /*
      2  * Copyright 2016, 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 
     17 package com.android.managedprovisioning.model;
     18 
     19 import static com.android.internal.util.Preconditions.checkArgument;
     20 import static com.android.internal.util.Preconditions.checkNotNull;
     21 
     22 
     23 import android.accounts.Account;
     24 import android.content.Context;
     25 import android.content.ComponentName;
     26 import android.os.Parcel;
     27 import android.os.Parcelable;
     28 import android.os.PersistableBundle;
     29 import android.support.annotation.Nullable;
     30 import android.text.TextUtils;
     31 
     32 import java.util.Arrays;
     33 import java.util.Locale;
     34 import java.util.Objects;
     35 import java.util.Set;
     36 
     37 import com.android.internal.annotations.Immutable;
     38 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
     39 import com.android.managedprovisioning.common.Utils;
     40 
     41 /**
     42  * Provisioning parameters for Device Owner and Profile Owner provisioning.
     43  */
     44 public final class ProvisioningParams implements Parcelable {
     45     public static final long DEFAULT_LOCAL_TIME = -1;
     46     public static final Integer DEFAULT_MAIN_COLOR = null;
     47     public static final boolean DEFAULT_STARTED_BY_TRUSTED_SOURCE = false;
     48     public static final boolean DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED = false;
     49     public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION = false;
     50     public static final boolean DEFAULT_SKIP_USER_SETUP = true;
     51     // Intent extra used internally for passing data between activities and service.
     52     public static final String EXTRA_PROVISIONING_PARAMS = "provisioningParams";
     53 
     54     public static final Parcelable.Creator<ProvisioningParams> CREATOR
     55             = new Parcelable.Creator<ProvisioningParams>() {
     56         @Override
     57         public ProvisioningParams createFromParcel(Parcel in) {
     58             return new ProvisioningParams(in);
     59         }
     60 
     61         @Override
     62         public ProvisioningParams[] newArray(int size) {
     63             return new ProvisioningParams[size];
     64         }
     65     };
     66 
     67     @Nullable
     68     public final String timeZone;
     69 
     70     public final long localTime;
     71 
     72     @Nullable
     73     public final Locale locale;
     74 
     75     /** WiFi configuration. */
     76     @Nullable
     77     public final WifiInfo wifiInfo;
     78 
     79     /**
     80      * Package name of the device admin package.
     81      *
     82      * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
     83      * non-null.
     84      */
     85     @Deprecated
     86     public final String deviceAdminPackageName;
     87 
     88     /**
     89      * {@link ComponentName} of the device admin package.
     90      *
     91      * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
     92      * non-null.
     93      */
     94     public final ComponentName deviceAdminComponentName;
     95 
     96     /** {@link Account} that should be migrated to the managed profile. */
     97     @Nullable
     98     public final Account accountToMigrate;
     99 
    100     /** Provisioning action comes along with the provisioning data. */
    101     public final String provisioningAction;
    102 
    103     /**
    104      * The main color theme used in managed profile only.
    105      *
    106      * <p>{@code null} means the default value.
    107      */
    108     @Nullable
    109     public final Integer mainColor;
    110 
    111     /** The download information of device admin package. */
    112     @Nullable
    113     public final PackageDownloadInfo deviceAdminDownloadInfo;
    114 
    115     /**
    116      * Custom key-value pairs from enterprise mobility management which are passed to device admin
    117      * package after provisioning.
    118      *
    119      * <p>Note that {@link ProvisioningParams} is not immutable because this field is mutable.
    120      */
    121     @Nullable
    122     public final PersistableBundle adminExtrasBundle;
    123 
    124     /**
    125      * True iff provisioning flow was started by a trusted app. This includes Nfc bump and QR code.
    126      */
    127     public final boolean startedByTrustedSource;
    128 
    129     /** True if all system apps should be enabled after provisioning. */
    130     public final boolean leaveAllSystemAppsEnabled;
    131 
    132     /** True if device encryption should be skipped. */
    133     public final boolean skipEncryption;
    134 
    135     /** True if user setup can be skipped. */
    136     public final boolean skipUserSetup;
    137 
    138     // TODO (stevenckng): This shouldn't belong here. Remove this logic from ProvisioningParams.
    139     private ComponentName inferedDeviceAdminComponentName;
    140 
    141     private final Utils mUtils = new Utils();
    142 
    143     public String inferDeviceAdminPackageName() {
    144         if (deviceAdminComponentName != null) {
    145             return deviceAdminComponentName.getPackageName();
    146         }
    147         return deviceAdminPackageName;
    148     }
    149 
    150     // This should not be called if the app has not been installed yet.
    151     public ComponentName inferDeviceAdminComponentName(Context c)
    152             throws IllegalProvisioningArgumentException {
    153         if (inferedDeviceAdminComponentName == null) {
    154             inferedDeviceAdminComponentName = mUtils.findDeviceAdmin(
    155                     deviceAdminPackageName, deviceAdminComponentName, c);
    156         }
    157         return inferedDeviceAdminComponentName;
    158     }
    159 
    160     private ProvisioningParams(Builder builder) {
    161         timeZone = builder.mTimeZone;
    162         localTime = builder.mLocalTime;
    163         locale = builder.mLocale;
    164 
    165         wifiInfo = builder.mWifiInfo;
    166 
    167         deviceAdminComponentName = builder.mDeviceAdminComponentName;
    168         deviceAdminPackageName = builder.mDeviceAdminPackageName;
    169 
    170         deviceAdminDownloadInfo = builder.mDeviceAdminDownloadInfo;
    171 
    172         adminExtrasBundle = builder.mAdminExtrasBundle;
    173 
    174         startedByTrustedSource = builder.mStartedByTrustedSource;
    175         leaveAllSystemAppsEnabled = builder.mLeaveAllSystemAppsEnabled;
    176         skipEncryption = builder.mSkipEncryption;
    177         accountToMigrate = builder.mAccountToMigrate;
    178         provisioningAction = checkNotNull(builder.mProvisioningAction);
    179         mainColor = builder.mMainColor;
    180         skipUserSetup = builder.mSkipUserSetup;
    181 
    182         validateFields();
    183     }
    184 
    185     private ProvisioningParams(Parcel in) {
    186         timeZone = in.readString();
    187         localTime = in.readLong();
    188         locale = (Locale) in.readSerializable();
    189 
    190         wifiInfo = (WifiInfo) in.readParcelable(WifiInfo.class.getClassLoader());
    191 
    192         deviceAdminPackageName = in.readString();
    193         deviceAdminComponentName = (ComponentName)
    194                 in.readParcelable(null /* use default classloader */);
    195 
    196         deviceAdminDownloadInfo =
    197                 (PackageDownloadInfo) in.readParcelable(PackageDownloadInfo.class.getClassLoader());
    198 
    199         adminExtrasBundle = in.readParcelable(null /* use default classloader */);
    200 
    201         startedByTrustedSource = in.readInt() == 1;
    202         leaveAllSystemAppsEnabled = in.readInt() == 1;
    203         skipEncryption = in.readInt() == 1;
    204         accountToMigrate = (Account) in.readParcelable(null /* use default classloader */);
    205         provisioningAction = checkNotNull(in.readString());
    206         if (in.readInt() != 0) {
    207             mainColor = in.readInt();
    208         } else {
    209             mainColor = null;
    210         }
    211         skipUserSetup = in.readInt() == 1;
    212 
    213         validateFields();
    214     }
    215 
    216     private void validateFields() {
    217         checkArgument(deviceAdminPackageName != null || deviceAdminComponentName != null);
    218     }
    219 
    220     @Override
    221     public int describeContents() {
    222         return 0;
    223     }
    224 
    225     @Override
    226     public void writeToParcel(Parcel out, int flags) {
    227         out.writeString(timeZone);
    228         out.writeLong(localTime);
    229         out.writeSerializable(locale);
    230 
    231         out.writeParcelable(wifiInfo, 0 /* default */ );
    232 
    233         out.writeString(deviceAdminPackageName);
    234         out.writeParcelable(deviceAdminComponentName, 0 /* default */);
    235 
    236         out.writeParcelable(deviceAdminDownloadInfo, 0 /* default */);
    237 
    238         out.writeParcelable(adminExtrasBundle, 0 /* default */);
    239 
    240         out.writeInt(startedByTrustedSource ? 1 : 0);
    241         out.writeInt(leaveAllSystemAppsEnabled ? 1 : 0);
    242         out.writeInt(skipEncryption ? 1 : 0);
    243         out.writeParcelable(accountToMigrate, 0 /* default */);
    244         out.writeString(provisioningAction);
    245         if (mainColor != null) {
    246             out.writeInt(1);
    247             out.writeInt(mainColor);
    248         } else {
    249             out.writeInt(0);
    250         }
    251         out.writeInt(skipUserSetup ? 1 : 0);
    252     }
    253 
    254     @Override
    255     public boolean equals(Object o) {
    256         if (this == o) {
    257             return true;
    258         }
    259         if (o == null || getClass() != o.getClass()) {
    260             return false;
    261         }
    262         ProvisioningParams that = (ProvisioningParams) o;
    263         return localTime == that.localTime
    264                 && startedByTrustedSource == that.startedByTrustedSource
    265                 && leaveAllSystemAppsEnabled == that.leaveAllSystemAppsEnabled
    266                 && skipEncryption == that.skipEncryption
    267                 && skipUserSetup == that.skipUserSetup
    268                 && Objects.equals(timeZone, that.timeZone)
    269                 && Objects.equals(locale, that.locale)
    270                 && Objects.equals(wifiInfo, that.wifiInfo)
    271                 && Objects.equals(deviceAdminPackageName, that.deviceAdminPackageName)
    272                 && Objects.equals(deviceAdminComponentName, that.deviceAdminComponentName)
    273                 && Objects.equals(accountToMigrate, that.accountToMigrate)
    274                 && Objects.equals(provisioningAction, that.provisioningAction)
    275                 && Objects.equals(mainColor, that.mainColor)
    276                 && Objects.equals(deviceAdminDownloadInfo, that.deviceAdminDownloadInfo)
    277                 && isPersistableBundleEquals(adminExtrasBundle, that.adminExtrasBundle)
    278                 && Objects.equals(
    279                         inferedDeviceAdminComponentName, that.inferedDeviceAdminComponentName);
    280     }
    281 
    282     /**
    283      * Compares two {@link PersistableBundle} objects are equals.
    284      */
    285     private static boolean isPersistableBundleEquals(
    286             PersistableBundle obj1, PersistableBundle obj2) {
    287         if (obj1 == obj2) {
    288             return true;
    289         }
    290         if (obj1 == null || obj2 == null || obj1.size() != obj2.size()) {
    291             return false;
    292         }
    293         Set<String> keys = obj1.keySet();
    294         for (String key : keys) {
    295             Object val1 = obj1.get(key);
    296             Object val2 = obj2.get(key);
    297             if (!isPersistableBundleSupportedValueEquals(val1, val2)) {
    298                 return false;
    299             }
    300         }
    301         return true;
    302     }
    303 
    304     /**
    305      * Compares two values which type is supported by {@link PersistableBundle}.
    306      *
    307      * <p>If the type isn't supported. The equality is done by {@link Object#equals(Object)}.
    308      */
    309     private static boolean isPersistableBundleSupportedValueEquals(Object val1, Object val2) {
    310         if (val1 == val2) {
    311             return true;
    312         } else if (val1 == null || val2 == null || !val1.getClass().equals(val2.getClass())) {
    313             return false;
    314         } else if (val1 instanceof PersistableBundle && val2 instanceof PersistableBundle) {
    315             return isPersistableBundleEquals((PersistableBundle) val1, (PersistableBundle) val2);
    316         } else if (val1 instanceof int[]) {
    317             return Arrays.equals((int[]) val1, (int[]) val2);
    318         } else if (val1 instanceof long[]) {
    319             return Arrays.equals((long[]) val1, (long[]) val2);
    320         } else if (val1 instanceof double[]) {
    321             return Arrays.equals((double[]) val1, (double[]) val2);
    322         } else if (val1 instanceof boolean[]) {
    323             return Arrays.equals((boolean[]) val1, (boolean[]) val2);
    324         } else if (val1 instanceof String[]) {
    325             return Arrays.equals((String[]) val1, (String[]) val2);
    326         } else {
    327             return Objects.equals(val1, val2);
    328         }
    329     }
    330 
    331     public final static class Builder {
    332         private String mTimeZone;
    333         private long mLocalTime = DEFAULT_LOCAL_TIME;
    334         private Locale mLocale;
    335         private WifiInfo mWifiInfo;
    336         private String mDeviceAdminPackageName;
    337         private ComponentName mDeviceAdminComponentName;
    338         private Account mAccountToMigrate;
    339         private String mProvisioningAction;
    340         private Integer mMainColor = DEFAULT_MAIN_COLOR;
    341         private PackageDownloadInfo mDeviceAdminDownloadInfo;
    342         private PersistableBundle mAdminExtrasBundle;
    343         private boolean mStartedByTrustedSource = DEFAULT_STARTED_BY_TRUSTED_SOURCE;
    344         private boolean mLeaveAllSystemAppsEnabled = DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED;
    345         private boolean mSkipEncryption = DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION;
    346         private boolean mSkipUserSetup = DEFAULT_SKIP_USER_SETUP;
    347 
    348         public Builder setTimeZone(String timeZone) {
    349             mTimeZone = timeZone;
    350             return this;
    351         }
    352 
    353         public Builder setLocalTime(long localTime) {
    354             mLocalTime = localTime;
    355             return this;
    356         }
    357 
    358         public Builder setLocale(Locale locale) {
    359             mLocale = locale;
    360             return this;
    361         }
    362 
    363         public Builder setWifiInfo(WifiInfo wifiInfo) {
    364             mWifiInfo = wifiInfo;
    365             return this;
    366         }
    367 
    368         @Deprecated
    369         public Builder setDeviceAdminPackageName(String deviceAdminPackageName) {
    370             mDeviceAdminPackageName = deviceAdminPackageName;
    371             return this;
    372         }
    373 
    374         public Builder setDeviceAdminComponentName(ComponentName deviceAdminComponentName) {
    375             mDeviceAdminComponentName = deviceAdminComponentName;
    376             return this;
    377         }
    378 
    379         public Builder setAccountToMigrate(Account accountToMigrate) {
    380             mAccountToMigrate = accountToMigrate;
    381             return this;
    382         }
    383 
    384         public Builder setProvisioningAction(String provisioningAction) {
    385             mProvisioningAction = provisioningAction;
    386             return this;
    387         }
    388 
    389         public Builder setMainColor(Integer mainColor) {
    390             mMainColor = mainColor;
    391             return this;
    392         }
    393 
    394         public Builder setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo) {
    395             mDeviceAdminDownloadInfo = deviceAdminDownloadInfo;
    396             return this;
    397         }
    398 
    399         public Builder setAdminExtrasBundle(PersistableBundle adminExtrasBundle) {
    400             mAdminExtrasBundle = adminExtrasBundle;
    401             return this;
    402         }
    403 
    404         public Builder setStartedByTrustedSource(boolean startedByTrustedSource) {
    405             mStartedByTrustedSource = startedByTrustedSource;
    406             return this;
    407         }
    408 
    409         public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) {
    410             mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
    411             return this;
    412         }
    413 
    414         public Builder setSkipEncryption(boolean skipEncryption) {
    415             mSkipEncryption = skipEncryption;
    416             return this;
    417         }
    418 
    419         public Builder setSkipUserSetup(boolean skipUserSetup) {
    420             mSkipUserSetup = skipUserSetup;
    421             return this;
    422         }
    423 
    424         public ProvisioningParams build() {
    425             return new ProvisioningParams(this);
    426         }
    427 
    428         public static Builder builder() {
    429             return new Builder();
    430         }
    431     }
    432 }
    433