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, 10415ab7758df616a27c28276ab97ddb2e2de6089f7Dianne Hackborn AppOpsManager.OP_NEIGHBORING_CELLS, 1054a06e4cc4370f5897f07f6314f25b37db759cf18David Christie AppOpsManager.OP_MONITOR_LOCATION, 106bdf28e40251772a35f776af9fd1a4b903f0f9771Michael Wright AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION }, 10727daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 10827daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 10927daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 11015ab7758df616a27c28276ab97ddb2e2de6089f7Dianne Hackborn false, 11127daaab633a80be50863e6539e947db674090662Dianne Hackborn false, 1124a06e4cc4370f5897f07f6314f25b37db759cf18David Christie false, 113bdf28e40251772a35f776af9fd1a4b903f0f9771Michael Wright false } 11418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 11518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 11618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final OpsTemplate PERSONAL_TEMPLATE = new OpsTemplate( 11718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn new int[] { AppOpsManager.OP_READ_CONTACTS, 11818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_WRITE_CONTACTS, 11918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpsManager.OP_READ_CALL_LOG, 1200dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_WRITE_CALL_LOG, 1210dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OP_READ_CALENDAR, 122782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_WRITE_CALENDAR, 123782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_READ_CLIPBOARD, 124782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn AppOpsManager.OP_WRITE_CLIPBOARD }, 12527daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { true, 12627daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12727daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12827daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 12927daaab633a80be50863e6539e947db674090662Dianne Hackborn true, 130782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn true, 131782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn false, 132782c3de338d6b4ac8280e0686b8a4b39c0e3f70fDianne Hackborn false } 13318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 13418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 135983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn public static final OpsTemplate MESSAGING_TEMPLATE = new OpsTemplate( 136983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn new int[] { AppOpsManager.OP_READ_SMS, 137983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_SMS, 138983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_EMERGECY_SMS, 139983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_MMS, 140983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_RECEIVE_WAP_PUSH, 141983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_WRITE_SMS, 142983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_SEND_SMS, 143983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_READ_ICC_SMS, 144983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn AppOpsManager.OP_WRITE_ICC_SMS }, 145983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn new boolean[] { true, 146983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 147983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 148983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 149983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 150983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 151983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 152983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true, 153983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn true } 154983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn ); 155983378738761150d8ba649b4b1d74635881e61ecDianne Hackborn 1566e91babedac9983b10fdf2650de86386800017beDianne Hackborn public static final OpsTemplate MEDIA_TEMPLATE = new OpsTemplate( 157df3f6d6c4722a7acc8189e47d0499aaf618969f9Daniel Sandler new int[] { AppOpsManager.OP_VIBRATE, 1587ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn AppOpsManager.OP_CAMERA, 1597ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn AppOpsManager.OP_RECORD_AUDIO, 1606e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_PLAY_AUDIO, 1616e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_TAKE_MEDIA_BUTTONS, 1626e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_TAKE_AUDIO_FOCUS, 1636e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_MASTER_VOLUME, 1646e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_VOICE_VOLUME, 1656e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_RING_VOLUME, 1666e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_MEDIA_VOLUME, 1676e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_ALARM_VOLUME, 1686e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, 1694241d0b8db1c4352956ce877272a9ebe1770ad01Emily Bernier AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, 1704241d0b8db1c4352956ce877272a9ebe1770ad01Emily Bernier AppOpsManager.OP_MUTE_MICROPHONE}, 17127daaab633a80be50863e6539e947db674090662Dianne Hackborn new boolean[] { false, 172d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn true, 1737ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 1746e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1756e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1766e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1776e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1786e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1796e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1806e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1816e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1826e91babedac9983b10fdf2650de86386800017beDianne Hackborn false, 1836e91babedac9983b10fdf2650de86386800017beDianne Hackborn false } 1846e91babedac9983b10fdf2650de86386800017beDianne Hackborn ); 1856e91babedac9983b10fdf2650de86386800017beDianne Hackborn 1866e91babedac9983b10fdf2650de86386800017beDianne Hackborn public static final OpsTemplate DEVICE_TEMPLATE = new OpsTemplate( 1876e91babedac9983b10fdf2650de86386800017beDianne Hackborn new int[] { AppOpsManager.OP_POST_NOTIFICATION, 1886e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_ACCESS_NOTIFICATIONS, 1896e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_CALL_PHONE, 1906e91babedac9983b10fdf2650de86386800017beDianne Hackborn AppOpsManager.OP_WRITE_SETTINGS, 191ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 192bdf28e40251772a35f776af9fd1a4b903f0f9771Michael Wright AppOpsManager.OP_WAKE_LOCK, 19390b3b211efda80535ac2981032f66e117ffeb221Jeff Davidson AppOpsManager.OP_PROJECT_MEDIA, 1947781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn AppOpsManager.OP_ACTIVATE_VPN, 1957781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn AppOpsManager.OP_ASSIST_STRUCTURE, 1967781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn AppOpsManager.OP_ASSIST_SCREENSHOT}, 1976e91babedac9983b10fdf2650de86386800017beDianne Hackborn new boolean[] { false, 1987ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 1997ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 2007ff56d331e1dfe133e734a36d191fc1d81b31e95Dianne Hackborn true, 201ec74da60cda5d0d7d1901e20a5a7806ef4cf387fDianne Hackborn true, 202bdf28e40251772a35f776af9fd1a4b903f0f9771Michael Wright true, 20390b3b211efda80535ac2981032f66e117ffeb221Jeff Davidson false, 2047781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn false, 2057781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn false, 2067781ef68703995c6724eb618c8c0c3eb10cb2a73Dianne Hackborn false } 20718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn ); 20818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 2090dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public static final OpsTemplate[] ALL_TEMPLATES = new OpsTemplate[] { 2106e91babedac9983b10fdf2650de86386800017beDianne Hackborn LOCATION_TEMPLATE, PERSONAL_TEMPLATE, MESSAGING_TEMPLATE, 2116e91babedac9983b10fdf2650de86386800017beDianne Hackborn MEDIA_TEMPLATE, DEVICE_TEMPLATE 2120dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn }; 2130dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 21418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 21518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 21618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 21718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppEntry { 21818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsState mState; 21918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ApplicationInfo mInfo; 22018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final File mApkFile; 2210dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private final SparseArray<AppOpsManager.OpEntry> mOps 2220dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn = new SparseArray<AppOpsManager.OpEntry>(); 22327daaab633a80be50863e6539e947db674090662Dianne Hackborn private final SparseArray<AppOpEntry> mOpSwitches 22427daaab633a80be50863e6539e947db674090662Dianne Hackborn = new SparseArray<AppOpEntry>(); 22518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private String mLabel; 22618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private Drawable mIcon; 22718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private boolean mMounted; 22818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 22918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry(AppOpsState state, ApplicationInfo info) { 23018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mState = state; 23118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mInfo = info; 23218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApkFile = new File(info.sourceDir); 23318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 23418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 23527daaab633a80be50863e6539e947db674090662Dianne Hackborn public void addOp(AppOpEntry entry, AppOpsManager.OpEntry op) { 2360dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.put(op.getOp(), op); 23727daaab633a80be50863e6539e947db674090662Dianne Hackborn mOpSwitches.put(AppOpsManager.opToSwitch(op.getOp()), entry); 2380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 2390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 2400dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn public boolean hasOp(int op) { 2410dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return mOps.indexOfKey(op) >= 0; 2420dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 2430dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 24427daaab633a80be50863e6539e947db674090662Dianne Hackborn public AppOpEntry getOpSwitch(int op) { 24527daaab633a80be50863e6539e947db674090662Dianne Hackborn return mOpSwitches.get(AppOpsManager.opToSwitch(op)); 24627daaab633a80be50863e6539e947db674090662Dianne Hackborn } 24727daaab633a80be50863e6539e947db674090662Dianne Hackborn 24818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public ApplicationInfo getApplicationInfo() { 24918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mInfo; 25018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 25218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public String getLabel() { 25318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 25418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 25518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 25618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public Drawable getIcon() { 25718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mIcon == null) { 25818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 25918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 26018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 26118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 26218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 26318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 26418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else if (!mMounted) { 26518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // If the app wasn't mounted but is now mounted, reload 26618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // its icon. 26718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mApkFile.exists()) { 26818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 26918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mIcon = mInfo.loadIcon(mState.mPm); 27018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 27118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 27318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mIcon; 27418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 2760ba89bd54c4b44b3803342da10b0c08b0bf76ad4Alan Viverette return mState.mContext.getDrawable( 27718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn android.R.drawable.sym_def_app_icon); 27818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 27918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 28018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 28118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mLabel; 28218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 28318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 28418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn void loadLabel(Context context) { 28518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (mLabel == null || !mMounted) { 28618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (!mApkFile.exists()) { 28718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = false; 28818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = mInfo.packageName; 28918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 29018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mMounted = true; 29118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn CharSequence label = mInfo.loadLabel(context.getPackageManager()); 29218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mLabel = label != null ? label.toString() : mInfo.packageName; 29318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 29718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 29818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 29918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * This class holds the per-item data in our Loader. 30018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 30118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static class AppOpEntry { 30218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppOpsManager.PackageOps mPkgOps; 30318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mOps 30418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 3058b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn private final ArrayList<AppOpsManager.OpEntry> mSwitchOps 30627daaab633a80be50863e6539e947db674090662Dianne Hackborn = new ArrayList<AppOpsManager.OpEntry>(); 30718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final AppEntry mApp; 308d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn private final int mSwitchOrder; 30918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 310d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn public AppOpEntry(AppOpsManager.PackageOps pkg, AppOpsManager.OpEntry op, AppEntry app, 311d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn int switchOrder) { 31218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mPkgOps = pkg; 31318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn mApp = app; 314d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn mSwitchOrder = switchOrder; 31527daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 3160dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn mOps.add(op); 3178b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn mSwitchOps.add(op); 31818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 31918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 32027daaab633a80be50863e6539e947db674090662Dianne Hackborn private static void addOp(ArrayList<AppOpsManager.OpEntry> list, AppOpsManager.OpEntry op) { 32127daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<list.size(); i++) { 32227daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpsManager.OpEntry pos = list.get(i); 32318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (pos.isRunning() != op.isRunning()) { 32418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (op.isRunning()) { 32527daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 32618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 32718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 32918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3300dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pos.getTime() < op.getTime()) { 33127daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(i, op); 33218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 33318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 33527daaab633a80be50863e6539e947db674090662Dianne Hackborn list.add(op); 33627daaab633a80be50863e6539e947db674090662Dianne Hackborn } 33727daaab633a80be50863e6539e947db674090662Dianne Hackborn 3388b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public void addOp(AppOpsManager.OpEntry op) { 33927daaab633a80be50863e6539e947db674090662Dianne Hackborn mApp.addOp(this, op); 34027daaab633a80be50863e6539e947db674090662Dianne Hackborn addOp(mOps, op); 3418b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn if (mApp.getOpSwitch(AppOpsManager.opToSwitch(op.getOp())) == null) { 3428b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn addOp(mSwitchOps, op); 34327daaab633a80be50863e6539e947db674090662Dianne Hackborn } 34418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 34518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 34618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppEntry getAppEntry() { 34718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp; 34818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 34918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 350d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn public int getSwitchOrder() { 351d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn return mSwitchOrder; 352d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn } 353d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn 35418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.PackageOps getPackageOps() { 35518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mPkgOps; 35618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 35718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 35818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int getNumOpEntry() { 35918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.size(); 36018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 36118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 36218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public AppOpsManager.OpEntry getOpEntry(int pos) { 36318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(pos); 36418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 36518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3668b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn private CharSequence getCombinedText(ArrayList<AppOpsManager.OpEntry> ops, 3678b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn CharSequence[] items) { 36827daaab633a80be50863e6539e947db674090662Dianne Hackborn if (ops.size() == 1) { 3698b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return items[ops.get(0).getOp()]; 37018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 37118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn StringBuilder builder = new StringBuilder(); 37227daaab633a80be50863e6539e947db674090662Dianne Hackborn for (int i=0; i<ops.size(); i++) { 37318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (i > 0) { 37418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn builder.append(", "); 37518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 3768b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn builder.append(items[ops.get(i).getOp()]); 37718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 37818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return builder.toString(); 37918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 38018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 38118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 3828b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getSummaryText(AppOpsState state) { 3838b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mOps, state.mOpSummaries); 38427daaab633a80be50863e6539e947db674090662Dianne Hackborn } 38527daaab633a80be50863e6539e947db674090662Dianne Hackborn 3868b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getSwitchText(AppOpsState state) { 3878b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn if (mSwitchOps.size() > 0) { 3888b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mSwitchOps, state.mOpLabels); 38927daaab633a80be50863e6539e947db674090662Dianne Hackborn } else { 3908b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return getCombinedText(mOps, state.mOpLabels); 39127daaab633a80be50863e6539e947db674090662Dianne Hackborn } 39227daaab633a80be50863e6539e947db674090662Dianne Hackborn } 39327daaab633a80be50863e6539e947db674090662Dianne Hackborn 3948b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn public CharSequence getTimeText(Resources res, boolean showEmptyText) { 39518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (isRunning()) { 39618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return res.getText(R.string.app_ops_running); 39718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 39818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (getTime() > 0) { 39918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return DateUtils.getRelativeTimeSpanString(getTime(), 40018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn System.currentTimeMillis(), 40118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.MINUTE_IN_MILLIS, 40218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn DateUtils.FORMAT_ABBREV_RELATIVE); 40318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 4048b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn return showEmptyText ? res.getText(R.string.app_ops_never_used) : ""; 40518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 40618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 40718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public boolean isRunning() { 40818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).isRunning(); 40918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 41018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 41118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public long getTime() { 41218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mOps.get(0).getTime(); 41318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 41418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 41518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override public String toString() { 41618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return mApp.getLabel(); 41718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 41818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 41918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 42018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn /** 42118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn * Perform alphabetical comparison of application entry objects. 42218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn */ 42318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public static final Comparator<AppOpEntry> APP_OP_COMPARATOR = new Comparator<AppOpEntry>() { 42418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private final Collator sCollator = Collator.getInstance(); 42518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn @Override 42618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public int compare(AppOpEntry object1, AppOpEntry object2) { 427d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn if (object1.getSwitchOrder() != object2.getSwitchOrder()) { 428d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn return object1.getSwitchOrder() < object2.getSwitchOrder() ? -1 : 1; 429d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn } 43018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.isRunning() != object2.isRunning()) { 43118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Currently running ops go first. 43218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.isRunning() ? -1 : 1; 43318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 43418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (object1.getTime() != object2.getTime()) { 43518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // More recent times go first. 43618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return object1.getTime() > object2.getTime() ? -1 : 1; 43718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 43818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return sCollator.compare(object1.getAppEntry().getLabel(), 43918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn object2.getAppEntry().getLabel()); 44018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 44118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn }; 44218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 44318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn private void addOp(List<AppOpEntry> entries, AppOpsManager.PackageOps pkgOps, 444d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn AppEntry appEntry, AppOpsManager.OpEntry opEntry, boolean allowMerge, int switchOrder) { 44527daaab633a80be50863e6539e947db674090662Dianne Hackborn if (allowMerge && entries.size() > 0) { 44618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn AppOpEntry last = entries.get(entries.size()-1); 44718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (last.getAppEntry() == appEntry) { 44818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean lastExe = last.getTime() != 0; 44918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn boolean entryExe = opEntry.getTime() != 0; 45018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (lastExe == entryExe) { 4510dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 4520dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": append to " + last); 4538b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn last.addOp(opEntry); 45418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return; 45518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 45827daaab633a80be50863e6539e947db674090662Dianne Hackborn AppOpEntry entry = appEntry.getOpSwitch(opEntry.getOp()); 45927daaab633a80be50863e6539e947db674090662Dianne Hackborn if (entry != null) { 4608b0afc7fb53b90e522b86ba04bb17c0cba2364abDianne Hackborn entry.addOp(opEntry); 46127daaab633a80be50863e6539e947db674090662Dianne Hackborn return; 46227daaab633a80be50863e6539e947db674090662Dianne Hackborn } 463d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn entry = new AppOpEntry(pkgOps, opEntry, appEntry, switchOrder); 4640dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (DEBUG) Log.d(TAG, "Add op " + opEntry.getOp() + " to package " 4650dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn + pkgOps.getPackageName() + ": making new " + entry); 46618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn entries.add(entry); 46718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 46818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 46918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl) { 47018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return buildState(tpl, 0, null); 47118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 47218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 4730dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn private AppEntry getAppEntry(final Context context, final HashMap<String, AppEntry> appEntries, 4740dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn final String packageName, ApplicationInfo appInfo) { 4750dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = appEntries.get(packageName); 4760dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 4770dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appInfo == null) { 4780dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 4790dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo = mPm.getApplicationInfo(packageName, 4800dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageManager.GET_DISABLED_COMPONENTS 4810dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn | PackageManager.GET_UNINSTALLED_PACKAGES); 4820dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (PackageManager.NameNotFoundException e) { 4830dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn Log.w(TAG, "Unable to find info for package " + packageName); 4840dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return null; 4850dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4860dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4870dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry = new AppEntry(this, appInfo); 4880dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntry.loadLabel(context); 4890dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appEntries.put(packageName, appEntry); 4900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4910dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn return appEntry; 4920dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 4930dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 49418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn public List<AppOpEntry> buildState(OpsTemplate tpl, int uid, String packageName) { 49518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final Context context = mContext; 49618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 49718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn final HashMap<String, AppEntry> appEntries = new HashMap<String, AppEntry>(); 49827daaab633a80be50863e6539e947db674090662Dianne Hackborn final List<AppOpEntry> entries = new ArrayList<AppOpEntry>(); 4990dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 50027daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<String> perms = new ArrayList<String>(); 50127daaab633a80be50863e6539e947db674090662Dianne Hackborn final ArrayList<Integer> permOps = new ArrayList<Integer>(); 502d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn final int[] opToOrder = new int[AppOpsManager._NUM_OP]; 5030dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<tpl.ops.length; i++) { 50427daaab633a80be50863e6539e947db674090662Dianne Hackborn if (tpl.showPerms[i]) { 50527daaab633a80be50863e6539e947db674090662Dianne Hackborn String perm = AppOpsManager.opToPermission(tpl.ops[i]); 50627daaab633a80be50863e6539e947db674090662Dianne Hackborn if (perm != null && !perms.contains(perm)) { 50727daaab633a80be50863e6539e947db674090662Dianne Hackborn perms.add(perm); 50827daaab633a80be50863e6539e947db674090662Dianne Hackborn permOps.add(tpl.ops[i]); 509d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn opToOrder[tpl.ops[i]] = i; 51027daaab633a80be50863e6539e947db674090662Dianne Hackborn } 5110dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5120dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 51318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 51418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn List<AppOpsManager.PackageOps> pkgs; 51518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn if (packageName != null) { 51618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getOpsForPackage(uid, packageName, tpl.ops); 51718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } else { 51818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn pkgs = mAppOps.getPackagesForOps(tpl.ops); 51918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5200dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn 5210dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (pkgs != null) { 5220dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<pkgs.size(); i++) { 5230dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = pkgs.get(i); 5240dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, pkgOps.getPackageName(), null); 5250dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 5260dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 5270dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5280dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int j=0; j<pkgOps.getOps().size(); j++) { 5290dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.OpEntry opEntry = pkgOps.getOps().get(j); 530d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, packageName == null, 531d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn packageName == null ? 0 : opToOrder[opEntry.getOp()]); 53218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 53318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 53418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 53518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 5360dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<PackageInfo> apps; 5370dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (packageName != null) { 5380dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = new ArrayList<PackageInfo>(); 5390dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn try { 5400dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo pi = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 5410dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps.add(pi); 5420dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } catch (NameNotFoundException e) { 54318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5440dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } else { 5450dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn String[] permsArray = new String[perms.size()]; 5460dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn perms.toArray(permsArray); 5470dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn apps = mPm.getPackagesHoldingPermissions(permsArray, 0); 5480dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5490dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn for (int i=0; i<apps.size(); i++) { 5500dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn PackageInfo appInfo = apps.get(i); 5510dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppEntry appEntry = getAppEntry(context, appEntries, appInfo.packageName, 5520dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn appInfo.applicationInfo); 5530dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn if (appEntry == null) { 5540dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn continue; 5550dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5560dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn List<AppOpsManager.OpEntry> dummyOps = null; 5570dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn AppOpsManager.PackageOps pkgOps = null; 5587d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissions != null) { 5597d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int j=0; j<appInfo.requestedPermissions.length; j++) { 5607d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appInfo.requestedPermissionsFlags != null) { 5617d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if ((appInfo.requestedPermissionsFlags[j] 5627d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) { 5637d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " 5647d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j] + " not granted; skipping"); 56567e72d9e8a2146ede95c06cac60c2100ad59a33bDanny Baumann continue; 5667d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 56718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 5687d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + ": requested perm " 5697d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + appInfo.requestedPermissions[j]); 5707d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler for (int k=0; k<perms.size(); k++) { 5717d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (!perms.get(k).equals(appInfo.requestedPermissions[j])) { 5727d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 5737d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5747d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (DEBUG) Log.d(TAG, "Pkg " + appInfo.packageName + " perm " + perms.get(k) 5757d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler + " has op " + permOps.get(k) + ": " + appEntry.hasOp(permOps.get(k))); 5767d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (appEntry.hasOp(permOps.get(k))) { 5777d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler continue; 5787d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5797d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler if (dummyOps == null) { 5807d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps = new ArrayList<AppOpsManager.OpEntry>(); 5817d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler pkgOps = new AppOpsManager.PackageOps( 5827d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler appInfo.packageName, appInfo.applicationInfo.uid, dummyOps); 5837d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler 5847d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler } 5857d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler AppOpsManager.OpEntry opEntry = new AppOpsManager.OpEntry( 5865b45c3cb2fdd9299a3fa632047f3da1bec4e868aSvetoslav permOps.get(k), AppOpsManager.MODE_ALLOWED, 0, 0, 0, -1, null); 5877d3a4c160cac37b72aa9149952358df4a3912cfbDaniel Sandler dummyOps.add(opEntry); 588d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn addOp(entries, pkgOps, appEntry, opEntry, packageName == null, 589d69e8dc44173c33c5425158c027bfe44ddcacf85Dianne Hackborn packageName == null ? 0 : opToOrder[opEntry.getOp()]); 5900dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 5910dd9902c89e7b705fd73158aadf1bf27843ad201Dianne Hackborn } 59218b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 59318b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 59418b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 59518b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Sort the list. 59618b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn Collections.sort(entries, APP_OP_COMPARATOR); 59718b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn 59818b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn // Done! 59918b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn return entries; 60018b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn } 60118b64f446cd7b9043909b0cd42d1ab364392da24Dianne Hackborn} 602