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 package com.android.managedprovisioning.parser; 17 18 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMERS; 19 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMER_CONTENT; 20 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMER_HEADER; 21 import static com.android.managedprovisioning.common.StoreUtils.DIR_PROVISIONING_PARAMS_FILE_CACHE; 22 23 import android.content.Context; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.Parcelable; 27 import androidx.annotation.Nullable; 28 import androidx.annotation.VisibleForTesting; 29 import android.text.TextUtils; 30 import com.android.managedprovisioning.common.ProvisionLogger; 31 import com.android.managedprovisioning.common.StoreUtils; 32 import com.android.managedprovisioning.model.DisclaimersParam; 33 import com.android.managedprovisioning.model.DisclaimersParam.Disclaimer; 34 import java.io.File; 35 import java.util.ArrayList; 36 import java.util.List; 37 38 /** 39 * Parser for {@link EXTRA_PROVISIONING_DISCLAIMERS} into {@link DisclaimersParam} 40 * It also saves the disclaimer content into files 41 */ 42 public class DisclaimersParser { 43 private static final int MAX_LENGTH = 3; 44 45 private final Context mContext; 46 private final long mProvisioningId; 47 private final File mDisclaimerDir; 48 DisclaimersParser(Context context, long provisioningId)49 public DisclaimersParser(Context context, long provisioningId) { 50 mContext = context; 51 mProvisioningId = provisioningId; 52 mDisclaimerDir = new File(mContext.getFilesDir(), DIR_PROVISIONING_PARAMS_FILE_CACHE); 53 } 54 55 @Nullable parse(Parcelable[] parcelables)56 public DisclaimersParam parse(Parcelable[] parcelables) throws ClassCastException { 57 if (parcelables == null) { 58 return null; 59 } 60 61 List<Disclaimer> disclaimers = new ArrayList<>(MAX_LENGTH); 62 for (int i = 0; i < parcelables.length; i++) { 63 // maximum 3 disclaimers are accepted in the EXTRA_PROVISIONING_DISCLAIMERS API 64 if (disclaimers.size() >= MAX_LENGTH) { 65 break; 66 } 67 final Bundle disclaimerBundle = (Bundle) parcelables[i]; 68 final String header = disclaimerBundle.getString(EXTRA_PROVISIONING_DISCLAIMER_HEADER); 69 final Uri uri = disclaimerBundle.getParcelable(EXTRA_PROVISIONING_DISCLAIMER_CONTENT); 70 if (TextUtils.isEmpty(header)) { 71 ProvisionLogger.logw("Empty disclaimer header in " + i + " element"); 72 continue; 73 } 74 75 if (uri == null) { 76 ProvisionLogger.logw("Null disclaimer content uri in " + i + " element"); 77 continue; 78 } 79 80 File disclaimerFile = saveDisclaimerContentIntoFile(uri, i); 81 82 if (disclaimerFile == null) { 83 ProvisionLogger.logw("Failed to copy disclaimer uri in " + i + " element"); 84 continue; 85 } 86 87 disclaimers.add(new Disclaimer(header, disclaimerFile.getPath())); 88 } 89 return disclaimers.isEmpty() ? null : new DisclaimersParam.Builder() 90 .setDisclaimers(disclaimers.toArray(new Disclaimer[disclaimers.size()])).build(); 91 } 92 93 /** 94 * @return {@link File} if the uri content is saved into the file successfully. Otherwise, 95 * return null. 96 */ saveDisclaimerContentIntoFile(Uri uri, int index)97 private File saveDisclaimerContentIntoFile(Uri uri, int index) { 98 if (!mDisclaimerDir.exists()) { 99 mDisclaimerDir.mkdirs(); 100 } 101 102 String filename = "disclaimer_content_" + mProvisioningId + "_" + index + ".txt"; 103 File outputFile = new File(mDisclaimerDir, filename); 104 105 boolean success = StoreUtils.copyUriIntoFile(mContext.getContentResolver(), uri, 106 outputFile); 107 return success ? outputFile : null; 108 } 109 } 110