AppOpsState.java revision 27daaab633a80be50863e6539e947db674090662
118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn/** 218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Copyright (C) 2013 The Android Open Source Project 318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); you may not 518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * use this file except in compliance with the License. You may obtain a copy 618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * of the License at 718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * 1018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 1218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 1318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * License for the specific language governing permissions and limitations 1418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * under the License. 1518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 1618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornpackage com.android.settings.applications; 1818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.app.AppOpsManager; 2018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.Context; 2118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.pm.ApplicationInfo; 2218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.pm.PackageInfo; 2318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.pm.PackageManager; 2418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 2518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.content.res.Resources; 2618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.graphics.drawable.Drawable; 2718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.os.Parcel; 2818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.os.Parcelable; 2918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport android.text.format.DateUtils; 3018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 310dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.util.Log; 320dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackbornimport android.util.SparseArray; 3318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport com.android.settings.R; 3418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.io.File; 3618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.text.Collator; 3718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.util.ArrayList; 3818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.util.Collections; 3918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.util.Comparator; 4018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.util.HashMap; 4118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornimport java.util.List; 4218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 4318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackbornpublic class AppOpsState { 440dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn static final String TAG = "AppOpsState"; 450dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn static final boolean DEBUG = false; 460dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 4718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final Context mContext; 4818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final AppOpsManager mAppOps; 4918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final PackageManager mPm; 500dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final CharSequence[] mOpNames; 5118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn List<AppOpEntry> mApps; 5318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsState(Context context) { 5518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mContext = context; 5618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 5718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mPm = context.getPackageManager(); 580dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOpNames = context.getResources().getTextArray(R.array.app_ops_names); 5918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 6018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 6118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class OpsTemplate implements Parcelable { 6218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public final int[] ops; 6327daaab633a80be50863e6539e947db674090662Dianne Hackborn public final boolean[] showPerms; 6418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 6527daaab633a80be50863e6539e947db674090662Dianne Hackborn public OpsTemplate(int[] _ops, boolean[] _showPerms) { 6618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ops = _ops; 6727daaab633a80be50863e6539e947db674090662Dianne Hackborn showPerms = _showPerms; 6818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 6918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 7018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn OpsTemplate(Parcel src) { 7118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ops = src.createIntArray(); 7227daaab633a80be50863e6539e947db674090662Dianne Hackborn showPerms = src.createBooleanArray(); 7318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 7418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 7518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 7618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int describeContents() { 7718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return 0; 7818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 7918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 8018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 8118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 8218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn dest.writeIntArray(ops); 8327daaab633a80be50863e6539e947db674090662Dianne Hackborn dest.writeBooleanArray(showPerms); 8418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 8518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 8618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final Creator<OpsTemplate> CREATOR = new Creator<OpsTemplate>() { 8718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public OpsTemplate createFromParcel(Parcel source) { 8818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return new OpsTemplate(source); 8918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 9118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public OpsTemplate[] newArray(int size) { 9218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return new OpsTemplate[size]; 9318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn }; 9518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 9718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate LOCATION_TEMPLATE = new OpsTemplate( 9818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn new int[] { AppOpsManager.OP_COARSE_LOCATION, 9918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_FINE_LOCATION, 1000dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_GPS, 10127daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_WIFI_SCAN, 10227daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_NEIGHBORING_CELLS }, 10327daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 10427daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 10527daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 10627daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 10727daaab633a80be50863e6539e947db674090662Dianne Hackborn false } 10818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 10918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 11018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate PERSONAL_TEMPLATE = new OpsTemplate( 11118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn new int[] { AppOpsManager.OP_READ_CONTACTS, 11218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_WRITE_CONTACTS, 11318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_READ_CALL_LOG, 1140dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_WRITE_CALL_LOG, 1150dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_READ_CALENDAR, 11627daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_WRITE_CALENDAR }, 11727daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 11827daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 11927daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12027daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12127daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12227daaab633a80be50863e6539e947db674090662Dianne Hackborn true } 12318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 12418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 12518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate DEVICE_TEMPLATE = new OpsTemplate( 126df3f6d6c4722a7acc8189e47d0499aaf618969f9Daniel Sandler new int[] { AppOpsManager.OP_VIBRATE, 12727daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_POST_NOTIFICATION, 12827daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_CALL_PHONE }, 12927daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { false, 13027daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 13127daaab633a80be50863e6539e947db674090662Dianne Hackborn true } 13218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 13318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1340dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public static final OpsTemplate[] ALL_TEMPLATES = new OpsTemplate[] { 1350dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn LOCATION_TEMPLATE, PERSONAL_TEMPLATE, DEVICE_TEMPLATE 1360dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn }; 1370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 13818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 13918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 14018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 14118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppEntry { 14218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsState mState; 14318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ApplicationInfo mInfo; 14418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final File mApkFile; 1450dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private final SparseArray<AppOpsManager.OpEntry> mOps 1460dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn = new SparseArray<AppOpsManager.OpEntry>(); 14727daaab633a80be50863e6539e947db674090662Dianne Hackborn private final SparseArray<AppOpEntry> mOpSwitches 14827daaab633a80be50863e6539e947db674090662Dianne Hackborn = new SparseArray<AppOpEntry>(); 14918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private String mLabel; 15018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private Drawable mIcon; 15118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private boolean mMounted; 15218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 15318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry(AppOpsState state, ApplicationInfo info) { 15418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mState = state; 15518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mInfo = info; 15618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApkFile = new File(info.sourceDir); 15718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 15818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 15927daaab633a80be50863e6539e947db674090662Dianne Hackborn public void addOp(AppOpEntry entry, AppOpsManager.OpEntry op) { 1600dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.put(op.getOp(), op); 16127daaab633a80be50863e6539e947db674090662Dianne Hackborn mOpSwitches.put(AppOpsManager.opToSwitch(op.getOp()), entry); 1620dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1630dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 1640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public boolean hasOp(int op) { 1650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mOps.indexOfKey(op) >= 0; 1660dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 1670dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 16827daaab633a80be50863e6539e947db674090662Dianne Hackborn public AppOpEntry getOpSwitch(int op) { 16927daaab633a80be50863e6539e947db674090662Dianne Hackborn return mOpSwitches.get(AppOpsManager.opToSwitch(op)); 17027daaab633a80be50863e6539e947db674090662Dianne Hackborn } 17127daaab633a80be50863e6539e947db674090662Dianne Hackborn 17218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public ApplicationInfo getApplicationInfo() { 17318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mInfo; 17418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 17518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 17618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public String getLabel() { 17718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 17818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 17918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 18018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public Drawable getIcon() { 18118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mIcon == null) { 18218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 18318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 18418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 18518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 18618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 18718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 18818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else if (!mMounted) { 18918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // If the app wasn't mounted but is now mounted, reload 19018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // its icon. 19118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 19218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 19318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 19418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 19518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 19618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 19718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 19818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 19918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 20018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mState.mContext.getResources().getDrawable( 20118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn android.R.drawable.sym_def_app_icon); 20218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 20318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 20418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 20518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 20618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 20718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 20818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn void loadLabel(Context context) { 20918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mLabel == null || !mMounted) { 21018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (!mApkFile.exists()) { 21118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 21218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = mInfo.packageName; 21318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 21418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 21518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn CharSequence label = mInfo.loadLabel(context.getPackageManager()); 21618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = label != null ? label.toString() : mInfo.packageName; 21718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 21818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 21918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 22018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 22118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 22218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 22318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 22418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 22518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppOpEntry { 22618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsManager.PackageOps mPkgOps; 22718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mOps 22818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 22927daaab633a80be50863e6539e947db674090662Dianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mBriefOps 23027daaab633a80be50863e6539e947db674090662Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 23118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppEntry mApp; 23218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 23327daaab633a80be50863e6539e947db674090662Dianne Hackborn public AppOpEntry(AppOpsManager.PackageOps pkg, AppOpsManager.OpEntry op, AppEntry app, 23427daaab633a80be50863e6539e947db674090662Dianne Hackborn boolean brief) { 23518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mPkgOps = pkg; 23618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApp = app; 23727daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 2380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.add(op); 23927daaab633a80be50863e6539e947db674090662Dianne Hackborn if (brief) { 24027daaab633a80be50863e6539e947db674090662Dianne Hackborn mBriefOps.add(op); 24127daaab633a80be50863e6539e947db674090662Dianne Hackborn } 24218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 24318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 24427daaab633a80be50863e6539e947db674090662Dianne Hackborn private static void addOp(ArrayList<AppOpsManager.OpEntry> list, AppOpsManager.OpEntry op) { 24527daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<list.size(); i++) { 24627daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OpEntry pos = list.get(i); 24718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (pos.isRunning() != op.isRunning()) { 24818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (op.isRunning()) { 24927daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 25018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 25118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 2520dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 25318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 2540dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pos.getTime() < op.getTime()) { 25527daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 25618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 25718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25927daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(op); 26027daaab633a80be50863e6539e947db674090662Dianne Hackborn } 26127daaab633a80be50863e6539e947db674090662Dianne Hackborn 26227daaab633a80be50863e6539e947db674090662Dianne Hackborn public void addOp(AppOpsManager.OpEntry op, boolean brief) { 26327daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 26427daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(mOps, op); 26527daaab633a80be50863e6539e947db674090662Dianne Hackborn if (brief) { 26627daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(mBriefOps, op); 26727daaab633a80be50863e6539e947db674090662Dianne Hackborn } 26818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 26918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 27018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry getAppEntry() { 27118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp; 27218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 27418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.PackageOps getPackageOps() { 27518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mPkgOps; 27618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 27818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int getNumOpEntry() { 27918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.size(); 28018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 28218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.OpEntry getOpEntry(int pos) { 28318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(pos); 28418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 28627daaab633a80be50863e6539e947db674090662Dianne Hackborn private CharSequence getLabelText(ArrayList<AppOpsManager.OpEntry> ops, 28727daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsState state) { 28827daaab633a80be50863e6539e947db674090662Dianne Hackborn if (ops.size() == 1) { 28927daaab633a80be50863e6539e947db674090662Dianne Hackborn return state.mOpNames[ops.get(0).getOp()]; 29018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 29118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn StringBuilder builder = new StringBuilder(); 29227daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<ops.size(); i++) { 29318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (i > 0) { 29418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn builder.append(", "); 29518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29627daaab633a80be50863e6539e947db674090662Dianne Hackborn builder.append(state.mOpNames[ops.get(i).getOp()]); 29718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return builder.toString(); 29918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 30018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 30118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 30227daaab633a80be50863e6539e947db674090662Dianne Hackborn public CharSequence getLabelText(AppOpsState state) { 30327daaab633a80be50863e6539e947db674090662Dianne Hackborn return getLabelText(mOps, state); 30427daaab633a80be50863e6539e947db674090662Dianne Hackborn } 30527daaab633a80be50863e6539e947db674090662Dianne Hackborn 30627daaab633a80be50863e6539e947db674090662Dianne Hackborn public CharSequence getBriefLabelText(AppOpsState state) { 30727daaab633a80be50863e6539e947db674090662Dianne Hackborn if (mBriefOps.size() > 0) { 30827daaab633a80be50863e6539e947db674090662Dianne Hackborn return getLabelText(mBriefOps, state); 30927daaab633a80be50863e6539e947db674090662Dianne Hackborn } else { 31027daaab633a80be50863e6539e947db674090662Dianne Hackborn return getLabelText(mOps, state); 31127daaab633a80be50863e6539e947db674090662Dianne Hackborn } 31227daaab633a80be50863e6539e947db674090662Dianne Hackborn } 31327daaab633a80be50863e6539e947db674090662Dianne Hackborn 31418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public CharSequence getTimeText(Resources res) { 31518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (isRunning()) { 31618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return res.getText(R.string.app_ops_running); 31718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 31818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (getTime() > 0) { 31918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return DateUtils.getRelativeTimeSpanString(getTime(), 32018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn System.currentTimeMillis(), 32118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.MINUTE_IN_MILLIS, 32218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.FORMAT_ABBREV_RELATIVE); 32318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 32418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return ""; 32518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 32618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 32718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public boolean isRunning() { 32818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).isRunning(); 32918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 33118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public long getTime() { 33218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).getTime(); 33318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 33518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 33618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp.getLabel(); 33718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 34018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 34118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Perform alphabetical comparison of application entry objects. 34218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 34318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final Comparator<AppOpEntry> APP_OP_COMPARATOR = new Comparator<AppOpEntry>() { 34418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final Collator sCollator = Collator.getInstance(); 34518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 34618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int compare(AppOpEntry object1, AppOpEntry object2) { 34718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.isRunning() != object2.isRunning()) { 34818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Currently running ops go first. 34918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.isRunning() ? -1 : 1; 35018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 35118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.getTime() != object2.getTime()) { 35218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // More recent times go first. 35318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.getTime() > object2.getTime() ? -1 : 1; 35418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 35518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return sCollator.compare(object1.getAppEntry().getLabel(), 35618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn object2.getAppEntry().getLabel()); 35718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 35818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn }; 35918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 36018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private void addOp(List<AppOpEntry> entries, AppOpsManager.PackageOps pkgOps, 36127daaab633a80be50863e6539e947db674090662Dianne Hackborn AppEntry appEntry, AppOpsManager.OpEntry opEntry, boolean brief, boolean allowMerge) { 36227daaab633a80be50863e6539e947db674090662Dianne Hackborn if (allowMerge && entries.size() > 0) { 36318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpEntry last = entries.get(entries.size()-1); 36418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (last.getAppEntry() == appEntry) { 36518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean lastExe = last.getTime() != 0; 36618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean entryExe = opEntry.getTime() != 0; 36718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (lastExe == entryExe) { 3680dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 3690dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": append to " + last); 37027daaab633a80be50863e6539e947db674090662Dianne Hackborn last.addOp(opEntry, brief); 37118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 37218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 37318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 37418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 37527daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpEntry entry = appEntry.getOpSwitch(opEntry.getOp()); 37627daaab633a80be50863e6539e947db674090662Dianne Hackborn if (entry != null) { 37727daaab633a80be50863e6539e947db674090662Dianne Hackborn entry.addOp(opEntry, brief); 37827daaab633a80be50863e6539e947db674090662Dianne Hackborn return; 37927daaab633a80be50863e6539e947db674090662Dianne Hackborn } 38027daaab633a80be50863e6539e947db674090662Dianne Hackborn entry = new AppOpEntry(pkgOps, opEntry, appEntry, brief); 3810dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 3820dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": making new " + entry); 38318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn entries.add(entry); 38418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 38518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 38618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl) { 38718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return buildState(tpl, 0, null); 38818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 38918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private AppEntry getAppEntry(final Context context, final HashMap<String, AppEntry> appEntries, 3910dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final String packageName, ApplicationInfo appInfo) { 3920dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = appEntries.get(packageName); 3930dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 3940dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appInfo == null) { 3950dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 3960dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo = mPm.getApplicationInfo(packageName, 3970dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageManager.GET_DISABLED_COMPONENTS 3980dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn | PackageManager.GET_UNINSTALLED_PACKAGES); 3990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (PackageManager.NameNotFoundException e) { 4000dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Log.w(TAG, "Unable to find info for package " + packageName); 4010dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return null; 4020dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4030dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4040dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry = new AppEntry(this, appInfo); 4050dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry.loadLabel(context); 4060dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntries.put(packageName, appEntry); 4070dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4080dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return appEntry; 4090dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4100dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 41118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName) { 41218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final Context context = mContext; 41318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 41418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final HashMap<String, AppEntry> appEntries = new HashMap<String, AppEntry>(); 41527daaab633a80be50863e6539e947db674090662Dianne Hackborn final List<AppOpEntry> entries = new ArrayList<AppOpEntry>(); 4160dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 41727daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<String> perms = new ArrayList<String>(); 41827daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<Integer> permOps = new ArrayList<Integer>(); 41927daaab633a80be50863e6539e947db674090662Dianne Hackborn final boolean[] brief = new boolean[AppOpsManager._NUM_OP]; 4200dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<tpl.ops.length; i++) { 42127daaab633a80be50863e6539e947db674090662Dianne Hackborn brief[tpl.ops[i]] = tpl.showPerms[i]; 42227daaab633a80be50863e6539e947db674090662Dianne Hackborn if (tpl.showPerms[i]) { 42327daaab633a80be50863e6539e947db674090662Dianne Hackborn String perm = AppOpsManager.opToPermission(tpl.ops[i]); 42427daaab633a80be50863e6539e947db674090662Dianne Hackborn if (perm != null && !perms.contains(perm)) { 42527daaab633a80be50863e6539e947db674090662Dianne Hackborn perms.add(perm); 42627daaab633a80be50863e6539e947db674090662Dianne Hackborn permOps.add(tpl.ops[i]); 42727daaab633a80be50863e6539e947db674090662Dianne Hackborn } 4280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 43018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 43118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn List<AppOpsManager.PackageOps> pkgs; 43218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (packageName != null) { 43318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getOpsForPackage(uid, packageName, tpl.ops); 43418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 43518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getPackagesForOps(tpl.ops); 43618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 4370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 4380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pkgs != null) { 4390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<pkgs.size(); i++) { 4400dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = pkgs.get(i); 4410dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null); 4420dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 4430dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 4440dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4450dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int j=0; j<pkgOps.getOps().size(); j++) { 4460dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OpEntry opEntry = pkgOps.getOps().get(j); 44727daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, brief[opEntry.getOp()], 44827daaab633a80be50863e6539e947db674090662Dianne Hackborn packageName == null); 44918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 4530dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<PackageInfo> apps; 4540dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (packageName != null) { 4550dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = new ArrayList<PackageInfo>(); 4560dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 4570dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo pi = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 4580dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps.add(pi); 4590dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (NameNotFoundException e) { 46018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 4610dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } else { 4620dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String[] permsArray = new String[perms.size()]; 4630dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn perms.toArray(permsArray); 4640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = mPm.getPackagesHoldingPermissions(permsArray, 0); 4650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4660dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<apps.size(); i++) { 4670dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo appInfo = apps.get(i); 4680dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, appInfo.packageName, 4690dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo.applicationInfo); 4700dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 4710dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 4720dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4730dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<AppOpsManager.OpEntry> dummyOps = null; 4740dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = null; 4757d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissions != null) { 4767d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int j=0; j<appInfo.requestedPermissions.length; j++) { 4777d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissionsFlags != null) { 4787d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if ((appInfo.requestedPermissionsFlags[j] 4797d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) { 4807d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " 4817d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j] + " not granted; skipping"); 4827d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler break; 4837d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 48418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 4857d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + ": requested perm " 4867d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j]); 4877d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int k=0; k<perms.size(); k++) { 4887d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (!perms.get(k).equals(appInfo.requestedPermissions[j])) { 4897d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 4907d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 4917d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " + perms.get(k) 4927d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + " has op " + permOps.get(k) + ": " + appEntry.hasOp(permOps.get(k))); 4937d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appEntry.hasOp(permOps.get(k))) { 4947d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 4957d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 4967d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (dummyOps == null) { 4977d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps = new ArrayList<AppOpsManager.OpEntry>(); 4987d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler pkgOps = new AppOpsManager.PackageOps( 4997d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler appInfo.packageName, appInfo.applicationInfo.uid, dummyOps); 5007d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler 5017d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5027d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler AppOpsManager.OpEntry opEntry = new AppOpsManager.OpEntry( 5037d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0); 5047d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps.add(opEntry); 50527daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, brief[opEntry.getOp()], 50627daaab633a80be50863e6539e947db674090662Dianne Hackborn packageName == null); 5070dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5080dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 50918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 51018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 51118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 51218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Sort the list. 51318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn Collections.sort(entries, APP_OP_COMPARATOR); 51418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 51518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Done! 51618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return entries; 51718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5180dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 5190dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public CharSequence getLabelText(AppOpsManager.OpEntry op) { 5200dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mOpNames[op.getOp()]; 5210dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5220dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 5230dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public CharSequence getTimeText(AppOpsManager.OpEntry op) { 5240dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (op.isRunning()) { 5250dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mContext.getResources().getText(R.string.app_ops_running); 5260dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5270dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (op.getTime() > 0) { 5280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return DateUtils.getRelativeTimeSpanString(op.getTime(), 5290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn System.currentTimeMillis(), 5300dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn DateUtils.MINUTE_IN_MILLIS, 5310dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn DateUtils.FORMAT_ABBREV_RELATIVE); 5320dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5330dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mContext.getResources().getText(R.string.app_ops_never_used); 5340dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5350dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 53618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn} 537