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