118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn/** 218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Copyright (C) 2013 The Android Open Source Project 318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); you may not 518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * use this file except in compliance with the License. You may obtain a copy 618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * of the License at 718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 1018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 1218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 1318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * License for the specific language governing permissions and limitations 1418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * under the License. 1518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 1618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornpackage com.android.settings.applications; 1818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 190dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.app.Activity; 200dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.app.AppOpsManager; 2118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.app.Fragment; 220dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.Context; 230dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.Intent; 240dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.pm.PackageInfo; 250dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.pm.PackageManager; 260dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 270dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.pm.PermissionGroupInfo; 280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.pm.PermissionInfo; 290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.content.res.Resources; 300dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.os.Bundle; 310dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.preference.PreferenceActivity; 320dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.util.Log; 330dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.view.LayoutInflater; 340dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.view.View; 350dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.view.ViewGroup; 360dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.widget.CompoundButton; 370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.widget.ImageView; 380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.widget.LinearLayout; 390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.widget.Switch; 400dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.widget.TextView; 410dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 420dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport com.android.settings.R; 430dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport com.android.settings.Utils; 440dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 450dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport java.util.List; 4618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 4718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornpublic class AppOpsDetails extends Fragment { 480dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn static final String TAG = "AppOpsDetails"; 490dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 500dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public static final String ARG_PACKAGE_NAME = "package"; 510dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 520dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private AppOpsState mState; 530dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private PackageManager mPm; 540dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private AppOpsManager mAppOps; 550dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private PackageInfo mPackageInfo; 560dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private LayoutInflater mInflater; 570dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private View mRootView; 580dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private TextView mAppVersion; 590dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private LinearLayout mOperationsSection; 600dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 610dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn // Utility method to set application label and icon. 620dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private void setAppLabelAndIcon(PackageInfo pkgInfo) { 630dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final View appSnippet = mRootView.findViewById(R.id.app_snippet); 640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appSnippet.setPaddingRelative(0, appSnippet.getPaddingTop(), 0, appSnippet.getPaddingBottom()); 650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 660dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn ImageView icon = (ImageView) appSnippet.findViewById(R.id.app_icon); 670dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn icon.setImageDrawable(mPm.getApplicationIcon(pkgInfo.applicationInfo)); 680dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn // Set application name. 690dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn TextView label = (TextView) appSnippet.findViewById(R.id.app_name); 700dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn label.setText(mPm.getApplicationLabel(pkgInfo.applicationInfo)); 710dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn // Version number of application 720dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mAppVersion = (TextView) appSnippet.findViewById(R.id.app_size); 730dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 740dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pkgInfo.versionName != null) { 750dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mAppVersion.setVisibility(View.VISIBLE); 760dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mAppVersion.setText(getActivity().getString(R.string.version_text, 770dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String.valueOf(pkgInfo.versionName))); 780dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } else { 790dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mAppVersion.setVisibility(View.INVISIBLE); 800dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 810dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 820dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 830dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private String retrieveAppEntry() { 840dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final Bundle args = getArguments(); 850dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String packageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null; 860dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (packageName == null) { 870dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Intent intent = (args == null) ? 880dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn getActivity().getIntent() : (Intent) args.getParcelable("intent"); 890dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (intent != null) { 900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn packageName = intent.getData().getSchemeSpecificPart(); 910dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 920dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 930dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 940dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mPackageInfo = mPm.getPackageInfo(packageName, 950dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageManager.GET_DISABLED_COMPONENTS | 960dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageManager.GET_UNINSTALLED_PACKAGES); 970dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (NameNotFoundException e) { 980dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Log.e(TAG, "Exception when retrieving package:" + packageName, e); 990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mPackageInfo = null; 1000dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1010dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1020dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return packageName; 1030dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1040dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1050dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private boolean refreshUi() { 1060dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (mPackageInfo == null) { 1070dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return false; 1080dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1090dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1100dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn setAppLabelAndIcon(mPackageInfo); 1110dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1120dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Resources res = getActivity().getResources(); 1130dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1140dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOperationsSection.removeAllViews(); 1150dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String lastPermGroup = ""; 1160dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (AppOpsState.OpsTemplate tpl : AppOpsState.ALL_TEMPLATES) { 1170dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<AppOpsState.AppOpEntry> entries = mState.buildState(tpl, 1180dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mPackageInfo.applicationInfo.uid, mPackageInfo.packageName); 1190dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (final AppOpsState.AppOpEntry entry : entries) { 12027daaab633a80be50863e6539e947db674090662Dianne Hackborn final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0); 12127daaab633a80be50863e6539e947db674090662Dianne Hackborn final View view = mInflater.inflate(R.layout.app_ops_details_item, 12227daaab633a80be50863e6539e947db674090662Dianne Hackborn mOperationsSection, false); 12327daaab633a80be50863e6539e947db674090662Dianne Hackborn mOperationsSection.addView(view); 12427daaab633a80be50863e6539e947db674090662Dianne Hackborn String perm = AppOpsManager.opToPermission(firstOp.getOp()); 12527daaab633a80be50863e6539e947db674090662Dianne Hackborn if (perm != null) { 12627daaab633a80be50863e6539e947db674090662Dianne Hackborn try { 12727daaab633a80be50863e6539e947db674090662Dianne Hackborn PermissionInfo pi = mPm.getPermissionInfo(perm, 0); 12827daaab633a80be50863e6539e947db674090662Dianne Hackborn if (pi.group != null && !lastPermGroup.equals(pi.group)) { 12927daaab633a80be50863e6539e947db674090662Dianne Hackborn lastPermGroup = pi.group; 13027daaab633a80be50863e6539e947db674090662Dianne Hackborn PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0); 13127daaab633a80be50863e6539e947db674090662Dianne Hackborn if (pgi.icon != 0) { 13227daaab633a80be50863e6539e947db674090662Dianne Hackborn ((ImageView)view.findViewById(R.id.op_icon)).setImageDrawable( 13327daaab633a80be50863e6539e947db674090662Dianne Hackborn pgi.loadIcon(mPm)); 1340dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1350dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 13627daaab633a80be50863e6539e947db674090662Dianne Hackborn } catch (NameNotFoundException e) { 1370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 13927daaab633a80be50863e6539e947db674090662Dianne Hackborn ((TextView)view.findViewById(R.id.op_name)).setText( 1408b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn entry.getSwitchText(mState)); 14127daaab633a80be50863e6539e947db674090662Dianne Hackborn ((TextView)view.findViewById(R.id.op_time)).setText( 1428b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn entry.getTimeText(res, true)); 14327daaab633a80be50863e6539e947db674090662Dianne Hackborn Switch sw = (Switch)view.findViewById(R.id.switchWidget); 14427daaab633a80be50863e6539e947db674090662Dianne Hackborn final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp()); 14527daaab633a80be50863e6539e947db674090662Dianne Hackborn sw.setChecked(mAppOps.checkOp(switchOp, entry.getPackageOps().getUid(), 14627daaab633a80be50863e6539e947db674090662Dianne Hackborn entry.getPackageOps().getPackageName()) == AppOpsManager.MODE_ALLOWED); 14727daaab633a80be50863e6539e947db674090662Dianne Hackborn sw.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() { 14827daaab633a80be50863e6539e947db674090662Dianne Hackborn @Override 14927daaab633a80be50863e6539e947db674090662Dianne Hackborn public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 15027daaab633a80be50863e6539e947db674090662Dianne Hackborn mAppOps.setMode(switchOp, entry.getPackageOps().getUid(), 15127daaab633a80be50863e6539e947db674090662Dianne Hackborn entry.getPackageOps().getPackageName(), isChecked 15227daaab633a80be50863e6539e947db674090662Dianne Hackborn ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); 15327daaab633a80be50863e6539e947db674090662Dianne Hackborn } 15427daaab633a80be50863e6539e947db674090662Dianne Hackborn }); 1550dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1560dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1570dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1580dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return true; 1590dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1600dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1610dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private void setIntentAndFinish(boolean finish, boolean appChanged) { 1620dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Intent intent = new Intent(); 1630dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn intent.putExtra(ManageApplications.APP_CHG, appChanged); 1640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PreferenceActivity pa = (PreferenceActivity)getActivity(); 1650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn pa.finishPreferencePanel(this, Activity.RESULT_OK, intent); 1660dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1670dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1680dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn /** Called when the activity is first created. */ 1690dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn @Override 1700dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public void onCreate(Bundle icicle) { 1710dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn super.onCreate(icicle); 1720dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1730dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mState = new AppOpsState(getActivity()); 1740dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mPm = getActivity().getPackageManager(); 1750dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 1760dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE); 1770dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1780dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn retrieveAppEntry(); 1790dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1800dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn setHasOptionsMenu(true); 1810dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1820dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1830dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn @Override 1840dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public View onCreateView( 1850dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1860dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final View view = inflater.inflate(R.layout.app_ops_details, container, false); 1870dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Utils.prepareCustomPreferencesList(container, view, view, false); 1880dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1890dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mRootView = view; 1900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOperationsSection = (LinearLayout)view.findViewById(R.id.operations_section); 1910dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return view; 1920dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 19318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1940dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn @Override 1950dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public void onResume() { 1960dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn super.onResume(); 1970dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (!refreshUi()) { 1980dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn setIntentAndFinish(true, true); 1990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 2000dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 20118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn} 202