| /* |
| * 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(); |
| } |
| } |
| } |