| /** |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy |
| * of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package com.android.settings.applications; |
| |
| import android.app.Activity; |
| import android.app.AppOpsManager; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.PackageInfo; |
| import android.content.pm.PackageManager; |
| import android.content.pm.PackageManager.NameNotFoundException; |
| import android.content.pm.PermissionGroupInfo; |
| import android.content.pm.PermissionInfo; |
| import android.content.res.Resources; |
| import android.graphics.drawable.Drawable; |
| import android.os.Bundle; |
| import android.text.TextUtils; |
| import android.util.Log; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.CompoundButton; |
| import android.widget.ImageView; |
| import android.widget.LinearLayout; |
| import android.widget.Switch; |
| import android.widget.TextView; |
| |
| import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
| import com.android.settings.core.InstrumentedPreferenceFragment; |
| import com.android.settings.R; |
| import com.android.settings.SettingsActivity; |
| import com.android.settings.Utils; |
| import com.android.settings.widget.EntityHeaderController; |
| |
| import java.util.List; |
| |
| public class AppOpsDetails extends InstrumentedPreferenceFragment { |
| static final String TAG = "AppOpsDetails"; |
| |
| public static final String ARG_PACKAGE_NAME = "package"; |
| |
| private AppOpsState mState; |
| private PackageManager mPm; |
| private AppOpsManager mAppOps; |
| private PackageInfo mPackageInfo; |
| private LayoutInflater mInflater; |
| private View mRootView; |
| private LinearLayout mOperationsSection; |
| |
| // Utility method to set application label and icon. |
| private void setAppLabelAndIcon(PackageInfo pkgInfo) { |
| final View appSnippet = mRootView.findViewById(R.id.app_snippet); |
| CharSequence label = mPm.getApplicationLabel(pkgInfo.applicationInfo); |
| Drawable icon = mPm.getApplicationIcon(pkgInfo.applicationInfo); |
| setupAppSnippet(appSnippet, label, icon, |
| pkgInfo != null ? pkgInfo.versionName : null); |
| } |
| |
| private String retrieveAppEntry() { |
| final Bundle args = getArguments(); |
| String packageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null; |
| if (packageName == null) { |
| Intent intent = (args == null) ? |
| getActivity().getIntent() : (Intent) args.getParcelable("intent"); |
| if (intent != null) { |
| packageName = intent.getData().getSchemeSpecificPart(); |
| } |
| } |
| try { |
| mPackageInfo = mPm.getPackageInfo(packageName, |
| PackageManager.MATCH_DISABLED_COMPONENTS | |
| PackageManager.MATCH_ANY_USER); |
| } catch (NameNotFoundException e) { |
| Log.e(TAG, "Exception when retrieving package:" + packageName, e); |
| mPackageInfo = null; |
| } |
| |
| return packageName; |
| } |
| |
| private boolean refreshUi() { |
| if (mPackageInfo == null) { |
| return false; |
| } |
| |
| setAppLabelAndIcon(mPackageInfo); |
| |
| Resources res = getActivity().getResources(); |
| |
| mOperationsSection.removeAllViews(); |
| String lastPermGroup = ""; |
| for (AppOpsState.OpsTemplate tpl : AppOpsState.ALL_TEMPLATES) { |
| List<AppOpsState.AppOpEntry> entries = mState.buildState(tpl, |
| mPackageInfo.applicationInfo.uid, mPackageInfo.packageName); |
| for (final AppOpsState.AppOpEntry entry : entries) { |
| final AppOpsManager.OpEntry firstOp = entry.getOpEntry(0); |
| final View view = mInflater.inflate(R.layout.app_ops_details_item, |
| mOperationsSection, false); |
| mOperationsSection.addView(view); |
| String perm = AppOpsManager.opToPermission(firstOp.getOp()); |
| if (perm != null) { |
| try { |
| PermissionInfo pi = mPm.getPermissionInfo(perm, 0); |
| if (pi.group != null && !lastPermGroup.equals(pi.group)) { |
| lastPermGroup = pi.group; |
| PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0); |
| if (pgi.icon != 0) { |
| ((ImageView)view.findViewById(R.id.op_icon)).setImageDrawable( |
| pgi.loadIcon(mPm)); |
| } |
| } |
| } catch (NameNotFoundException e) { |
| } |
| } |
| ((TextView)view.findViewById(R.id.op_name)).setText( |
| entry.getSwitchText(mState)); |
| ((TextView)view.findViewById(R.id.op_time)).setText( |
| entry.getTimeText(res, true)); |
| Switch sw = (Switch)view.findViewById(R.id.switchWidget); |
| final int switchOp = AppOpsManager.opToSwitch(firstOp.getOp()); |
| sw.setChecked(mAppOps.checkOp(switchOp, entry.getPackageOps().getUid(), |
| entry.getPackageOps().getPackageName()) == AppOpsManager.MODE_ALLOWED); |
| sw.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() { |
| @Override |
| public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
| mAppOps.setMode(switchOp, entry.getPackageOps().getUid(), |
| entry.getPackageOps().getPackageName(), isChecked |
| ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); |
| } |
| }); |
| } |
| } |
| |
| return true; |
| } |
| |
| private void setIntentAndFinish(boolean finish, boolean appChanged) { |
| Intent intent = new Intent(); |
| intent.putExtra(ManageApplications.APP_CHG, appChanged); |
| SettingsActivity sa = (SettingsActivity)getActivity(); |
| sa.finishPreferencePanel(this, Activity.RESULT_OK, intent); |
| } |
| |
| /** Called when the activity is first created. */ |
| @Override |
| public void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| |
| mState = new AppOpsState(getActivity()); |
| mPm = getActivity().getPackageManager(); |
| mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
| mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE); |
| |
| retrieveAppEntry(); |
| |
| setHasOptionsMenu(true); |
| } |
| |
| @Override |
| public View onCreateView( |
| LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { |
| final View view = inflater.inflate(R.layout.app_ops_details, container, false); |
| Utils.prepareCustomPreferencesList(container, view, view, false); |
| |
| mRootView = view; |
| mOperationsSection = (LinearLayout)view.findViewById(R.id.operations_section); |
| return view; |
| } |
| |
| @Override |
| public int getMetricsCategory() { |
| return MetricsEvent.APP_OPS_DETAILS; |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| if (!refreshUi()) { |
| setIntentAndFinish(true, true); |
| } |
| } |
| |
| /** |
| * @deprecated app info pages should use {@link EntityHeaderController} to show the app header. |
| */ |
| void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon, |
| CharSequence versionName) { |
| LayoutInflater.from(appSnippet.getContext()).inflate(R.layout.widget_text_views, |
| appSnippet.findViewById(android.R.id.widget_frame)); |
| |
| ImageView iconView = appSnippet.findViewById(android.R.id.icon); |
| iconView.setImageDrawable(icon); |
| // Set application name. |
| TextView labelView = appSnippet.findViewById(android.R.id.title); |
| labelView.setText(label); |
| // Version number of application |
| TextView appVersion = appSnippet.findViewById(R.id.widget_text1); |
| |
| if (!TextUtils.isEmpty(versionName)) { |
| appVersion.setSelected(true); |
| appVersion.setVisibility(View.VISIBLE); |
| appVersion.setText(appSnippet.getContext().getString(R.string.version_text, |
| String.valueOf(versionName))); |
| } else { |
| appVersion.setVisibility(View.INVISIBLE); |
| } |
| } |
| } |