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