1d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng/*
2d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * Copyright 2016, The Android Open Source Project
3d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng *
4d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * Licensed under the Apache License, Version 2.0 (the "License");
5d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * you may not use this file except in compliance with the License.
6d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * You may obtain a copy of the License at
7d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng *
8d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng *     http://www.apache.org/licenses/LICENSE-2.0
9d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng *
10d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * Unless required by applicable law or agreed to in writing, software
11d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * distributed under the License is distributed on an "AS IS" BASIS,
12d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * See the License for the specific language governing permissions and
14d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * limitations under the License.
15d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng */
16d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
17d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngpackage com.android.managedprovisioning.model;
18d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
19d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport static com.android.internal.util.Preconditions.checkArgument;
20d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport static com.android.internal.util.Preconditions.checkNotNull;
21d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
22d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport android.os.Parcel;
23d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport android.os.Parcelable;
24d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport android.support.annotation.Nullable;
25d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport android.text.TextUtils;
26d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
27d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport java.util.Arrays;
28d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport java.util.Objects;
29d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
30d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport com.android.internal.annotations.Immutable;
31d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
32d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng/**
33d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng * Stores the device admin package download information.
34d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng */
35d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng@Immutable
36d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngpublic final class PackageDownloadInfo implements Parcelable {
37d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public static final byte[] DEFAULT_PACKAGE_CHECKSUM = new byte[0];
38d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public static final byte[] DEFAULT_SIGNATURE_CHECKSUM = new byte[0];
39d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public static final boolean DEFAULT_PACKAGE_CHECKSUM_SUPPORTS_SHA1 = false;
40d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    // Always download packages if no minimum version given.
41d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public static final int DEFAULT_MINIMUM_VERSION = Integer.MAX_VALUE;
42d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
43d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public static final Parcelable.Creator<PackageDownloadInfo> CREATOR
44d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            = new Parcelable.Creator<PackageDownloadInfo>() {
45d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        @Override
46d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public PackageDownloadInfo createFromParcel(Parcel in) {
47d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return new PackageDownloadInfo(in);
48d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
49d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
50d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        @Override
51d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public PackageDownloadInfo[] newArray(int size) {
52d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return new PackageDownloadInfo[size];
53d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
54d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    };
55d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
56d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /**
57d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * Url where the package (.apk) can be downloaded from. {@code null} if there is no download
58d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * location specified.
59d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     */
60d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final String location;
61d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /** Cookie header for http request. */
62d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    @Nullable
63d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final String cookieHeader;
64d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /**
65d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * One of the following two checksums should be non empty. SHA-256 or SHA-1 hash of the
66d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * .apk file, or empty array if not used.
67d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     */
68d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final byte[] packageChecksum;
69d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /** SHA-256 hash of the signature in the .apk file, or empty array if not used. */
70d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final byte[] signatureChecksum;
71d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /** Minimum supported version code of the downloaded package. */
72d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final int minVersion;
73d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    /**
74d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * If this is false, packageChecksum can only be SHA-256 hash, otherwise SHA-1 is also
75d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     * supported.
76d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng     */
77d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final boolean packageChecksumSupportsSha1;
78d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
79d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    private PackageDownloadInfo(Builder builder) {
80d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        location = builder.mLocation;
81d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        cookieHeader = builder.mCookieHeader;
8277bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng        packageChecksum = checkNotNull(builder.mPackageChecksum, "package checksum can't be null");
8377bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng        signatureChecksum = checkNotNull(builder.mSignatureChecksum,
8477bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng                "signature checksum can't be null");
85d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        minVersion = builder.mMinVersion;
86d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        packageChecksumSupportsSha1 = builder.mPackageChecksumSupportsSha1;
87d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
88d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        validateFields();
89d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
90d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
91d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    private PackageDownloadInfo(Parcel in) {
92d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        minVersion = in.readInt();
93d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        location = in.readString();
94d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        cookieHeader = in.readString();
95d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        packageChecksum = checkNotNull(in.createByteArray());
96d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        signatureChecksum = checkNotNull(in.createByteArray());
97d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        packageChecksumSupportsSha1 = in.readInt() == 1;
98d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
99d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        validateFields();
100d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
101d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
102d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    private void validateFields() {
10377bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng        if (TextUtils.isEmpty(location)) {
10477bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng            throw new IllegalArgumentException("Download location must not be empty.");
10577bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng        }
10677bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng        if (packageChecksum.length == 0 && signatureChecksum.length == 0) {
10777bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng            throw new IllegalArgumentException("Package checksum or signature checksum must be "
10877bac595693aa1aa6e4832f278d5b3b35a3ffd53Steven Ng                    + "provided.");
109d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
110d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
111d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
112d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    @Override
113d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public int describeContents() {
114d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        return 0;
115d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
116d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
117d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    @Override
118d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public void writeToParcel(Parcel out, int flags) {
119d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeInt(minVersion);
120d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeString(location);
121d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeString(cookieHeader);
122d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeByteArray(packageChecksum);
123d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeByteArray(signatureChecksum);
124d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        out.writeInt(packageChecksumSupportsSha1 ? 1 : 0);
125d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
126d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
127d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    @Override
128d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public boolean equals(Object o) {
129d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        if (this == o) {
130d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return true;
131d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
132d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        if (o == null || getClass() != o.getClass()) {
133d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return false;
134d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
135d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        PackageDownloadInfo that = (PackageDownloadInfo) o;
136d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        return minVersion == that.minVersion
137d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng                && packageChecksumSupportsSha1 == that.packageChecksumSupportsSha1
138d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng                && Objects.equals(location, that.location)
139d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng                && Objects.equals(cookieHeader, that.cookieHeader)
140d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng                && Arrays.equals(packageChecksum, that.packageChecksum)
141d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng                && Arrays.equals(signatureChecksum, that.signatureChecksum);
142d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
143d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
144d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    public final static class Builder {
145d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private String mLocation;
146d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private String mCookieHeader;
147d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private byte[] mPackageChecksum = DEFAULT_PACKAGE_CHECKSUM;
148d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private byte[] mSignatureChecksum = DEFAULT_SIGNATURE_CHECKSUM;
149d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private int mMinVersion = DEFAULT_MINIMUM_VERSION;
150d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        private boolean mPackageChecksumSupportsSha1 = DEFAULT_PACKAGE_CHECKSUM_SUPPORTS_SHA1;
151d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
152d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setLocation(String location) {
153d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mLocation = location;
154d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
155d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
156d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
157d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setCookieHeader(String cookieHeader) {
158d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mCookieHeader = cookieHeader;
159d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
160d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
161d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
162d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setPackageChecksum(byte[] packageChecksum) {
163d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mPackageChecksum = packageChecksum;
164d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
165d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
166d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
167d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setSignatureChecksum(byte[] signatureChecksum) {
168d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mSignatureChecksum = signatureChecksum;
169d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
170d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
171d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
172d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setMinVersion(int minVersion) {
173d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mMinVersion = minVersion;
174d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
175d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
176d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
177d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        // TODO: remove once SHA-1 is fully deprecated.
178d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public Builder setPackageChecksumSupportsSha1(boolean packageChecksumSupportsSha1) {
179d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            mPackageChecksumSupportsSha1 = packageChecksumSupportsSha1;
180d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return this;
181d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
182d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
183d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public PackageDownloadInfo build() {
184d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return new PackageDownloadInfo(this);
185d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
186d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng
187d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        public static Builder builder() {
188d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng            return new Builder();
189d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng        }
190d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng    }
191d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng}
192