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