| /* |
| * Copyright (C) 2017 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.dialer.about; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import com.android.dialer.common.Assert; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.UnsupportedEncodingException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| |
| /** A helper for extracting licenses. */ |
| public final class Licenses { |
| private static final String TAG = "Licenses"; |
| private static final String LICENSE_FILENAME = "third_party_licenses"; |
| private static final String LICENSE_METADATA_FILENAME = "third_party_license_metadata"; |
| |
| /** Return the licenses bundled into this app. */ |
| public static ArrayList<License> getLicenses(Context context) { |
| return getLicenseListFromMetadata( |
| getTextFromResource(context.getApplicationContext(), LICENSE_METADATA_FILENAME, 0, -1)); |
| } |
| |
| /** |
| * Returns a list of {@link License}s parsed from a license metadata file. |
| * |
| * @param metadata a {@code String} containing the contents of a license metadata file. |
| */ |
| private static ArrayList<License> getLicenseListFromMetadata(String metadata) { |
| String[] entries = metadata.split("\n"); |
| ArrayList<License> licenses = new ArrayList<License>(entries.length); |
| for (String entry : entries) { |
| int delimiter = entry.indexOf(' '); |
| String[] licenseLocation = entry.substring(0, delimiter).split(":"); |
| Assert.checkState( |
| delimiter > 0 && licenseLocation.length == 2, |
| "Invalid license meta-data line:\n" + entry); |
| long licenseOffset = Long.parseLong(licenseLocation[0]); |
| int licenseLength = Integer.parseInt(licenseLocation[1]); |
| licenses.add(License.create(entry.substring(delimiter + 1), licenseOffset, licenseLength)); |
| } |
| Collections.sort(licenses); |
| return licenses; |
| } |
| |
| /** Return the text of a bundled license file. */ |
| public static String getLicenseText(Context context, License license) { |
| long offset = license.getLicenseOffset(); |
| int length = license.getLicenseLength(); |
| return getTextFromResource(context, LICENSE_FILENAME, offset, length); |
| } |
| |
| private static String getTextFromResource( |
| Context context, String filename, long offset, int length) { |
| Resources resources = context.getApplicationContext().getResources(); |
| // When aapt is called with --rename-manifest-package, the package name is changed for the |
| // application, but not for the resources. This is to find the package name of a known |
| // resource to know what package to lookup the license files in. |
| String packageName = resources.getResourcePackageName(R.id.license); |
| InputStream stream = |
| resources.openRawResource(resources.getIdentifier(filename, "raw", packageName)); |
| return getTextFromInputStream(stream, offset, length); |
| } |
| |
| private static String getTextFromInputStream(InputStream stream, long offset, int length) { |
| byte[] buffer = new byte[1024]; |
| ByteArrayOutputStream textArray = new ByteArrayOutputStream(); |
| |
| try { |
| stream.skip(offset); |
| int bytesRemaining = length > 0 ? length : Integer.MAX_VALUE; |
| int bytes = 0; |
| |
| while (bytesRemaining > 0 |
| && (bytes = stream.read(buffer, 0, Math.min(bytesRemaining, buffer.length))) != -1) { |
| textArray.write(buffer, 0, bytes); |
| bytesRemaining -= bytes; |
| } |
| stream.close(); |
| } catch (IOException e) { |
| throw new RuntimeException("Failed to read license or metadata text.", e); |
| } |
| try { |
| return textArray.toString("UTF-8"); |
| } catch (UnsupportedEncodingException e) { |
| throw new RuntimeException("Unsupported encoding UTF8. This should always be supported.", e); |
| } |
| } |
| } |