| /* | |
| * 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 android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION; | |
| import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER; | |
| import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM; | |
| import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM; | |
| import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE; | |
| import static com.android.internal.util.Preconditions.checkNotNull; | |
| import android.os.Parcel; | |
| import android.os.Parcelable; | |
| import android.os.PersistableBundle; | |
| import androidx.annotation.Nullable; | |
| import android.text.TextUtils; | |
| import com.android.internal.annotations.Immutable; | |
| import com.android.managedprovisioning.common.PersistableBundlable; | |
| import com.android.managedprovisioning.common.StoreUtils; | |
| import java.io.IOException; | |
| import java.util.Arrays; | |
| import java.util.Objects; | |
| import org.xmlpull.v1.XmlPullParser; | |
| import org.xmlpull.v1.XmlPullParserException; | |
| import org.xmlpull.v1.XmlSerializer; | |
| /** | |
| * Stores the device admin package download information. | |
| */ | |
| @Immutable | |
| public final class PackageDownloadInfo extends PersistableBundlable { | |
| public static final byte[] DEFAULT_PACKAGE_CHECKSUM = new byte[0]; | |
| public static final byte[] DEFAULT_SIGNATURE_CHECKSUM = new byte[0]; | |
| // Always download packages if no minimum version given. | |
| public static final int DEFAULT_MINIMUM_VERSION = Integer.MAX_VALUE; | |
| public static final Parcelable.Creator<PackageDownloadInfo> CREATOR | |
| = new Parcelable.Creator<PackageDownloadInfo>() { | |
| @Override | |
| public PackageDownloadInfo createFromParcel(Parcel in) { | |
| return new PackageDownloadInfo(in); | |
| } | |
| @Override | |
| public PackageDownloadInfo[] newArray(int size) { | |
| return new PackageDownloadInfo[size]; | |
| } | |
| }; | |
| /** | |
| * Url where the package (.apk) can be downloaded from. {@code null} if there is no download | |
| * location specified. | |
| */ | |
| public final String location; | |
| /** Cookie header for http request. */ | |
| @Nullable | |
| public final String cookieHeader; | |
| /** | |
| * One of the following two checksums should be non empty. SHA-256 hash of the | |
| * .apk file, or empty array if not used. | |
| */ | |
| public final byte[] packageChecksum; | |
| /** SHA-256 hash of the signature in the .apk file, or empty array if not used. */ | |
| public final byte[] signatureChecksum; | |
| /** Minimum supported version code of the downloaded package. */ | |
| public final int minVersion; | |
| private PackageDownloadInfo(Builder builder) { | |
| location = builder.mLocation; | |
| cookieHeader = builder.mCookieHeader; | |
| packageChecksum = checkNotNull(builder.mPackageChecksum, "package checksum can't be null"); | |
| signatureChecksum = checkNotNull(builder.mSignatureChecksum, | |
| "signature checksum can't be null"); | |
| minVersion = builder.mMinVersion; | |
| validateFields(); | |
| } | |
| private PackageDownloadInfo(Parcel in) { | |
| this(createBuilderFromPersistableBundle( | |
| PersistableBundlable.getPersistableBundleFromParcel(in))); | |
| } | |
| private void validateFields() { | |
| if (TextUtils.isEmpty(location)) { | |
| throw new IllegalArgumentException("Download location must not be empty."); | |
| } | |
| if (packageChecksum.length == 0 && signatureChecksum.length == 0) { | |
| throw new IllegalArgumentException("Package checksum or signature checksum must be " | |
| + "provided."); | |
| } | |
| } | |
| /* package */ static PackageDownloadInfo fromPersistableBundle(PersistableBundle bundle) { | |
| return createBuilderFromPersistableBundle(bundle).build(); | |
| } | |
| private static Builder createBuilderFromPersistableBundle(PersistableBundle bundle) { | |
| Builder builder = new Builder(); | |
| builder.setMinVersion(bundle.getInt(EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE)); | |
| builder.setLocation(bundle.getString( | |
| EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)); | |
| builder.setCookieHeader(bundle.getString( | |
| EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER)); | |
| builder.setPackageChecksum(StoreUtils.stringToByteArray(bundle.getString( | |
| EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM))); | |
| builder.setSignatureChecksum(StoreUtils.stringToByteArray(bundle.getString( | |
| EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM))); | |
| return builder; | |
| } | |
| @Override | |
| public PersistableBundle toPersistableBundle() { | |
| final PersistableBundle bundle = new PersistableBundle(); | |
| bundle.putInt(EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE, | |
| minVersion); | |
| bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION, location); | |
| bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER, | |
| cookieHeader); | |
| bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM, | |
| StoreUtils.byteArrayToString(packageChecksum)); | |
| bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM, | |
| StoreUtils.byteArrayToString(signatureChecksum)); | |
| return bundle; | |
| } | |
| public final static class Builder { | |
| private String mLocation; | |
| private String mCookieHeader; | |
| private byte[] mPackageChecksum = DEFAULT_PACKAGE_CHECKSUM; | |
| private byte[] mSignatureChecksum = DEFAULT_SIGNATURE_CHECKSUM; | |
| private int mMinVersion = DEFAULT_MINIMUM_VERSION; | |
| public Builder setLocation(String location) { | |
| mLocation = location; | |
| return this; | |
| } | |
| public Builder setCookieHeader(String cookieHeader) { | |
| mCookieHeader = cookieHeader; | |
| return this; | |
| } | |
| public Builder setPackageChecksum(byte[] packageChecksum) { | |
| mPackageChecksum = packageChecksum; | |
| return this; | |
| } | |
| public Builder setSignatureChecksum(byte[] signatureChecksum) { | |
| mSignatureChecksum = signatureChecksum; | |
| return this; | |
| } | |
| public Builder setMinVersion(int minVersion) { | |
| mMinVersion = minVersion; | |
| return this; | |
| } | |
| public PackageDownloadInfo build() { | |
| return new PackageDownloadInfo(this); | |
| } | |
| public static Builder builder() { | |
| return new Builder(); | |
| } | |
| } | |
| } |