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