AppOpsState.java revision ec74da60cda5d0d7d1901e20a5a7806ef4cf387f
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; 508b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn final CharSequence[] mOpSummaries; 518b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn final CharSequence[] mOpLabels; 5218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn List<AppOpEntry> mApps; 5418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsState(Context context) { 5618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mContext = context; 5718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 5818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mPm = context.getPackageManager(); 598b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn mOpSummaries = context.getResources().getTextArray(R.array.app_ops_summaries); 608b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn mOpLabels = context.getResources().getTextArray(R.array.app_ops_labels); 6118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 6218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 6318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class OpsTemplate implements Parcelable { 6418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public final int[] ops; 6527daaab633a80be50863e6539e947db674090662Dianne Hackborn public final boolean[] showPerms; 6618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 6727daaab633a80be50863e6539e947db674090662Dianne Hackborn public OpsTemplate(int[] _ops, boolean[] _showPerms) { 6818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ops = _ops; 6927daaab633a80be50863e6539e947db674090662Dianne Hackborn showPerms = _showPerms; 7018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 7118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 7218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn OpsTemplate(Parcel src) { 7318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ops = src.createIntArray(); 7427daaab633a80be50863e6539e947db674090662Dianne Hackborn showPerms = src.createBooleanArray(); 7518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 7618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 7718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 7818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int describeContents() { 7918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return 0; 8018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 8118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 8218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 8318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 8418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn dest.writeIntArray(ops); 8527daaab633a80be50863e6539e947db674090662Dianne Hackborn dest.writeBooleanArray(showPerms); 8618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 8718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 8818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final Creator<OpsTemplate> CREATOR = new Creator<OpsTemplate>() { 8918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public OpsTemplate createFromParcel(Parcel source) { 9018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return new OpsTemplate(source); 9118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 9318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public OpsTemplate[] newArray(int size) { 9418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return new OpsTemplate[size]; 9518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn }; 9718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 9818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 9918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate LOCATION_TEMPLATE = new OpsTemplate( 10018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn new int[] { AppOpsManager.OP_COARSE_LOCATION, 10118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_FINE_LOCATION, 1020dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_GPS, 10327daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_WIFI_SCAN, 10427daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OP_NEIGHBORING_CELLS }, 10527daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 10627daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 10727daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 10827daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 10927daaab633a80be50863e6539e947db674090662Dianne Hackborn false } 11018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 11118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 11218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate PERSONAL_TEMPLATE = new OpsTemplate( 11318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn new int[] { AppOpsManager.OP_READ_CONTACTS, 11418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_WRITE_CONTACTS, 11518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_READ_CALL_LOG, 1160dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_WRITE_CALL_LOG, 1170dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_READ_CALENDAR, 118782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_WRITE_CALENDAR, 119782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_READ_CLIPBOARD, 120782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_WRITE_CLIPBOARD }, 12127daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 12227daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12327daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12427daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12527daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 126782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn true, 127782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn false, 128782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn false } 12918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 13018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 131983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn public static final OpsTemplate MESSAGING_TEMPLATE = new OpsTemplate( 132983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn new int[] { AppOpsManager.OP_READ_SMS, 133983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_SMS, 134983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_EMERGECY_SMS, 135983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_MMS, 136983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_WAP_PUSH, 137983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_WRITE_SMS, 138983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_SEND_SMS, 139983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_READ_ICC_SMS, 140983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_WRITE_ICC_SMS }, 141983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn new boolean[] { true, 142983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 143983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 144983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 145983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 146983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 147983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 148983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 149983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true } 150983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn ); 151983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn 1526e91babedac9983b10fdf2650de86386800017beDianne Hackborn public static final OpsTemplate MEDIA_TEMPLATE = new OpsTemplate( 153df3f6d6c4722a7acc8189e47d0499aaf618969f9Daniel Sandler new int[] { AppOpsManager.OP_VIBRATE, 1547ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn AppOpsManager.OP_CAMERA, 1557ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn AppOpsManager.OP_RECORD_AUDIO, 1566e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_PLAY_AUDIO, 1576e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_TAKE_MEDIA_BUTTONS, 1586e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_TAKE_AUDIO_FOCUS, 1596e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_MASTER_VOLUME, 1606e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_VOICE_VOLUME, 1616e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_RING_VOLUME, 1626e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_MEDIA_VOLUME, 1636e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_ALARM_VOLUME, 1646e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, 1656e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, }, 16627daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { false, 167d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn true, 1687ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 1696e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1706e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1716e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1726e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1736e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1746e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1756e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1766e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1776e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1786e91babedac9983b10fdf2650de86386800017beDianne Hackborn false } 1796e91babedac9983b10fdf2650de86386800017beDianne Hackborn ); 1806e91babedac9983b10fdf2650de86386800017beDianne Hackborn 1816e91babedac9983b10fdf2650de86386800017beDianne Hackborn public static final OpsTemplate DEVICE_TEMPLATE = new OpsTemplate( 1826e91babedac9983b10fdf2650de86386800017beDianne Hackborn new int[] { AppOpsManager.OP_POST_NOTIFICATION, 1836e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_ACCESS_NOTIFICATIONS, 1846e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_CALL_PHONE, 1856e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_WRITE_SETTINGS, 186ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 187ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn AppOpsManager.OP_WAKE_LOCK }, 1886e91babedac9983b10fdf2650de86386800017beDianne Hackborn new boolean[] { false, 1897ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 1907ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 1917ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 192ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn true, 193ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn true, } 19418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 19518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 1960dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public static final OpsTemplate[] ALL_TEMPLATES = new OpsTemplate[] { 1976e91babedac9983b10fdf2650de86386800017beDianne Hackborn LOCATION_TEMPLATE, PERSONAL_TEMPLATE, MESSAGING_TEMPLATE, 1986e91babedac9983b10fdf2650de86386800017beDianne Hackborn MEDIA_TEMPLATE, DEVICE_TEMPLATE 1990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn }; 2000dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 20118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 20218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 20318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 20418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppEntry { 20518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsState mState; 20618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ApplicationInfo mInfo; 20718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final File mApkFile; 2080dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private final SparseArray<AppOpsManager.OpEntry> mOps 2090dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn = new SparseArray<AppOpsManager.OpEntry>(); 21027daaab633a80be50863e6539e947db674090662Dianne Hackborn private final SparseArray<AppOpEntry> mOpSwitches 21127daaab633a80be50863e6539e947db674090662Dianne Hackborn = new SparseArray<AppOpEntry>(); 21218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private String mLabel; 21318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private Drawable mIcon; 21418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private boolean mMounted; 21518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 21618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry(AppOpsState state, ApplicationInfo info) { 21718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mState = state; 21818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mInfo = info; 21918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApkFile = new File(info.sourceDir); 22018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 22118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 22227daaab633a80be50863e6539e947db674090662Dianne Hackborn public void addOp(AppOpEntry entry, AppOpsManager.OpEntry op) { 2230dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.put(op.getOp(), op); 22427daaab633a80be50863e6539e947db674090662Dianne Hackborn mOpSwitches.put(AppOpsManager.opToSwitch(op.getOp()), entry); 2250dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 2260dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 2270dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public boolean hasOp(int op) { 2280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mOps.indexOfKey(op) >= 0; 2290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 2300dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 23127daaab633a80be50863e6539e947db674090662Dianne Hackborn public AppOpEntry getOpSwitch(int op) { 23227daaab633a80be50863e6539e947db674090662Dianne Hackborn return mOpSwitches.get(AppOpsManager.opToSwitch(op)); 23327daaab633a80be50863e6539e947db674090662Dianne Hackborn } 23427daaab633a80be50863e6539e947db674090662Dianne Hackborn 23518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public ApplicationInfo getApplicationInfo() { 23618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mInfo; 23718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 23818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 23918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public String getLabel() { 24018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 24118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 24218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 24318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public Drawable getIcon() { 24418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mIcon == null) { 24518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 24618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 24718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 24818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 24918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 25018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else if (!mMounted) { 25218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // If the app wasn't mounted but is now mounted, reload 25318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // its icon. 25418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 25518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 25618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 25718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 25818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 26018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 26118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 26218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 26318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mState.mContext.getResources().getDrawable( 26418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn android.R.drawable.sym_def_app_icon); 26518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 26618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 26718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 26818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 26918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 27118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn void loadLabel(Context context) { 27218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mLabel == null || !mMounted) { 27318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (!mApkFile.exists()) { 27418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 27518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = mInfo.packageName; 27618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 27718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 27818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn CharSequence label = mInfo.loadLabel(context.getPackageManager()); 27918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = label != null ? label.toString() : mInfo.packageName; 28018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 28518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 28618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 28718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 28818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppOpEntry { 28918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsManager.PackageOps mPkgOps; 29018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mOps 29118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 2928b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mSwitchOps 29327daaab633a80be50863e6539e947db674090662Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 29418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppEntry mApp; 295d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn private final int mSwitchOrder; 29618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 297d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn public AppOpEntry(AppOpsManager.PackageOps pkg, AppOpsManager.OpEntry op, AppEntry app, 298d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn int switchOrder) { 29918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mPkgOps = pkg; 30018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApp = app; 301d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn mSwitchOrder = switchOrder; 30227daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 3030dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.add(op); 3048b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn mSwitchOps.add(op); 30518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 30618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 30727daaab633a80be50863e6539e947db674090662Dianne Hackborn private static void addOp(ArrayList<AppOpsManager.OpEntry> list, AppOpsManager.OpEntry op) { 30827daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<list.size(); i++) { 30927daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OpEntry pos = list.get(i); 31018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (pos.isRunning() != op.isRunning()) { 31118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (op.isRunning()) { 31227daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 31318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 31418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3150dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 31618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3170dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pos.getTime() < op.getTime()) { 31827daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 31918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 32018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 32118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 32227daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(op); 32327daaab633a80be50863e6539e947db674090662Dianne Hackborn } 32427daaab633a80be50863e6539e947db674090662Dianne Hackborn 3258b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public void addOp(AppOpsManager.OpEntry op) { 32627daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 32727daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(mOps, op); 3288b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn if (mApp.getOpSwitch(AppOpsManager.opToSwitch(op.getOp())) == null) { 3298b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn addOp(mSwitchOps, op); 33027daaab633a80be50863e6539e947db674090662Dianne Hackborn } 33118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 33318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry getAppEntry() { 33418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp; 33518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 337d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn public int getSwitchOrder() { 338d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn return mSwitchOrder; 339d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn } 340d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn 34118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.PackageOps getPackageOps() { 34218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mPkgOps; 34318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 34418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 34518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int getNumOpEntry() { 34618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.size(); 34718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 34818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 34918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.OpEntry getOpEntry(int pos) { 35018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(pos); 35118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 35218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3538b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn private CharSequence getCombinedText(ArrayList<AppOpsManager.OpEntry> ops, 3548b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn CharSequence[] items) { 35527daaab633a80be50863e6539e947db674090662Dianne Hackborn if (ops.size() == 1) { 3568b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return items[ops.get(0).getOp()]; 35718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 35818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn StringBuilder builder = new StringBuilder(); 35927daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<ops.size(); i++) { 36018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (i > 0) { 36118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn builder.append(", "); 36218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3638b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn builder.append(items[ops.get(i).getOp()]); 36418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 36518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return builder.toString(); 36618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 36718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 36818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3698b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getSummaryText(AppOpsState state) { 3708b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mOps, state.mOpSummaries); 37127daaab633a80be50863e6539e947db674090662Dianne Hackborn } 37227daaab633a80be50863e6539e947db674090662Dianne Hackborn 3738b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getSwitchText(AppOpsState state) { 3748b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn if (mSwitchOps.size() > 0) { 3758b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mSwitchOps, state.mOpLabels); 37627daaab633a80be50863e6539e947db674090662Dianne Hackborn } else { 3778b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mOps, state.mOpLabels); 37827daaab633a80be50863e6539e947db674090662Dianne Hackborn } 37927daaab633a80be50863e6539e947db674090662Dianne Hackborn } 38027daaab633a80be50863e6539e947db674090662Dianne Hackborn 3818b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getTimeText(Resources res, boolean showEmptyText) { 38218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (isRunning()) { 38318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return res.getText(R.string.app_ops_running); 38418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 38518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (getTime() > 0) { 38618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return DateUtils.getRelativeTimeSpanString(getTime(), 38718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn System.currentTimeMillis(), 38818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.MINUTE_IN_MILLIS, 38918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.FORMAT_ABBREV_RELATIVE); 39018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3918b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return showEmptyText ? res.getText(R.string.app_ops_never_used) : ""; 39218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 39318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 39418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public boolean isRunning() { 39518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).isRunning(); 39618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 39718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 39818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public long getTime() { 39918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).getTime(); 40018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 40118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 40218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 40318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp.getLabel(); 40418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 40518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 40618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 40718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 40818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Perform alphabetical comparison of application entry objects. 40918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 41018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final Comparator<AppOpEntry> APP_OP_COMPARATOR = new Comparator<AppOpEntry>() { 41118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final Collator sCollator = Collator.getInstance(); 41218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 41318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int compare(AppOpEntry object1, AppOpEntry object2) { 414d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn if (object1.getSwitchOrder() != object2.getSwitchOrder()) { 415d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn return object1.getSwitchOrder() < object2.getSwitchOrder() ? -1 : 1; 416d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn } 41718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.isRunning() != object2.isRunning()) { 41818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Currently running ops go first. 41918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.isRunning() ? -1 : 1; 42018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 42118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.getTime() != object2.getTime()) { 42218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // More recent times go first. 42318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.getTime() > object2.getTime() ? -1 : 1; 42418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 42518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return sCollator.compare(object1.getAppEntry().getLabel(), 42618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn object2.getAppEntry().getLabel()); 42718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 42818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn }; 42918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 43018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private void addOp(List<AppOpEntry> entries, AppOpsManager.PackageOps pkgOps, 431d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn AppEntry appEntry, AppOpsManager.OpEntry opEntry, boolean allowMerge, int switchOrder) { 43227daaab633a80be50863e6539e947db674090662Dianne Hackborn if (allowMerge && entries.size() > 0) { 43318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpEntry last = entries.get(entries.size()-1); 43418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (last.getAppEntry() == appEntry) { 43518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean lastExe = last.getTime() != 0; 43618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean entryExe = opEntry.getTime() != 0; 43718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (lastExe == entryExe) { 4380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 4390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": append to " + last); 4408b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn last.addOp(opEntry); 44118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 44218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 44318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 44418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 44527daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpEntry entry = appEntry.getOpSwitch(opEntry.getOp()); 44627daaab633a80be50863e6539e947db674090662Dianne Hackborn if (entry != null) { 4478b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn entry.addOp(opEntry); 44827daaab633a80be50863e6539e947db674090662Dianne Hackborn return; 44927daaab633a80be50863e6539e947db674090662Dianne Hackborn } 450d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn entry = new AppOpEntry(pkgOps, opEntry, appEntry, switchOrder); 4510dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 4520dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": making new " + entry); 45318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn entries.add(entry); 45418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 45618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl) { 45718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return buildState(tpl, 0, null); 45818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 4600dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private AppEntry getAppEntry(final Context context, final HashMap<String, AppEntry> appEntries, 4610dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final String packageName, ApplicationInfo appInfo) { 4620dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = appEntries.get(packageName); 4630dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 4640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appInfo == null) { 4650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 4660dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo = mPm.getApplicationInfo(packageName, 4670dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageManager.GET_DISABLED_COMPONENTS 4680dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn | PackageManager.GET_UNINSTALLED_PACKAGES); 4690dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (PackageManager.NameNotFoundException e) { 4700dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Log.w(TAG, "Unable to find info for package " + packageName); 4710dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return null; 4720dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4730dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4740dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry = new AppEntry(this, appInfo); 4750dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry.loadLabel(context); 4760dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntries.put(packageName, appEntry); 4770dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4780dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return appEntry; 4790dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4800dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 48118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName) { 48218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final Context context = mContext; 48318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 48418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final HashMap<String, AppEntry> appEntries = new HashMap<String, AppEntry>(); 48527daaab633a80be50863e6539e947db674090662Dianne Hackborn final List<AppOpEntry> entries = new ArrayList<AppOpEntry>(); 4860dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 48727daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<String> perms = new ArrayList<String>(); 48827daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<Integer> permOps = new ArrayList<Integer>(); 489d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn final int[] opToOrder = new int[AppOpsManager._NUM_OP]; 4900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<tpl.ops.length; i++) { 49127daaab633a80be50863e6539e947db674090662Dianne Hackborn if (tpl.showPerms[i]) { 49227daaab633a80be50863e6539e947db674090662Dianne Hackborn String perm = AppOpsManager.opToPermission(tpl.ops[i]); 49327daaab633a80be50863e6539e947db674090662Dianne Hackborn if (perm != null && !perms.contains(perm)) { 49427daaab633a80be50863e6539e947db674090662Dianne Hackborn perms.add(perm); 49527daaab633a80be50863e6539e947db674090662Dianne Hackborn permOps.add(tpl.ops[i]); 496d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn opToOrder[tpl.ops[i]] = i; 49727daaab633a80be50863e6539e947db674090662Dianne Hackborn } 4980dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 50018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 50118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn List<AppOpsManager.PackageOps> pkgs; 50218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (packageName != null) { 50318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getOpsForPackage(uid, packageName, tpl.ops); 50418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 50518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getPackagesForOps(tpl.ops); 50618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5070dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 5080dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pkgs != null) { 5090dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<pkgs.size(); i++) { 5100dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = pkgs.get(i); 5110dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null); 5120dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 5130dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 5140dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5150dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int j=0; j<pkgOps.getOps().size(); j++) { 5160dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OpEntry opEntry = pkgOps.getOps().get(j); 517d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, packageName == null, 518d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn packageName == null ? 0 : opToOrder[opEntry.getOp()]); 51918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 52018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 52118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 52218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5230dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<PackageInfo> apps; 5240dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (packageName != null) { 5250dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = new ArrayList<PackageInfo>(); 5260dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 5270dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo pi = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 5280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps.add(pi); 5290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (NameNotFoundException e) { 53018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5310dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } else { 5320dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String[] permsArray = new String[perms.size()]; 5330dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn perms.toArray(permsArray); 5340dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = mPm.getPackagesHoldingPermissions(permsArray, 0); 5350dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5360dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<apps.size(); i++) { 5370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo appInfo = apps.get(i); 5380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, appInfo.packageName, 5390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo.applicationInfo); 5400dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 5410dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 5420dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5430dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<AppOpsManager.OpEntry> dummyOps = null; 5440dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = null; 5457d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissions != null) { 5467d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int j=0; j<appInfo.requestedPermissions.length; j++) { 5477d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissionsFlags != null) { 5487d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if ((appInfo.requestedPermissionsFlags[j] 5497d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) { 5507d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " 5517d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j] + " not granted; skipping"); 5527d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler break; 5537d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 55418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5557d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + ": requested perm " 5567d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j]); 5577d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int k=0; k<perms.size(); k++) { 5587d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (!perms.get(k).equals(appInfo.requestedPermissions[j])) { 5597d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 5607d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5617d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " + perms.get(k) 5627d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + " has op " + permOps.get(k) + ": " + appEntry.hasOp(permOps.get(k))); 5637d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appEntry.hasOp(permOps.get(k))) { 5647d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 5657d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5667d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (dummyOps == null) { 5677d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps = new ArrayList<AppOpsManager.OpEntry>(); 5687d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler pkgOps = new AppOpsManager.PackageOps( 5697d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler appInfo.packageName, appInfo.applicationInfo.uid, dummyOps); 5707d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler 5717d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5727d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler AppOpsManager.OpEntry opEntry = new AppOpsManager.OpEntry( 5737d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0); 5747d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps.add(opEntry); 575d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, packageName == null, 576d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn packageName == null ? 0 : opToOrder[opEntry.getOp()]); 5770dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5780dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 57918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 58018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 58118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 58218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Sort the list. 58318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn Collections.sort(entries, APP_OP_COMPARATOR); 58418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 58518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Done! 58618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return entries; 58718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 58818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn} 589