1 /** 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17 package com.android.settings.applications; 18 19 import android.app.Activity; 20 import android.app.AppOpsManager; 21 import android.app.Fragment; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.PackageInfo; 25 import android.content.pm.PackageManager; 26 import android.content.pm.PackageManager.NameNotFoundException; 27 import android.content.pm.PermissionGroupInfo; 28 import android.content.pm.PermissionInfo; 29 import android.content.res.Resources; 30 import android.graphics.drawable.Drawable; 31 import android.os.Bundle; 32 import android.util.Log; 33 import android.view.LayoutInflater; 34 import android.view.View; 35 import android.view.ViewGroup; 36 import android.widget.CompoundButton; 37 import android.widget.ImageView; 38 import android.widget.LinearLayout; 39 import android.widget.Switch; 40 import android.widget.TextView; 41 42 import com.android.internal.logging.MetricsLogger; 43 import com.android.settings.InstrumentedFragment; 44 import com.android.settings.R; 45 import com.android.settings.SettingsActivity; 46 import com.android.settings.Utils; 47 48 import java.util.List; 49 50 public class AppOpsDetails extends InstrumentedFragment { 51 static final String TAG = "AppOpsDetails"; 52 53 public static final String ARG_PACKAGE_NAME = "package"; 54 55 private AppOpsState mState; 56 private PackageManager mPm; 57 private AppOpsManager mAppOps; 58 private PackageInfo mPackageInfo; 59 private LayoutInflater mInflater; 60 private View mRootView; 61 private LinearLayout mOperationsSection; 62 63 // Utility method to set application label and icon. setAppLabelAndIcon(PackageInfo pkgInfo)64 private void setAppLabelAndIcon(PackageInfo pkgInfo) { 65 final View appSnippet = mRootView.findViewById(R.id.app_snippet); 66 CharSequence label = mPm.getApplicationLabel(pkgInfo.applicationInfo); 67 Drawable icon = mPm.getApplicationIcon(pkgInfo.applicationInfo); 68 InstalledAppDetails.setupAppSnippet(appSnippet, label, icon, 69 pkgInfo != null ? pkgInfo.versionName : null); 70 } 71 retrieveAppEntry()72 private String retrieveAppEntry() { 73 final Bundle args = getArguments(); 74 String packageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null; 75 if (packageName == null) { 76 Intent intent = (args == null) ? 77 getActivity().getIntent() : (Intent) args.getParcelable("intent"); 78 if (intent != null) { 79 packageName = intent.getData().getSchemeSpecificPart(); 80 } 81 } 82 try { 83 mPackageInfo = mPm.getPackageInfo(packageName, 84 PackageManager.GET_DISABLED_COMPONENTS | 85 PackageManager.GET_UNINSTALLED_PACKAGES); 86 } catch (NameNotFoundException e) { 87 Log.e(TAG, "Exception when retrieving package:" + packageName, e); 88 mPackageInfo = null; 89 } 90 91 return packageName; 92 } 93 refreshUi()94 private boolean refreshUi() { 95 if (mPackageInfo == null) { 96 return false; 97 } 98 99 setAppLabelAndIcon(mPackageInfo); 100 101 Resources res = getActivity().getResources(); 102 103 mOperationsSection.removeAllViews(); 104 String lastPermGroup = ""; 105 for (AppOpsState.OpsTemplate tpl : AppOpsState.ALL_TEMPLATES) { 106 List<AppOpsState.AppOpEntry> entries = mState.buildState(tpl, 107 mPackageInfo.applicationInfo.uid, mPackageInfo.packageName); 108 for (final AppOpsState.AppOpEntry entry : entries) { 109 final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0); 110 final View view = mInflater.inflate(R.layout.app_ops_details_item, 111 mOperationsSection, false); 112 mOperationsSection.addView(view); 113 String perm = AppOpsManager.opToPermission(firstOp.getOp()); 114 if (perm != null) { 115 try { 116 PermissionInfo pi = mPm.getPermissionInfo(perm, 0); 117 if (pi.group != null && !lastPermGroup.equals(pi.group)) { 118 lastPermGroup = pi.group; 119 PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0); 120 if (pgi.icon != 0) { 121 ((ImageView)view.findViewById(R.id.op_icon)).setImageDrawable( 122 pgi.loadIcon(mPm)); 123 } 124 } 125 } catch (NameNotFoundException e) { 126 } 127 } 128 ((TextView)view.findViewById(R.id.op_name)).setText( 129 entry.getSwitchText(mState)); 130 ((TextView)view.findViewById(R.id.op_time)).setText( 131 entry.getTimeText(res, true)); 132 Switch sw = (Switch)view.findViewById(R.id.switchWidget); 133 final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp()); 134 sw.setChecked(mAppOps.checkOp(switchOp, entry.getPackageOps().getUid(), 135 entry.getPackageOps().getPackageName()) == AppOpsManager.MODE_ALLOWED); 136 sw.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() { 137 @Override 138 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 139 mAppOps.setMode(switchOp, entry.getPackageOps().getUid(), 140 entry.getPackageOps().getPackageName(), isChecked 141 ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); 142 } 143 }); 144 } 145 } 146 147 return true; 148 } 149 setIntentAndFinish(boolean finish, boolean appChanged)150 private void setIntentAndFinish(boolean finish, boolean appChanged) { 151 Intent intent = new Intent(); 152 intent.putExtra(ManageApplications.APP_CHG, appChanged); 153 SettingsActivity sa = (SettingsActivity)getActivity(); 154 sa.finishPreferencePanel(this, Activity.RESULT_OK, intent); 155 } 156 157 /** Called when the activity is first created. */ 158 @Override onCreate(Bundle icicle)159 public void onCreate(Bundle icicle) { 160 super.onCreate(icicle); 161 162 mState = new AppOpsState(getActivity()); 163 mPm = getActivity().getPackageManager(); 164 mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 165 mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE); 166 167 retrieveAppEntry(); 168 169 setHasOptionsMenu(true); 170 } 171 172 @Override onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)173 public View onCreateView( 174 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 175 final View view = inflater.inflate(R.layout.app_ops_details, container, false); 176 Utils.prepareCustomPreferencesList(container, view, view, false); 177 178 mRootView = view; 179 mOperationsSection = (LinearLayout)view.findViewById(R.id.operations_section); 180 return view; 181 } 182 183 @Override getMetricsCategory()184 protected int getMetricsCategory() { 185 return MetricsLogger.APP_OPS_DETAILS; 186 } 187 188 @Override onResume()189 public void onResume() { 190 super.onResume(); 191 if (!refreshUi()) { 192 setIntentAndFinish(true, true); 193 } 194 } 195 } 196