1/* 2 * Copyright (C) 2007 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.settings; 18 19import android.app.Activity; 20import android.app.LoaderManager; 21import android.content.ActivityNotFoundException; 22import android.content.ContentResolver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.Loader; 26import android.net.Uri; 27import android.os.Bundle; 28import android.os.StrictMode; 29import android.os.SystemProperties; 30import android.support.annotation.VisibleForTesting; 31import android.support.v4.content.FileProvider; 32import android.text.TextUtils; 33import android.util.Log; 34import android.widget.Toast; 35 36import com.android.settings.users.RestrictedProfileSettings; 37 38import java.io.File; 39import java.util.ArrayList; 40import java.util.List; 41 42/** 43 * The "dialog" that shows from "License" in the Settings app. 44 */ 45public class SettingsLicenseActivity extends Activity implements 46 LoaderManager.LoaderCallbacks<File> { 47 private static final String TAG = "SettingsLicenseActivity"; 48 49 private static final String DEFAULT_LICENSE_PATH = "/system/etc/NOTICE.html.gz"; 50 private static final String PROPERTY_LICENSE_PATH = "ro.config.license_path"; 51 52 private static final int LOADER_ID_LICENSE_HTML_LOADER = 0; 53 54 @Override 55 protected void onCreate(Bundle savedInstanceState) { 56 super.onCreate(savedInstanceState); 57 58 final String licenseHtmlPath = 59 SystemProperties.get(PROPERTY_LICENSE_PATH, DEFAULT_LICENSE_PATH); 60 if (isFilePathValid(licenseHtmlPath)) { 61 showSelectedFile(licenseHtmlPath); 62 } else { 63 showHtmlFromDefaultXmlFiles(); 64 } 65 } 66 67 @Override 68 public Loader<File> onCreateLoader(int id, Bundle args) { 69 return new LicenseHtmlLoader(this); 70 } 71 72 @Override 73 public void onLoadFinished(Loader<File> loader, File generatedHtmlFile) { 74 showGeneratedHtmlFile(generatedHtmlFile); 75 } 76 77 @Override 78 public void onLoaderReset(Loader<File> loader) { 79 } 80 81 private void showHtmlFromDefaultXmlFiles() { 82 getLoaderManager().initLoader(LOADER_ID_LICENSE_HTML_LOADER, Bundle.EMPTY, this); 83 } 84 85 @VisibleForTesting 86 Uri getUriFromGeneratedHtmlFile(File generatedHtmlFile) { 87 return FileProvider.getUriForFile(this, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, 88 generatedHtmlFile); 89 } 90 91 private void showGeneratedHtmlFile(File generatedHtmlFile) { 92 if (generatedHtmlFile != null) { 93 showHtmlFromUri(getUriFromGeneratedHtmlFile(generatedHtmlFile)); 94 } else { 95 Log.e(TAG, "Failed to generate."); 96 showErrorAndFinish(); 97 } 98 } 99 100 private void showSelectedFile(final String path) { 101 if (TextUtils.isEmpty(path)) { 102 Log.e(TAG, "The system property for the license file is empty"); 103 showErrorAndFinish(); 104 return; 105 } 106 107 final File file = new File(path); 108 if (!isFileValid(file)) { 109 Log.e(TAG, "License file " + path + " does not exist"); 110 showErrorAndFinish(); 111 return; 112 } 113 showHtmlFromUri(Uri.fromFile(file)); 114 } 115 116 private void showHtmlFromUri(Uri uri) { 117 // Kick off external viewer due to WebView security restrictions; we 118 // carefully point it at HTMLViewer, since it offers to decompress 119 // before viewing. 120 final Intent intent = new Intent(Intent.ACTION_VIEW); 121 intent.setDataAndType(uri, "text/html"); 122 intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.settings_license_activity_title)); 123 if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 124 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 125 } 126 intent.addCategory(Intent.CATEGORY_DEFAULT); 127 intent.setPackage("com.android.htmlviewer"); 128 129 try { 130 startActivity(intent); 131 finish(); 132 } catch (ActivityNotFoundException e) { 133 Log.e(TAG, "Failed to find viewer", e); 134 showErrorAndFinish(); 135 } 136 } 137 138 private void showErrorAndFinish() { 139 Toast.makeText(this, R.string.settings_license_activity_unavailable, Toast.LENGTH_LONG) 140 .show(); 141 finish(); 142 } 143 144 private boolean isFilePathValid(final String path) { 145 return !TextUtils.isEmpty(path) && isFileValid(new File(path)); 146 } 147 148 @VisibleForTesting 149 boolean isFileValid(final File file) { 150 return file.exists() && file.length() != 0; 151 } 152} 153