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 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.support.annotation.Nullable;
     25 import android.text.TextUtils;
     26 
     27 import java.util.Arrays;
     28 import java.util.Objects;
     29 
     30 import com.android.internal.annotations.Immutable;
     31 
     32 /**
     33  * Stores the device admin package download information.
     34  */
     35 @Immutable
     36 public final class PackageDownloadInfo implements Parcelable {
     37     public static final byte[] DEFAULT_PACKAGE_CHECKSUM = new byte[0];
     38     public static final byte[] DEFAULT_SIGNATURE_CHECKSUM = new byte[0];
     39     public static final boolean DEFAULT_PACKAGE_CHECKSUM_SUPPORTS_SHA1 = false;
     40     // Always download packages if no minimum version given.
     41     public static final int DEFAULT_MINIMUM_VERSION = Integer.MAX_VALUE;
     42 
     43     public static final Parcelable.Creator<PackageDownloadInfo> CREATOR
     44             = new Parcelable.Creator<PackageDownloadInfo>() {
     45         @Override
     46         public PackageDownloadInfo createFromParcel(Parcel in) {
     47             return new PackageDownloadInfo(in);
     48         }
     49 
     50         @Override
     51         public PackageDownloadInfo[] newArray(int size) {
     52             return new PackageDownloadInfo[size];
     53         }
     54     };
     55 
     56     /**
     57      * Url where the package (.apk) can be downloaded from. {@code null} if there is no download
     58      * location specified.
     59      */
     60     public final String location;
     61     /** Cookie header for http request. */
     62     @Nullable
     63     public final String cookieHeader;
     64     /**
     65      * One of the following two checksums should be non empty. SHA-256 or SHA-1 hash of the
     66      * .apk file, or empty array if not used.
     67      */
     68     public final byte[] packageChecksum;
     69     /** SHA-256 hash of the signature in the .apk file, or empty array if not used. */
     70     public final byte[] signatureChecksum;
     71     /** Minimum supported version code of the downloaded package. */
     72     public final int minVersion;
     73     /**
     74      * If this is false, packageChecksum can only be SHA-256 hash, otherwise SHA-1 is also
     75      * supported.
     76      */
     77     public final boolean packageChecksumSupportsSha1;
     78 
     79     private PackageDownloadInfo(Builder builder) {
     80         location = builder.mLocation;
     81         cookieHeader = builder.mCookieHeader;
     82         packageChecksum = checkNotNull(builder.mPackageChecksum, "package checksum can't be null");
     83         signatureChecksum = checkNotNull(builder.mSignatureChecksum,
     84                 "signature checksum can't be null");
     85         minVersion = builder.mMinVersion;
     86         packageChecksumSupportsSha1 = builder.mPackageChecksumSupportsSha1;
     87 
     88         validateFields();
     89     }
     90 
     91     private PackageDownloadInfo(Parcel in) {
     92         minVersion = in.readInt();
     93         location = in.readString();
     94         cookieHeader = in.readString();
     95         packageChecksum = checkNotNull(in.createByteArray());
     96         signatureChecksum = checkNotNull(in.createByteArray());
     97         packageChecksumSupportsSha1 = in.readInt() == 1;
     98 
     99         validateFields();
    100     }
    101 
    102     private void validateFields() {
    103         if (TextUtils.isEmpty(location)) {
    104             throw new IllegalArgumentException("Download location must not be empty.");
    105         }
    106         if (packageChecksum.length == 0 && signatureChecksum.length == 0) {
    107             throw new IllegalArgumentException("Package checksum or signature checksum must be "
    108                     + "provided.");
    109         }
    110     }
    111 
    112     @Override
    113     public int describeContents() {
    114         return 0;
    115     }
    116 
    117     @Override
    118     public void writeToParcel(Parcel out, int flags) {
    119         out.writeInt(minVersion);
    120         out.writeString(location);
    121         out.writeString(cookieHeader);
    122         out.writeByteArray(packageChecksum);
    123         out.writeByteArray(signatureChecksum);
    124         out.writeInt(packageChecksumSupportsSha1 ? 1 : 0);
    125     }
    126 
    127     @Override
    128     public boolean equals(Object o) {
    129         if (this == o) {
    130             return true;
    131         }
    132         if (o == null || getClass() != o.getClass()) {
    133             return false;
    134         }
    135         PackageDownloadInfo that = (PackageDownloadInfo) o;
    136         return minVersion == that.minVersion
    137                 && packageChecksumSupportsSha1 == that.packageChecksumSupportsSha1
    138                 && Objects.equals(location, that.location)
    139                 && Objects.equals(cookieHeader, that.cookieHeader)
    140                 && Arrays.equals(packageChecksum, that.packageChecksum)
    141                 && Arrays.equals(signatureChecksum, that.signatureChecksum);
    142     }
    143 
    144     public final static class Builder {
    145         private String mLocation;
    146         private String mCookieHeader;
    147         private byte[] mPackageChecksum = DEFAULT_PACKAGE_CHECKSUM;
    148         private byte[] mSignatureChecksum = DEFAULT_SIGNATURE_CHECKSUM;
    149         private int mMinVersion = DEFAULT_MINIMUM_VERSION;
    150         private boolean mPackageChecksumSupportsSha1 = DEFAULT_PACKAGE_CHECKSUM_SUPPORTS_SHA1;
    151 
    152         public Builder setLocation(String location) {
    153             mLocation = location;
    154             return this;
    155         }
    156 
    157         public Builder setCookieHeader(String cookieHeader) {
    158             mCookieHeader = cookieHeader;
    159             return this;
    160         }
    161 
    162         public Builder setPackageChecksum(byte[] packageChecksum) {
    163             mPackageChecksum = packageChecksum;
    164             return this;
    165         }
    166 
    167         public Builder setSignatureChecksum(byte[] signatureChecksum) {
    168             mSignatureChecksum = signatureChecksum;
    169             return this;
    170         }
    171 
    172         public Builder setMinVersion(int minVersion) {
    173             mMinVersion = minVersion;
    174             return this;
    175         }
    176 
    177         // TODO: remove once SHA-1 is fully deprecated.
    178         public Builder setPackageChecksumSupportsSha1(boolean packageChecksumSupportsSha1) {
    179             mPackageChecksumSupportsSha1 = packageChecksumSupportsSha1;
    180             return this;
    181         }
    182 
    183         public PackageDownloadInfo build() {
    184             return new PackageDownloadInfo(this);
    185         }
    186 
    187         public static Builder builder() {
    188             return new Builder();
    189         }
    190     }
    191 }
    192