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 17 package com.android.settings; 18 19 import android.content.ActivityNotFoundException; 20 import android.content.ComponentName; 21 import android.content.ContentResolver; 22 import android.content.Intent; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.util.Log; 26 import android.widget.Toast; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.core.content.FileProvider; 30 import androidx.fragment.app.FragmentActivity; 31 import androidx.loader.app.LoaderManager; 32 import androidx.loader.content.Loader; 33 34 import com.android.settingslib.license.LicenseHtmlLoaderCompat; 35 36 import java.io.File; 37 38 /** 39 * The "dialog" that shows from "License" in the Settings app. 40 */ 41 public class SettingsLicenseActivity extends FragmentActivity implements 42 LoaderManager.LoaderCallbacks<File> { 43 private static final String TAG = "SettingsLicenseActivity"; 44 45 private static final String LICENSE_PATH = "/system/etc/NOTICE.html.gz"; 46 47 private static final int LOADER_ID_LICENSE_HTML_LOADER = 0; 48 49 @Override onCreate(Bundle savedInstanceState)50 protected void onCreate(Bundle savedInstanceState) { 51 super.onCreate(savedInstanceState); 52 53 File file = new File(LICENSE_PATH); 54 if (isFileValid(file)) { 55 showHtmlFromUri(Uri.fromFile(file)); 56 } else { 57 showHtmlFromDefaultXmlFiles(); 58 } 59 } 60 61 @Override onCreateLoader(int id, Bundle args)62 public Loader<File> onCreateLoader(int id, Bundle args) { 63 return new LicenseHtmlLoaderCompat(this); 64 } 65 66 @Override onLoadFinished(Loader<File> loader, File generatedHtmlFile)67 public void onLoadFinished(Loader<File> loader, File generatedHtmlFile) { 68 showGeneratedHtmlFile(generatedHtmlFile); 69 } 70 71 @Override onLoaderReset(Loader<File> loader)72 public void onLoaderReset(Loader<File> loader) { 73 } 74 showHtmlFromDefaultXmlFiles()75 private void showHtmlFromDefaultXmlFiles() { 76 getSupportLoaderManager().initLoader(LOADER_ID_LICENSE_HTML_LOADER, Bundle.EMPTY, this); 77 } 78 79 @VisibleForTesting getUriFromGeneratedHtmlFile(File generatedHtmlFile)80 Uri getUriFromGeneratedHtmlFile(File generatedHtmlFile) { 81 return FileProvider.getUriForFile(this, Utils.FILE_PROVIDER_AUTHORITY, 82 generatedHtmlFile); 83 } 84 showGeneratedHtmlFile(File generatedHtmlFile)85 private void showGeneratedHtmlFile(File generatedHtmlFile) { 86 if (generatedHtmlFile != null) { 87 showHtmlFromUri(getUriFromGeneratedHtmlFile(generatedHtmlFile)); 88 } else { 89 Log.e(TAG, "Failed to generate."); 90 showErrorAndFinish(); 91 } 92 } 93 showHtmlFromUri(Uri uri)94 private void showHtmlFromUri(Uri uri) { 95 // Kick off external viewer due to WebView security restrictions; we 96 // carefully point it at HTMLViewer, since it offers to decompress 97 // before viewing. 98 final Intent intent = new Intent(Intent.ACTION_VIEW); 99 intent.setDataAndType(uri, "text/html"); 100 intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.settings_license_activity_title)); 101 if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 102 intent.addFlags( 103 Intent.FLAG_GRANT_READ_URI_PERMISSION 104 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 105 } 106 intent.addCategory(Intent.CATEGORY_DEFAULT); 107 ComponentName componentName = new ComponentName( 108 "com.android.htmlviewer", "com.android.htmlviewer.HTMLViewerActivity"); 109 intent.setComponent(componentName); 110 intent.setPackage("com.android.htmlviewer"); 111 112 try { 113 startActivity(intent); 114 finish(); 115 } catch (ActivityNotFoundException e) { 116 Log.e(TAG, "Failed to find viewer", e); 117 showErrorAndFinish(); 118 } 119 } 120 showErrorAndFinish()121 private void showErrorAndFinish() { 122 Toast.makeText(this, R.string.settings_license_activity_unavailable, Toast.LENGTH_LONG) 123 .show(); 124 finish(); 125 } 126 127 @VisibleForTesting isFileValid(final File file)128 boolean isFileValid(final File file) { 129 return file.exists() && file.length() != 0; 130 } 131 } 132