Licenses.java revision 95961816a768da387f0b5523cf4363ace2044089
1/* 2 * Copyright (C) 2017 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 17package com.android.tv.license; 18 19import android.content.Context; 20import android.support.annotation.RawRes; 21import com.android.tv.R; 22import com.android.tv.common.SoftPreconditions; 23import java.io.ByteArrayOutputStream; 24import java.io.IOException; 25import java.io.InputStream; 26import java.io.UnsupportedEncodingException; 27import java.util.ArrayList; 28import java.util.Collections; 29 30/** 31 * A helper for extracting licenses embedded using 32 * third_party_licenses.build:third_party_licenses(). 33 */ 34public final class Licenses { 35 36 public static final String TAG = "Licenses"; 37 38 public static boolean hasLicenses(Context context) { 39 return !getTextFromResource( 40 context.getApplicationContext(), R.raw.third_party_license_metadata, 0, -1) 41 .isEmpty(); 42 } 43 44 /** Return the licenses bundled into this app. */ 45 public static ArrayList<License> getLicenses(Context context) { 46 return getLicenseListFromMetadata( 47 getTextFromResource( 48 context.getApplicationContext(), R.raw.third_party_license_metadata, 0, -1), 49 ""); 50 } 51 52 /** 53 * Returns a list of {@link License}s parsed from a license metadata file. 54 * 55 * @param metadata a {@code String} containing the contents of a license metadata file. 56 * @param filePath a path to a package archive with licenses or empty string for the app package 57 */ 58 private static ArrayList<License> getLicenseListFromMetadata(String metadata, String filePath) { 59 String[] entries = metadata.split("\n"); 60 ArrayList<License> licenses = new ArrayList<License>(entries.length); 61 for (String entry : entries) { 62 int delimiter = entry.indexOf(' '); 63 String[] licenseLocation = entry.substring(0, delimiter).split(":"); 64 SoftPreconditions.checkState( 65 licenseLocation.length == 2 && delimiter > 0, 66 TAG, 67 "Invalid license meta-data line:\n" + entry); 68 long licenseOffset = Long.parseLong(licenseLocation[0]); 69 int licenseLength = Integer.parseInt(licenseLocation[1]); 70 licenses.add( 71 License.create( 72 entry.substring(delimiter + 1), 73 licenseOffset, 74 licenseLength, 75 filePath)); 76 } 77 Collections.sort(licenses); 78 return licenses; 79 } 80 81 /** Return the text of a bundled license file. */ 82 public static String getLicenseText(Context context, License license) { 83 long offset = license.getLicenseOffset(); 84 int length = license.getLicenseLength(); 85 return getTextFromResource(context, R.raw.third_party_licenses, offset, length); 86 } 87 88 private static String getTextFromResource( 89 Context context, @RawRes int resourcesIdentifier, long offset, int length) { 90 InputStream stream = 91 context.getApplicationContext().getResources().openRawResource(resourcesIdentifier); 92 return getTextFromInputStream(stream, offset, length); 93 } 94 95 private static String getTextFromInputStream(InputStream stream, long offset, int length) { 96 byte[] buffer = new byte[1024]; 97 ByteArrayOutputStream textArray = new ByteArrayOutputStream(); 98 99 try { 100 stream.skip(offset); 101 int bytesRemaining = length > 0 ? length : Integer.MAX_VALUE; 102 int bytes = 0; 103 104 while (bytesRemaining > 0 105 && (bytes = stream.read(buffer, 0, Math.min(bytesRemaining, buffer.length))) 106 != -1) { 107 textArray.write(buffer, 0, bytes); 108 bytesRemaining -= bytes; 109 } 110 stream.close(); 111 } catch (IOException e) { 112 throw new RuntimeException("Failed to read license or metadata text.", e); 113 } 114 try { 115 return textArray.toString("UTF-8"); 116 } catch (UnsupportedEncodingException e) { 117 throw new RuntimeException( 118 "Unsupported encoding UTF8. This should always be supported.", e); 119 } 120 } 121} 122