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