1a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn/* 2a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project 3a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 4a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * you may not use this file except in compliance with the License. 6a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * You may obtain a copy of the License at 7a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 8a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 10a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * See the License for the specific language governing permissions and 14a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * limitations under the License. 15a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn */ 16a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 17a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpackage com.android.server; 18a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 199cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganovimport android.Manifest; 207b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackbornimport android.app.ActivityManager; 211c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monkimport android.app.ActivityThread; 222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganovimport android.app.AppGlobals; 23a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.app.AppOpsManager; 24d52544183e2532f22cee33df582bc7bece400837Dianne Hackbornimport android.app.AppOpsManagerInternal; 2565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackbornimport android.content.ContentResolver; 26a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.Context; 271c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monkimport android.content.pm.ApplicationInfo; 281c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monkimport android.content.pm.IPackageManager; 29a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager; 30aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shuklaimport android.content.pm.PackageManagerInternal; 31e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport android.content.pm.UserInfo; 3265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackbornimport android.database.ContentObserver; 337b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlockimport android.media.AudioAttributes; 3465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackbornimport android.net.Uri; 3535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.AsyncTask; 36a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Binder; 3762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monkimport android.os.Bundle; 3835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.Handler; 39c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.IBinder; 40a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Process; 41c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.RemoteException; 42268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackbornimport android.os.ResultReceiver; 43a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.ServiceManager; 44354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornimport android.os.ShellCallback; 45268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackbornimport android.os.ShellCommand; 46cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport android.os.SystemClock; 47a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.UserHandle; 48e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport android.os.UserManager; 492250d56a0b47b93016018340c8f4040325aa5611Sudheer Shankaimport android.os.storage.StorageManagerInternal; 5065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackbornimport android.provider.Settings; 51e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackbornimport android.util.ArrayMap; 521af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.util.ArraySet; 53a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.AtomicFile; 5465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackbornimport android.util.KeyValueListParser; 55a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.Slog; 56a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.SparseArray; 572378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackbornimport android.util.SparseBooleanArray; 582af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganovimport android.util.SparseIntArray; 59a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.TimeUtils; 6035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.util.Xml; 61a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 623ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklaimport com.android.internal.annotations.VisibleForTesting; 632d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganovimport com.android.internal.app.IAppOpsActiveCallback; 64c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport com.android.internal.app.IAppOpsCallback; 65e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport com.android.internal.app.IAppOpsService; 666ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganovimport com.android.internal.os.Zygote; 672af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganovimport com.android.internal.util.ArrayUtils; 68fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport com.android.internal.util.DumpUtils; 6935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 709cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganovimport com.android.internal.util.Preconditions; 7135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.XmlUtils; 722d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganovimport com.android.internal.util.function.pooled.PooledLambda; 736cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds 742af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganovimport libcore.util.EmptyArray; 75e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 7635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 7735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 7835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 79a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 80e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.File; 81e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.FileDescriptor; 82e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.FileInputStream; 83e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.FileNotFoundException; 84e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.FileOutputStream; 85e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.IOException; 86e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.io.PrintWriter; 87e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.nio.charset.StandardCharsets; 88cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport java.text.SimpleDateFormat; 89e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.ArrayList; 90e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.Arrays; 91e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.Collections; 92cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport java.util.Date; 93e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.HashMap; 94e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.Iterator; 95e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.List; 96e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmannimport java.util.Map; 97e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 98e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackbornimport static android.app.AppOpsManager._NUM_UID_STATE; 99cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_BACKGROUND; 100cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_CACHED; 101cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_FOREGROUND; 102cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; 103e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED; 104cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_PERSISTENT; 105cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackbornimport static android.app.AppOpsManager.UID_STATE_TOP; 106cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 107a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpublic class AppOpsService extends IAppOpsService.Stub { 108a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn static final String TAG = "AppOps"; 10935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final boolean DEBUG = false; 11035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 1113ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla private static final int NO_VERSION = -1; 1123ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla /** Increment by one every time and add the corresponding upgrade logic in 1133ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * {@link #upgradeLocked(int)} below. The first version was 1 */ 1143ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla private static final int CURRENT_VERSION = 1; 1153ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 11635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn // Write at most every 30 minutes. 11735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000; 118a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1193a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov // Constant meaning that any UID should be matched when dispatching callbacks 1203a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov private static final int UID_ANY = -2; 1213a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov 122cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn // Map from process states to the uid states we track. 123cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn private static final int[] PROCESS_STATE_TO_UID_STATE = new int[] { 124cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT 125cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI 126cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_TOP, // ActivityManager.PROCESS_STATE_TOP 127cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_FOREGROUND_SERVICE, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 128cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE 129cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND 130cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 131cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND 132cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_BACKUP 133cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_SERVICE 134cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_RECEIVER 135cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_TOP_SLEEPING 136cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT 137cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_HOME 138cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY 139cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY 140cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT 141cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT 142cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY 143cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_NONEXISTENT 144cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn }; 145cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 146cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn static final String[] UID_STATE_NAMES = new String[] { 147cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "pers ", // UID_STATE_PERSISTENT 148cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "top ", // UID_STATE_TOP 149cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "fgsvc", // UID_STATE_FOREGROUND_SERVICE 150cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "fg ", // UID_STATE_FOREGROUND 151cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "bg ", // UID_STATE_BACKGROUND 152cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "cch ", // UID_STATE_CACHED 153cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn }; 154cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 155cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn static final String[] UID_STATE_TIME_ATTRS = new String[] { 156cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tp", // UID_STATE_PERSISTENT 157cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tt", // UID_STATE_TOP 158cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tfs", // UID_STATE_FOREGROUND_SERVICE 159cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tf", // UID_STATE_FOREGROUND 160cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tb", // UID_STATE_BACKGROUND 161cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "tc", // UID_STATE_CACHED 162cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn }; 163cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 164cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn static final String[] UID_STATE_REJECT_ATTRS = new String[] { 165cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rp", // UID_STATE_PERSISTENT 166cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rt", // UID_STATE_TOP 167cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rfs", // UID_STATE_FOREGROUND_SERVICE 168cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rf", // UID_STATE_FOREGROUND 169cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rb", // UID_STATE_BACKGROUND 170cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn "rc", // UID_STATE_CACHED 171cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn }; 172cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 173a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Context mContext; 174a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final AtomicFile mFile; 17535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Handler mHandler; 17635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 177d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn private final AppOpsManagerInternalImpl mAppOpsManagerInternal 178d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn = new AppOpsManagerInternalImpl(); 179d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn 18035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean mWriteScheduled; 1817b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn boolean mFastWriteScheduled; 18235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Runnable mWriteRunner = new Runnable() { 18335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public void run() { 18435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (AppOpsService.this) { 18535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 1867b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn mFastWriteScheduled = false; 18735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 18835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn @Override protected Void doInBackground(Void... params) { 18935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 19035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 19135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 19235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 19335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); 19435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 19535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 19635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 197a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1983ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @VisibleForTesting 1993ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla final SparseArray<UidState> mUidStates = new SparseArray<>(); 200a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 2012378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn long mLastUptime; 2022378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 20329931bc684bde6b430923122777684178ee2681cRuben Brunk /* 20429931bc684bde6b430923122777684178ee2681cRuben Brunk * These are app op restrictions imposed per user from various parties. 20529931bc684bde6b430923122777684178ee2681cRuben Brunk */ 206a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov private final ArrayMap<IBinder, ClientRestrictionState> mOpUserRestrictions = new ArrayMap<>(); 20762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 208d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn SparseIntArray mProfileOwners; 209d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn 21065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn /** 21165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn * All times are in milliseconds. These constants are kept synchronized with the system 21265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn * global Settings. Any access to this class or its fields should be done while 21365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn * holding the AppOpsService lock. 21465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn */ 21565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private final class Constants extends ContentObserver { 21665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn // Key names stored in the settings value. 217e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn private static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time"; 218e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn private static final String KEY_FG_SERVICE_STATE_SETTLE_TIME 219e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn = "fg_service_state_settle_time"; 220e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn private static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time"; 221e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn 222e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn /** 223e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * How long we want for a drop in uid state from top to settle before applying it. 224e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * @see Settings.Global#APP_OPS_CONSTANTS 225e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * @see #KEY_TOP_STATE_SETTLE_TIME 226e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn */ 227e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn public long TOP_STATE_SETTLE_TIME; 22865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 22965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn /** 230e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * How long we want for a drop in uid state from foreground to settle before applying it. 23165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn * @see Settings.Global#APP_OPS_CONSTANTS 232e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * @see #KEY_FG_SERVICE_STATE_SETTLE_TIME 23365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn */ 234e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn public long FG_SERVICE_STATE_SETTLE_TIME; 23565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 236e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn /** 237e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * How long we want for a drop in uid state from background to settle before applying it. 238e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * @see Settings.Global#APP_OPS_CONSTANTS 239e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn * @see #KEY_BG_STATE_SETTLE_TIME 240e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn */ 241e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn public long BG_STATE_SETTLE_TIME; 24265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 24365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private final KeyValueListParser mParser = new KeyValueListParser(','); 24465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private ContentResolver mResolver; 24565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 24665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public Constants(Handler handler) { 24765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn super(handler); 24865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn updateConstants(); 24965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 25065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 25165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public void startMonitoring(ContentResolver resolver) { 25265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mResolver = resolver; 25365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mResolver.registerContentObserver( 25445c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn Settings.Global.getUriFor(Settings.Global.APP_OPS_CONSTANTS), 25565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn false, this); 25665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn updateConstants(); 25765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 25865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 25965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn @Override 26065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public void onChange(boolean selfChange, Uri uri) { 26165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn updateConstants(); 26265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 26365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 26465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private void updateConstants() { 26545c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn String value = mResolver != null ? Settings.Global.getString(mResolver, 26645c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn Settings.Global.APP_OPS_CONSTANTS) : ""; 26745c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn 26865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn synchronized (AppOpsService.this) { 26965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn try { 27045c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn mParser.setString(value); 27165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } catch (IllegalArgumentException e) { 27265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn // Failed to parse the settings string, log this and move on 27365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn // with defaults. 27465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn Slog.e(TAG, "Bad app ops settings", e); 27565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 276e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn TOP_STATE_SETTLE_TIME = mParser.getDurationMillis( 277e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn KEY_TOP_STATE_SETTLE_TIME, 30 * 1000L); 278e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn FG_SERVICE_STATE_SETTLE_TIME = mParser.getDurationMillis( 279e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn KEY_FG_SERVICE_STATE_SETTLE_TIME, 10 * 1000L); 280e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn BG_STATE_SETTLE_TIME = mParser.getDurationMillis( 281e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn KEY_BG_STATE_SETTLE_TIME, 1 * 1000L); 28265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 28365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 28465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 28565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn void dump(PrintWriter pw) { 28665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" Settings:"); 28765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 288e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn pw.print(" "); pw.print(KEY_TOP_STATE_SETTLE_TIME); pw.print("="); 289e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn TimeUtils.formatDuration(TOP_STATE_SETTLE_TIME, pw); 290b94d82f41576fa81fc2aa1994a88796b71c6b9e4Dianne Hackborn pw.println(); 291e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn pw.print(" "); pw.print(KEY_FG_SERVICE_STATE_SETTLE_TIME); pw.print("="); 292e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn TimeUtils.formatDuration(FG_SERVICE_STATE_SETTLE_TIME, pw); 293b94d82f41576fa81fc2aa1994a88796b71c6b9e4Dianne Hackborn pw.println(); 294e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn pw.print(" "); pw.print(KEY_BG_STATE_SETTLE_TIME); pw.print("="); 295e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn TimeUtils.formatDuration(BG_STATE_SETTLE_TIME, pw); 29665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(); 29765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 29865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 29965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 30065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private final Constants mConstants; 30165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 3023ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @VisibleForTesting 3033ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla static final class UidState { 3042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public final int uid; 3052378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 306cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn public int state = UID_STATE_CACHED; 3072378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn public int pendingState = UID_STATE_CACHED; 3082378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn public long pendingStateCommitTime; 3092378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 310cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn public int startNesting; 3112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public ArrayMap<String, Ops> pkgOps; 3122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public SparseIntArray opModes; 3132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 31465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn // true indicates there is an interested observer, false there isn't but it has such an op 3152378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn public SparseBooleanArray foregroundOps; 31665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public boolean hasForegroundWatchers; 3172378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 3182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public UidState(int uid) { 3192af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov this.uid = uid; 3202af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3212af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 3222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public void clear() { 3232af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov pkgOps = null; 3242af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov opModes = null; 3252af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3262af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 3272af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public boolean isDefault() { 3282af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return (pkgOps == null || pkgOps.isEmpty()) 3292af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov && (opModes == null || opModes.size() <= 0); 3302af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3312378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 3322378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn int evalMode(int mode) { 3332378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (mode == AppOpsManager.MODE_FOREGROUND) { 334e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn return state <= UID_STATE_LAST_NON_RESTRICTED 3352378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED; 3362378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3372378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return mode; 3382378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3392378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 34065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private void evalForegroundWatchers(int op, SparseArray<ArraySet<ModeCallback>> watchers, 34165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn SparseBooleanArray which) { 34265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean curValue = which.get(op, false); 34365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn ArraySet<ModeCallback> callbacks = watchers.get(op); 34465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (callbacks != null) { 34565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int cbi = callbacks.size() - 1; !curValue && cbi >= 0; cbi--) { 34665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if ((callbacks.valueAt(cbi).mFlags 34765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn & AppOpsManager.WATCH_FOREGROUND_CHANGES) != 0) { 34865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasForegroundWatchers = true; 34965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn curValue = true; 35065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 35165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 35265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 35365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn which.put(op, curValue); 35465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 35565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 35665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public void evalForegroundOps(SparseArray<ArraySet<ModeCallback>> watchers) { 3572378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn SparseBooleanArray which = null; 35865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasForegroundWatchers = false; 35965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (opModes != null) { 36065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int i = opModes.size() - 1; i >= 0; i--) { 36165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (opModes.valueAt(i) == AppOpsManager.MODE_FOREGROUND) { 36265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (which == null) { 36365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn which = new SparseBooleanArray(); 36465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 36565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn evalForegroundWatchers(opModes.keyAt(i), watchers, which); 36665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 36765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 36865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 3692378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (pkgOps != null) { 3702378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn for (int i = pkgOps.size() - 1; i >= 0; i--) { 3712378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn Ops ops = pkgOps.valueAt(i); 3722378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn for (int j = ops.size() - 1; j >= 0; j--) { 3732378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (ops.valueAt(j).mode == AppOpsManager.MODE_FOREGROUND) { 3742378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (which == null) { 3752378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn which = new SparseBooleanArray(); 3762378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 37765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn evalForegroundWatchers(ops.keyAt(j), watchers, which); 3782378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3792378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3802378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3812378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3822378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn foregroundOps = which; 3832378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3842af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3852af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 386cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final static class Ops extends SparseArray<Op> { 387cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final String packageName; 388cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final UidState uidState; 389cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final boolean isPrivileged; 390a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 391cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Ops(String _packageName, UidState _uidState, boolean _isPrivileged) { 392a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn packageName = _packageName; 3932af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState = _uidState; 3941c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk isPrivileged = _isPrivileged; 395a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 396a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 397a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 398cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final static class Op { 399cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final UidState uidState; 400cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final int uid; 401cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final String packageName; 402cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final int op; 403cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn int proxyUid = -1; 404cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn String proxyPackageName; 405cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn int mode; 406cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn int duration; 407cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn long time[] = new long[_NUM_UID_STATE]; 408cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn long rejectTime[] = new long[_NUM_UID_STATE]; 409cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn int startNesting; 410cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn long startRealtime; 411cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 412cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Op(UidState _uidState, String _packageName, int _op) { 413cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn uidState = _uidState; 414cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn uid = _uidState.uid; 415e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn packageName = _packageName; 416a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn op = _op; 417f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun mode = AppOpsManager.opToDefaultMode(op); 418a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 419cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 420cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn boolean hasAnyTime() { 421cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int i = 0; i < AppOpsManager._NUM_UID_STATE; i++) { 422cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (time[i] != 0) { 423cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn return true; 424cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 425cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (rejectTime[i] != 0) { 426cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn return true; 427cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 428cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 429cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn return false; 430cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 4312378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 4322378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn int getMode() { 4332378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return uidState.evalMode(mode); 4342378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 435a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 436a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 4372d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>(); 4382d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ArrayMap<String, ArraySet<ModeCallback>> mPackageModeWatchers = new ArrayMap<>(); 4392d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ArrayMap<IBinder, ModeCallback> mModeWatchers = new ArrayMap<>(); 4402d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ArrayMap<IBinder, SparseArray<ActiveCallback>> mActiveWatchers = new ArrayMap<>(); 44168d76555582ebd414158af9874f64bae3832540cDianne Hackborn final SparseArray<SparseArray<Restriction>> mAudioRestrictions = new SparseArray<>(); 442c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 443cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final class ModeCallback implements DeathRecipient { 444c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final IAppOpsCallback mCallback; 4453b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mWatchingUid; 44665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final int mFlags; 4473b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mCallingUid; 4483b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mCallingPid; 449c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 45065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn ModeCallback(IAppOpsCallback callback, int watchingUid, int flags, int callingUid, 4513b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn int callingPid) { 452c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback = callback; 4533b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mWatchingUid = watchingUid; 45465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mFlags = flags; 4553b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mCallingUid = callingUid; 4563b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mCallingPid = callingPid; 457c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 458c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().linkToDeath(this, 0); 459c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 460c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 461c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 462c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 46365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public boolean isWatchingUid(int uid) { 46465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return uid == UID_ANY || mWatchingUid < 0 || mWatchingUid == uid; 46565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 46665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 4673b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn @Override 4683b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn public String toString() { 4693b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn StringBuilder sb = new StringBuilder(128); 4703b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append("ModeCallback{"); 4713b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 4723b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" watchinguid="); 4733b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn UserHandle.formatUid(sb, mWatchingUid); 47465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn sb.append(" flags=0x"); 47565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn sb.append(Integer.toHexString(mFlags)); 4763b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" from uid="); 4773b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn UserHandle.formatUid(sb, mCallingUid); 4783b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" pid="); 4793b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(mCallingPid); 4803b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append('}'); 4813b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn return sb.toString(); 4823b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn } 4833b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn 484cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn void unlinkToDeath() { 485c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().unlinkToDeath(this, 0); 486c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 487c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 488c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 489c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void binderDied() { 490c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn stopWatchingMode(mCallback); 491c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 492c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 493c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 494cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final class ActiveCallback implements DeathRecipient { 4952d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final IAppOpsActiveCallback mCallback; 4963b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mWatchingUid; 4973b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mCallingUid; 4983b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int mCallingPid; 4992d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 500cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn ActiveCallback(IAppOpsActiveCallback callback, int watchingUid, int callingUid, 5013b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn int callingPid) { 5022d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mCallback = callback; 5033b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mWatchingUid = watchingUid; 5043b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mCallingUid = callingUid; 5053b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mCallingPid = callingPid; 5062d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov try { 5072d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mCallback.asBinder().linkToDeath(this, 0); 5082d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } catch (RemoteException e) { 5092d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 5102d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 5112d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 5123b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn @Override 5133b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn public String toString() { 5143b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn StringBuilder sb = new StringBuilder(128); 5153b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append("ActiveCallback{"); 5163b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 5173b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" watchinguid="); 5183b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn UserHandle.formatUid(sb, mWatchingUid); 5193b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" from uid="); 5203b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn UserHandle.formatUid(sb, mCallingUid); 5213b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(" pid="); 5223b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append(mCallingPid); 5233b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn sb.append('}'); 5243b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn return sb.toString(); 5253b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn } 5263b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn 527cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn void destroy() { 5282d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mCallback.asBinder().unlinkToDeath(this, 0); 5292d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 5302d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 5312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov @Override 5322d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov public void binderDied() { 5332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov stopWatchingActive(mCallback); 5342d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 5352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 5362d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 537a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>(); 538e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 539cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final class ClientState extends Binder implements DeathRecipient { 540f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov final ArrayList<Op> mStartedOps = new ArrayList<>(); 541e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final IBinder mAppToken; 542e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final int mPid; 543e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 544cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn ClientState(IBinder appToken) { 545e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken = appToken; 546e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPid = Binder.getCallingPid(); 547f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov // Watch only for remote processes dying 548f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (!(appToken instanceof Binder)) { 549e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn try { 550e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken.linkToDeath(this, 0); 551e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } catch (RemoteException e) { 552f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov /* do nothing */ 553e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 554e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 555e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 556e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 557e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 558e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public String toString() { 559e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return "ClientState{" + 560e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn "mAppToken=" + mAppToken + 561f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov ", " + "pid=" + mPid + 562e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn '}'; 563e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 564e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 565e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 566e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void binderDied() { 567e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (AppOpsService.this) { 568e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mStartedOps.size()-1; i>=0; i--) { 569a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov finishOperationLocked(mStartedOps.get(i), /*finishNested*/ true); 570e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 571e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.remove(mAppToken); 572e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 573e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 574e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 575e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 5766f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public AppOpsService(File storagePath, Handler handler) { 5775f3e93451e87d72c513e75c5d5459a4bd2cc41b2Jeff Sharkey LockGuard.installLock(this, LockGuard.INDEX_APP_OPS); 578e17b445b6c813f6f9bc93a5e3811128a197ef50bDianne Hackborn mFile = new AtomicFile(storagePath, "appops"); 5796f357d3284a833cc50a990e14b39f389b8972254Jeff Brown mHandler = handler; 58065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mConstants = new Constants(mHandler); 58135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readState(); 582a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 583f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun 584a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void publish(Context context) { 585a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext = context; 586a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); 587d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn LocalServices.addService(AppOpsManagerInternal.class, mAppOpsManagerInternal); 588a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 589a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 590514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void systemReady() { 59145c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn mConstants.startMonitoring(mContext.getContentResolver()); 59245c79b0b24ad62cb6fc95955b9bdea0520f028c2Dianne Hackborn 593514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 594514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn boolean changed = false; 5952af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i = mUidStates.size() - 1; i >= 0; i--) { 5962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.valueAt(i); 5972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 5982af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov String[] packageNames = getPackagesForUid(uidState.uid); 5992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (ArrayUtils.isEmpty(packageNames)) { 6002af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.clear(); 6012af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.removeAt(i); 6022af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov changed = true; 6032af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 6042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 6052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 6062af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov ArrayMap<String, Ops> pkgs = uidState.pkgOps; 6072af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (pkgs == null) { 6082af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 6092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 6102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 611514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Iterator<Ops> it = pkgs.values().iterator(); 612514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn while (it.hasNext()) { 613514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Ops ops = it.next(); 614e2ed23e6b221185ce2587fb19a6e904dbf7ec77bJeff Sharkey int curUid = -1; 615514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 616cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey curUid = AppGlobals.getPackageManager().getPackageUid(ops.packageName, 617cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageManager.MATCH_UNINSTALLED_PACKAGES, 6182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UserHandle.getUserId(ops.uidState.uid)); 619e2ed23e6b221185ce2587fb19a6e904dbf7ec77bJeff Sharkey } catch (RemoteException ignored) { 620514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 6212af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (curUid != ops.uidState.uid) { 622514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.i(TAG, "Pruning old package " + ops.packageName 6232af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov + "/" + ops.uidState + ": new uid=" + curUid); 624514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn it.remove(); 625514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn changed = true; 626514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 627514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 6282af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 6292af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.isDefault()) { 6302af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.removeAt(i); 631514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 632514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 633514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (changed) { 6347b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn scheduleFastWriteLocked(); 635514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 636514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 6376ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov 638aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla PackageManagerInternal packageManagerInternal = LocalServices.getService( 639aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla PackageManagerInternal.class); 640aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla packageManagerInternal.setExternalSourcesPolicy( 641aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla new PackageManagerInternal.ExternalSourcesPolicy() { 642aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla @Override 643aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla public int getPackageTrustedToInstallApps(String packageName, int uid) { 644aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla int appOpMode = checkOperation(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, 645aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla uid, packageName); 646aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla switch (appOpMode) { 647aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla case AppOpsManager.MODE_ALLOWED: 648aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla return PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED; 649aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla case AppOpsManager.MODE_ERRORED: 650aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla return PackageManagerInternal.ExternalSourcesPolicy.USER_BLOCKED; 651aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla default: 652aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla return PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT; 653aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla } 654aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla } 655aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla }); 656aef2513c7157a28236d097a81fe74d7ba6b710c9Suprabh Shukla 6572250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka StorageManagerInternal storageManagerInternal = LocalServices.getService( 6582250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka StorageManagerInternal.class); 6592250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka storageManagerInternal.addExternalStoragePolicy( 6602250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka new StorageManagerInternal.ExternalStorageMountPolicy() { 6616ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov @Override 6626ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov public int getMountMode(int uid, String packageName) { 6636ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov if (Process.isIsolated(uid)) { 6646ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov return Zygote.MOUNT_EXTERNAL_NONE; 6656ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov } 6666ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, 6676ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov packageName) != AppOpsManager.MODE_ALLOWED) { 6686ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov return Zygote.MOUNT_EXTERNAL_NONE; 6696ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov } 6706ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, 6716ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov packageName) != AppOpsManager.MODE_ALLOWED) { 6726ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov return Zygote.MOUNT_EXTERNAL_READ; 6736ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov } 6746ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov return Zygote.MOUNT_EXTERNAL_WRITE; 6756ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov } 6766ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov 6776ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov @Override 6786ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov public boolean hasExternalStorage(int uid, String packageName) { 6796ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov final int mountMode = getMountMode(uid, packageName); 6806ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov return mountMode == Zygote.MOUNT_EXTERNAL_READ 6816ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; 6826ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov } 6836ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov }); 684514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 685514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 686514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void packageRemoved(int uid, String packageName) { 687514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 6882af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.get(uid); 6892af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState == null) { 6902af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return; 6912af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 6922af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 6932d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Ops ops = null; 6942af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 6952af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov // Remove any package state if such. 6962d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (uidState.pkgOps != null) { 6972d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ops = uidState.pkgOps.remove(packageName); 6982af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 6992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 7002af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov // If we just nuked the last package state check if the UID is valid. 7012d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (ops != null && uidState.pkgOps.isEmpty() 7022af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov && getPackagesForUid(uid).length <= 0) { 7032af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.remove(uid); 7042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 7052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 706a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov // Finish ops other packages started on behalf of the package. 707a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov final int clientCount = mClients.size(); 708a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov for (int i = 0; i < clientCount; i++) { 709a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov final ClientState client = mClients.valueAt(i); 710a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov if (client.mStartedOps == null) { 711a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov continue; 712a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov } 713a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov final int opCount = client.mStartedOps.size(); 714a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov for (int j = opCount - 1; j >= 0; j--) { 715a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov final Op op = client.mStartedOps.get(j); 716a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov if (uid == op.uid && packageName.equals(op.packageName)) { 717a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov finishOperationLocked(op, /*finishNested*/ true); 718a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov client.mStartedOps.remove(j); 719cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting <= 0) { 720a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov scheduleOpActiveChangedIfNeededLocked(op.op, 721a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov uid, packageName, false); 722a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov } 723a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov } 724a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov } 725a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov } 726a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov 7272d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (ops != null) { 7282af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov scheduleFastWriteLocked(); 7292d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 7302d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int opCount = ops.size(); 7312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < opCount; i++) { 7322d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final Op op = ops.valueAt(i); 7332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (op.duration == -1) { 7342d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov scheduleOpActiveChangedIfNeededLocked( 7352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov op.op, op.uid, op.packageName, false); 7362d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 7372d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 738514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 739514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 740514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 741514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 742514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void uidRemoved(int uid) { 743514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 7442af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (mUidStates.indexOfKey(uid) >= 0) { 7452af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.remove(uid); 7467b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn scheduleFastWriteLocked(); 747514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 748514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 749514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 750514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 751cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn public void updateUidProcState(int uid, int procState) { 752cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn synchronized (this) { 753cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final UidState uidState = getUidStateLocked(uid, true); 754cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final int newState = PROCESS_STATE_TO_UID_STATE[procState]; 7552378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState != null && uidState.pendingState != newState) { 75665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final int oldPendingState = uidState.pendingState; 75765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.pendingState = newState; 758e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn if (newState < uidState.state || newState <= UID_STATE_LAST_NON_RESTRICTED) { 759e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn // We are moving to a more important state, or the new state is in the 760e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn // foreground, then always do it immediately. 76165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn commitUidPendingStateLocked(uidState); 7622378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } else if (uidState.pendingStateCommitTime == 0) { 7632378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn // We are moving to a less important state for the first time, 7642378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn // delay the application for a bit. 765e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn final long settleTime; 766e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn if (uidState.state <= UID_STATE_TOP) { 767e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn settleTime = mConstants.TOP_STATE_SETTLE_TIME; 768e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn } else if (uidState.state <= UID_STATE_FOREGROUND_SERVICE) { 769e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn settleTime = mConstants.FG_SERVICE_STATE_SETTLE_TIME; 770e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn } else { 771e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn settleTime = mConstants.BG_STATE_SETTLE_TIME; 772e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn } 773e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn uidState.pendingStateCommitTime = SystemClock.uptimeMillis() + settleTime; 7742378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 775cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (uidState.startNesting != 0) { 776cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn // There is some actively running operation... need to find it 777cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn // and appropriately update its state. 778cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final long now = System.currentTimeMillis(); 779cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int i = uidState.pkgOps.size() - 1; i >= 0; i--) { 780cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Ops ops = uidState.pkgOps.valueAt(i); 781cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int j = ops.size() - 1; j >= 0; j--) { 782cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Op op = ops.valueAt(j); 783cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting > 0) { 78465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn op.time[oldPendingState] = now; 785cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[newState] = now; 786cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 787cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 788cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 789cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 790cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 791cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 792cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 793cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 794a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void shutdown() { 795a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Slog.w(TAG, "Writing app ops before shutdown..."); 79635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean doWrite = false; 79735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 79835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mWriteScheduled) { 79935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 80035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn doWrite = true; 80135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (doWrite) { 80435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 80535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 806a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 807a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 80872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) { 80972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = null; 810cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final long elapsedNow = SystemClock.elapsedRealtime(); 81172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 812cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn resOps = new ArrayList<>(); 81372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<pkgOps.size(); j++) { 81472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.valueAt(j); 815a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani final boolean running = curOp.duration == -1; 816a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani long duration = running 817cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn ? (elapsedNow - curOp.startRealtime) 818cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn : curOp.duration; 8195e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 820a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani curOp.rejectTime, (int) duration, running, curOp.proxyUid, 82199b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov curOp.proxyPackageName)); 82272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 82372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } else { 82472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<ops.length; j++) { 82572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.get(ops[j]); 82672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (curOp != null) { 82772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 828cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn resOps = new ArrayList<>(); 82972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 830a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani final boolean running = curOp.duration == -1; 831a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani final long duration = running 832cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn ? (elapsedNow - curOp.startRealtime) 833cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn : curOp.duration; 8345e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 835a1ce9637435f28b1de2b9e8e8a2175b53cc9e0f2Amith Yamasani curOp.rejectTime, (int) duration, running, curOp.proxyUid, 83699b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov curOp.proxyPackageName)); 83772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 83872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 83972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 84072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return resOps; 84172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 84272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 843c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn private ArrayList<AppOpsManager.OpEntry> collectOps(SparseIntArray uidOps, int[] ops) { 844c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = null; 845c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (ops == null) { 846c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn resOps = new ArrayList<>(); 847c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn for (int j=0; j<uidOps.size(); j++) { 848c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(j), uidOps.valueAt(j), 849c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn 0, 0, 0, -1, null)); 850c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 851c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } else { 852c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn for (int j=0; j<ops.length; j++) { 853c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int index = uidOps.indexOfKey(ops[j]); 854c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (index >= 0) { 855c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (resOps == null) { 856c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn resOps = new ArrayList<>(); 857c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 858c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(index), uidOps.valueAt(index), 859c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn 0, 0, 0, -1, null)); 860c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 861c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 862c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 863c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn return resOps; 864c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 865c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn 866a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 86735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 86835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 86935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 87035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = null; 871a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 8722af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int uidStateCount = mUidStates.size(); 8732af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i = 0; i < uidStateCount; i++) { 8742af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.valueAt(i); 8752af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()) { 8762af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 8772af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 8782af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov ArrayMap<String, Ops> packages = uidState.pkgOps; 8792af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int packageCount = packages.size(); 8802af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int j = 0; j < packageCount; j++) { 8812af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov Ops pkgOps = packages.valueAt(j); 88272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 88335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (resOps != null) { 88435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (res == null) { 88535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res = new ArrayList<AppOpsManager.PackageOps>(); 88635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 88735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 8882af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov pkgOps.packageName, pkgOps.uidState.uid, resOps); 88935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res.add(resPackage); 89035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 89135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 892a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 893a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 89435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return res; 895a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 896a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 897a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 89872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, 89972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn int[] ops) { 90072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 90172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 902f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolvedPackageName = resolvePackageName(uid, packageName); 903f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolvedPackageName == null) { 904f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return Collections.emptyList(); 905f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 90672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn synchronized (this) { 907a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */, 908a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 90972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (pkgOps == null) { 91072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 91172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 91272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 91372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 91472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 91572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 91672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); 91772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 9182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov pkgOps.packageName, pkgOps.uidState.uid, resOps); 91972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn res.add(resPackage); 92072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return res; 92172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 92272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 92372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 924c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn @Override 925c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn public List<AppOpsManager.PackageOps> getUidOps(int uid, int[] ops) { 926c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 927c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 928c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn synchronized (this) { 929c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn UidState uidState = getUidStateLocked(uid, false); 930c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (uidState == null) { 931c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn return null; 932c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 933c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState.opModes, ops); 934c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (resOps == null) { 935c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn return null; 936c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 937c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); 938c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 939c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn null, uidState.uid, resOps); 940c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn res.add(resPackage); 941c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn return res; 942c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 943c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 944c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn 945607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn private void pruneOp(Op op, int uid, String packageName) { 946cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (!op.hasAnyTime()) { 947a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops ops = getOpsRawLocked(uid, packageName, false /* edit */, 948a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 949607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (ops != null) { 950607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn ops.remove(op.op); 951607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (ops.size() <= 0) { 9522af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = ops.uidState; 9532af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov ArrayMap<String, Ops> pkgOps = uidState.pkgOps; 954607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (pkgOps != null) { 955607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn pkgOps.remove(ops.packageName); 9562af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (pkgOps.isEmpty()) { 9572af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.pkgOps = null; 9582af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9592af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.isDefault()) { 9602af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.remove(uid); 9612af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9622af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9632af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9642af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9652af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9662af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 9672af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 968d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn void enforceManageAppOpsModes(int callingPid, int callingUid, int targetUid) { 969d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn if (callingPid == Process.myPid()) { 970d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn return; 971d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 972d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn final int callingUser = UserHandle.getUserId(callingUid); 973d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn synchronized (this) { 974d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn if (mProfileOwners != null && mProfileOwners.get(callingUser, -1) == callingUid) { 975d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn if (targetUid >= 0 && callingUser == UserHandle.getUserId(targetUid)) { 976d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn // Profile owners are allowed to change modes but only for apps 977d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn // within their user. 978d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn return; 979d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 980d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 981d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 982d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES, 983d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 984d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 985d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn 9862af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov @Override 9872af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov public void setUidMode(int code, int uid, int mode) { 988d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); 9892af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov verifyIncomingOp(code); 9902af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov code = AppOpsManager.opToSwitch(code); 9912af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 9922af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov synchronized (this) { 9932af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int defaultMode = AppOpsManager.opToDefaultMode(code); 9942af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 9952af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, false); 9962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState == null) { 9972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (mode == defaultMode) { 9982af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return; 9992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10002af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState = new UidState(uid); 10012af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes = new SparseIntArray(); 10022af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes.put(code, mode); 10032af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.put(uid, uidState); 10042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov scheduleWriteLocked(); 10052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } else if (uidState.opModes == null) { 10062af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (mode != defaultMode) { 10072af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes = new SparseIntArray(); 10082af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes.put(code, mode); 10092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov scheduleWriteLocked(); 10102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } else { 10122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.opModes.get(code) == mode) { 10132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return; 10142af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10152af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (mode == defaultMode) { 10162af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes.delete(code); 10172af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.opModes.size() <= 0) { 10182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes = null; 10192af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10202af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } else { 10212af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes.put(code, mode); 10222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10232af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov scheduleWriteLocked(); 10242af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10252af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10262af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 1027215b44a1c2c883e628e1ab5b945a1a4aa04ee392Svetoslav String[] uidPackageNames = getPackagesForUid(uid); 10282d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArrayMap<ModeCallback, ArraySet<String>> callbackSpecs = null; 10292af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 103040b300fd80708fd100d22f22ff6100db20ee467friddle_hsu synchronized (this) { 10312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); 10322af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (callbacks != null) { 10332af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int callbackCount = callbacks.size(); 10342af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i = 0; i < callbackCount; i++) { 10352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback callback = callbacks.valueAt(i); 103640b300fd80708fd100d22f22ff6100db20ee467friddle_hsu ArraySet<String> changedPackages = new ArraySet<>(); 103740b300fd80708fd100d22f22ff6100db20ee467friddle_hsu Collections.addAll(changedPackages, uidPackageNames); 103865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (callbackSpecs == null) { 103965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn callbackSpecs = new ArrayMap<>(); 104065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 104140b300fd80708fd100d22f22ff6100db20ee467friddle_hsu callbackSpecs.put(callback, changedPackages); 104240b300fd80708fd100d22f22ff6100db20ee467friddle_hsu } 104340b300fd80708fd100d22f22ff6100db20ee467friddle_hsu } 104440b300fd80708fd100d22f22ff6100db20ee467friddle_hsu 104540b300fd80708fd100d22f22ff6100db20ee467friddle_hsu for (String uidPackageName : uidPackageNames) { 104640b300fd80708fd100d22f22ff6100db20ee467friddle_hsu callbacks = mPackageModeWatchers.get(uidPackageName); 104740b300fd80708fd100d22f22ff6100db20ee467friddle_hsu if (callbacks != null) { 104840b300fd80708fd100d22f22ff6100db20ee467friddle_hsu if (callbackSpecs == null) { 104940b300fd80708fd100d22f22ff6100db20ee467friddle_hsu callbackSpecs = new ArrayMap<>(); 105040b300fd80708fd100d22f22ff6100db20ee467friddle_hsu } 105140b300fd80708fd100d22f22ff6100db20ee467friddle_hsu final int callbackCount = callbacks.size(); 105240b300fd80708fd100d22f22ff6100db20ee467friddle_hsu for (int i = 0; i < callbackCount; i++) { 10532d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback callback = callbacks.valueAt(i); 105440b300fd80708fd100d22f22ff6100db20ee467friddle_hsu ArraySet<String> changedPackages = callbackSpecs.get(callback); 105540b300fd80708fd100d22f22ff6100db20ee467friddle_hsu if (changedPackages == null) { 105640b300fd80708fd100d22f22ff6100db20ee467friddle_hsu changedPackages = new ArraySet<>(); 105740b300fd80708fd100d22f22ff6100db20ee467friddle_hsu callbackSpecs.put(callback, changedPackages); 105840b300fd80708fd100d22f22ff6100db20ee467friddle_hsu } 105940b300fd80708fd100d22f22ff6100db20ee467friddle_hsu changedPackages.add(uidPackageName); 10602af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10612af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10622af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10632af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10642af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 10652af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (callbackSpecs == null) { 10662af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return; 10672af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 10682af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 10692d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < callbackSpecs.size(); i++) { 10702d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ModeCallback callback = callbackSpecs.keyAt(i); 10712d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i); 10722d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (reportedPackageNames == null) { 10732d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 10742d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsService::notifyOpChanged, 10752d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov this, callback, code, uid, (String) null)); 10762d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 10772d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } else { 10782d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int reportedPackageCount = reportedPackageNames.size(); 10792d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int j = 0; j < reportedPackageCount; j++) { 10802d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final String reportedPackageName = reportedPackageNames.valueAt(j); 10812d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 10822d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsService::notifyOpChanged, 10832d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov this, callback, code, uid, reportedPackageName)); 1084607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1085607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1086607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1087607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1088607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 108972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn @Override 10905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public void setMode(int code, int uid, String packageName, int mode) { 1091d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); 1092961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 10932d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> repCbs = null; 1094c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn code = AppOpsManager.opToSwitch(code); 10955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn synchronized (this) { 10962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, false); 1097c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 10985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op != null) { 10995e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.mode != mode) { 11005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = mode; 11012378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState != null) { 110265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.evalForegroundOps(mOpModeWatchers); 11032378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 11042d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> cbs = mOpModeWatchers.get(code); 1105c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 1106c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 11072d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov repCbs = new ArraySet<>(); 1108c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1109c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 1110c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1111c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = mPackageModeWatchers.get(packageName); 1112c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 1113c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 11142d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov repCbs = new ArraySet<>(); 1115c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1116c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 1117c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1118f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (mode == AppOpsManager.opToDefaultMode(op.op)) { 1119514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // If going into the default mode, prune this op 1120514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // if there is nothing else interesting in it. 1121607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn pruneOp(op, uid, packageName); 1122514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 11237b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn scheduleFastWriteLocked(); 11245e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 11255e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 11265e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 1127c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs != null) { 11282d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 11292d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsService::notifyOpChanged, 11302d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov this, repCbs, code, uid, packageName)); 11312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 11322d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 11332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 11342d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov private void notifyOpChanged(ArraySet<ModeCallback> callbacks, int code, 11352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov int uid, String packageName) { 11362d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < callbacks.size(); i++) { 11372d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ModeCallback callback = callbacks.valueAt(i); 11382d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov notifyOpChanged(callback, code, uid, packageName); 11392d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 11402d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 11412d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 11422d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov private void notifyOpChanged(ModeCallback callback, int code, 11432d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov int uid, String packageName) { 11443b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn if (uid != UID_ANY && callback.mWatchingUid >= 0 && callback.mWatchingUid != uid) { 11452d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return; 11462d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 11472d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // There are components watching for mode changes such as window manager 11482d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // and location manager which are in our process. The callbacks in these 11492d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // components may require permissions our remote caller does not have. 11502d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 11512d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov try { 11522d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov callback.mCallback.opChanged(code, uid, packageName); 11532d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } catch (RemoteException e) { 11542d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov /* ignore */ 11552d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } finally { 11562d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Binder.restoreCallingIdentity(identity); 1157c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1158c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1159c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 11602d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov private static HashMap<ModeCallback, ArrayList<ChangeRec>> addCallbacks( 11612d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks, 11622d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov int op, int uid, String packageName, ArraySet<ModeCallback> cbs) { 1163607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (cbs == null) { 1164607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn return callbacks; 1165607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1166607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (callbacks == null) { 1167bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn callbacks = new HashMap<>(); 1168607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 11692af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov boolean duplicate = false; 117068d76555582ebd414158af9874f64bae3832540cDianne Hackborn final int N = cbs.size(); 117168d76555582ebd414158af9874f64bae3832540cDianne Hackborn for (int i=0; i<N; i++) { 11722d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback cb = cbs.valueAt(i); 1173bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn ArrayList<ChangeRec> reports = callbacks.get(cb); 1174607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (reports == null) { 1175bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn reports = new ArrayList<>(); 1176607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks.put(cb, reports); 11772af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } else { 11782af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int reportCount = reports.size(); 11792af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int j = 0; j < reportCount; j++) { 1180bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn ChangeRec report = reports.get(j); 1181bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn if (report.op == op && report.pkg.equals(packageName)) { 11822af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov duplicate = true; 11832af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov break; 11842af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 11852af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 11862af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 11872af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (!duplicate) { 1188bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn reports.add(new ChangeRec(op, uid, packageName)); 1189607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1190607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1191607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn return callbacks; 1192607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1193607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 1194bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn static final class ChangeRec { 1195bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn final int op; 1196bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn final int uid; 1197bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn final String pkg; 1198bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn 1199bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn ChangeRec(int _op, int _uid, String _pkg) { 1200bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn op = _op; 1201bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn uid = _uid; 1202bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn pkg = _pkg; 1203bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn } 1204bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn } 1205bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn 1206607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn @Override 12077b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn public void resetAllModes(int reqUserId, String reqPackageName) { 12087b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn final int callingPid = Binder.getCallingPid(); 12097b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn final int callingUid = Binder.getCallingUid(); 12107b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId, 12117b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn true, true, "resetAllModes", null); 12122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 12132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov int reqUid = -1; 12142af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (reqPackageName != null) { 12152af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov try { 12162af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov reqUid = AppGlobals.getPackageManager().getPackageUid( 1217cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey reqPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, reqUserId); 12182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } catch (RemoteException e) { 12192af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov /* ignore - local call */ 12202af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12212af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 1223d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn enforceManageAppOpsModes(callingPid, callingUid, reqUid); 1224d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn 12252d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks = null; 1226607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn synchronized (this) { 1227607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn boolean changed = false; 12282af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i = mUidStates.size() - 1; i >= 0; i--) { 12292af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.valueAt(i); 12302af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 12312af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov SparseIntArray opModes = uidState.opModes; 12322af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) { 12332af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int uidOpCount = opModes.size(); 12342af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int j = uidOpCount - 1; j >= 0; j--) { 12352af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int code = opModes.keyAt(j); 12362af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (AppOpsManager.opAllowsReset(code)) { 12372af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov opModes.removeAt(j); 12382af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (opModes.size() <= 0) { 12392af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes = null; 12402af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12412af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (String packageName : getPackagesForUid(uidState.uid)) { 1242bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, 12432af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mOpModeWatchers.get(code)); 1244bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, 12452af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mPackageModeWatchers.get(packageName)); 12462af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12472af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12482af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12492af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12502af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 12512af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.pkgOps == null) { 12522af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 12532af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 12542af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 12557b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn if (reqUserId != UserHandle.USER_ALL 12562af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov && reqUserId != UserHandle.getUserId(uidState.uid)) { 1257d6a98979b5d45fff1fa842932274517e999a59c2Alexandra Gherghina // Skip any ops for a different user 1258d6a98979b5d45fff1fa842932274517e999a59c2Alexandra Gherghina continue; 1259d6a98979b5d45fff1fa842932274517e999a59c2Alexandra Gherghina } 12602af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 12612af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov Map<String, Ops> packages = uidState.pkgOps; 12627f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator(); 12632378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean uidChanged = false; 12647f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn while (it.hasNext()) { 12657f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn Map.Entry<String, Ops> ent = it.next(); 1266607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn String packageName = ent.getKey(); 12677b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn if (reqPackageName != null && !reqPackageName.equals(packageName)) { 12687b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn // Skip any ops for a different package 12697b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn continue; 12707b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn } 1271607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Ops pkgOps = ent.getValue(); 12727f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn for (int j=pkgOps.size()-1; j>=0; j--) { 1273607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Op curOp = pkgOps.valueAt(j); 12748828d3a153e28fe631edcd5145e6cc706e0b34c8Dianne Hackborn if (AppOpsManager.opAllowsReset(curOp.op) 12758828d3a153e28fe631edcd5145e6cc706e0b34c8Dianne Hackborn && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) { 1276f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun curOp.mode = AppOpsManager.opToDefaultMode(curOp.op); 1277607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn changed = true; 12782378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn uidChanged = true; 1279bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName, 1280607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mOpModeWatchers.get(curOp.op)); 1281bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName, 1282607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mPackageModeWatchers.get(packageName)); 1283cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (!curOp.hasAnyTime()) { 12847f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn pkgOps.removeAt(j); 12857f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 1286607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1287607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 12887f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (pkgOps.size() == 0) { 12897f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn it.remove(); 12907f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 12917f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 12922af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.isDefault()) { 12932af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.remove(uidState.uid); 1294607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 12952378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidChanged) { 129665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.evalForegroundOps(mOpModeWatchers); 12972378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 1298607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 12992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 1300607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (changed) { 13017b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn scheduleFastWriteLocked(); 1302607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1303607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1304607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (callbacks != null) { 13052d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (Map.Entry<ModeCallback, ArrayList<ChangeRec>> ent : callbacks.entrySet()) { 13062d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback cb = ent.getKey(); 1307bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn ArrayList<ChangeRec> reports = ent.getValue(); 1308607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (int i=0; i<reports.size(); i++) { 1309bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn ChangeRec rep = reports.get(i); 13102d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 13112d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsService::notifyOpChanged, 13122d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov this, cb, rep.op, rep.uid, rep.pkg)); 1313607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1314607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1315607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1316607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 1317607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 131865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private void evalAllForegroundOpsLocked() { 131965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int uidi = mUidStates.size() - 1; uidi >= 0; uidi--) { 132065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final UidState uidState = mUidStates.valueAt(uidi); 132165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (uidState.foregroundOps != null) { 132265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.evalForegroundOps(mOpModeWatchers); 132365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 132465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 132565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 132665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 1327c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 1328c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { 132965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn startWatchingModeWithFlags(op, packageName, 0, callback); 133065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 133165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 133265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn @Override 133365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn public void startWatchingModeWithFlags(int op, String packageName, int flags, 133465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn IAppOpsCallback callback) { 13352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov int watchedUid = -1; 13363b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int callingUid = Binder.getCallingUid(); 13373b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int callingPid = Binder.getCallingPid(); 13385376edd3b18984dfdfca16d7c15bd8913c5ceba5Dianne Hackborn // TODO: should have a privileged permission to protect this. 13395376edd3b18984dfdfca16d7c15bd8913c5ceba5Dianne Hackborn // Also, if the caller has requested WATCH_FOREGROUND_CHANGES, should we require 13405376edd3b18984dfdfca16d7c15bd8913c5ceba5Dianne Hackborn // the USAGE_STATS permission since this can provide information about when an 13415376edd3b18984dfdfca16d7c15bd8913c5ceba5Dianne Hackborn // app is in the foreground? 13422d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Preconditions.checkArgumentInRange(op, AppOpsManager.OP_NONE, 13432d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsManager._NUM_OP - 1, "Invalid op code: " + op); 13448de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov if (callback == null) { 13458de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov return; 13468de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov } 1347c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 13482af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op; 13492d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback cb = mModeWatchers.get(callback.asBinder()); 1350c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb == null) { 135165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn cb = new ModeCallback(callback, watchedUid, flags, callingUid, callingPid); 1352c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mModeWatchers.put(callback.asBinder(), cb); 1353c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1354c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (op != AppOpsManager.OP_NONE) { 13552d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> cbs = mOpModeWatchers.get(op); 1356c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 135768d76555582ebd414158af9874f64bae3832540cDianne Hackborn cbs = new ArraySet<>(); 1358c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.put(op, cbs); 1359c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1360c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 1361c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1362c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (packageName != null) { 13632d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> cbs = mPackageModeWatchers.get(packageName); 1364c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 136568d76555582ebd414158af9874f64bae3832540cDianne Hackborn cbs = new ArraySet<>(); 1366c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mPackageModeWatchers.put(packageName, cbs); 1367c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1368c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 1369c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 137065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn evalAllForegroundOpsLocked(); 1371c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1372c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1373c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 1374c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 1375c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void stopWatchingMode(IAppOpsCallback callback) { 13768de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov if (callback == null) { 13778de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov return; 13788de5971ac68fdae1a418ed6cd95d276b98b21996Svetoslav Ganov } 1379c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 13802d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ModeCallback cb = mModeWatchers.remove(callback.asBinder()); 1381c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb != null) { 1382c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb.unlinkToDeath(); 1383e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mOpModeWatchers.size()-1; i>=0; i--) { 13842d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> cbs = mOpModeWatchers.valueAt(i); 1385c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 1386c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 1387c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.removeAt(i); 1388c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1389c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1390e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mPackageModeWatchers.size()-1; i>=0; i--) { 13912d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> cbs = mPackageModeWatchers.valueAt(i); 1392e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cbs.remove(cb); 1393e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cbs.size() <= 0) { 1394e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPackageModeWatchers.removeAt(i); 1395c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1396c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1397c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 139865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn evalAllForegroundOpsLocked(); 1399c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 14005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 14015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 14025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn @Override 1403e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public IBinder getToken(IBinder clientToken) { 1404e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (this) { 1405e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.get(clientToken); 1406e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs == null) { 1407e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cs = new ClientState(clientToken); 1408e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.put(clientToken, cs); 1409e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1410e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return cs; 1411e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1412e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1413e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 1414e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 141535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int checkOperation(int code, int uid, String packageName) { 1416f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 1417961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 1418f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolvedPackageName = resolvePackageName(uid, packageName); 1419f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolvedPackageName == null) { 1420f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.MODE_IGNORED; 1421f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1422a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 1423442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { 142462062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk return AppOpsManager.MODE_IGNORED; 142562062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 14262af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov code = AppOpsManager.opToSwitch(code); 14272af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, false); 1428ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (uidState != null && uidState.opModes != null 1429ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov && uidState.opModes.indexOfKey(code) >= 0) { 1430ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov return uidState.opModes.get(code); 14312af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 1432f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov Op op = getOpLocked(code, uid, resolvedPackageName, false); 1433a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 1434f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun return AppOpsManager.opToDefaultMode(code); 1435a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 143665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return op.mode; 1437a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1438a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1439a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1440a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 14417b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock public int checkAudioOperation(int code, int usage, int uid, String packageName) { 1442efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu boolean suspended; 1443efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu try { 1444efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu suspended = isPackageSuspendedForUser(packageName, uid); 1445efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu } catch (IllegalArgumentException ex) { 1446efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu // Package not found. 1447efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu suspended = false; 1448efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu } 1449efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu 1450efc4a344a173ae20ec72b8c05c45b794687fda87Andrei Stingaceanu if (suspended) { 14512d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Slog.i(TAG, "Audio disabled for suspended package=" + packageName + " for uid=" + uid); 14522bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu return AppOpsManager.MODE_IGNORED; 14532bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu } 14542bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu 14551af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock synchronized (this) { 14567b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock final int mode = checkRestrictionLocked(code, usage, uid, packageName); 14571af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (mode != AppOpsManager.MODE_ALLOWED) { 14581af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return mode; 14591af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14601af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14611af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return checkOperation(code, uid, packageName); 14621af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14631af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 1464355b232d7998cfc9b29d42a0356390e25191bcbdAndrei Stingaceanu private boolean isPackageSuspendedForUser(String pkg, int uid) { 14652bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu try { 1466355b232d7998cfc9b29d42a0356390e25191bcbdAndrei Stingaceanu return AppGlobals.getPackageManager().isPackageSuspendedForUser( 1467355b232d7998cfc9b29d42a0356390e25191bcbdAndrei Stingaceanu pkg, UserHandle.getUserId(uid)); 14682bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu } catch (RemoteException re) { 14692bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu throw new SecurityException("Could not talk to package manager service"); 14702bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu } 14712bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu } 14722bc2febd56b12131e7a5e5b1ad49d62b3092ec17Andrei Stingaceanu 14737b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock private int checkRestrictionLocked(int code, int usage, int uid, String packageName) { 14747b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock final SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code); 14757b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock if (usageRestrictions != null) { 14767b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock final Restriction r = usageRestrictions.get(usage); 14771af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (r != null && !r.exceptionPackages.contains(packageName)) { 14781af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return r.mode; 14791af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14801af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14811af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return AppOpsManager.MODE_ALLOWED; 14821af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14831af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 14841af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock @Override 14857b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock public void setAudioRestriction(int code, int usage, int uid, int mode, 14861af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock String[] exceptionPackages) { 1487d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); 14881af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock verifyIncomingUid(uid); 14891af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock verifyIncomingOp(code); 14901af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock synchronized (this) { 14917b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code); 14927b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock if (usageRestrictions == null) { 14937b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock usageRestrictions = new SparseArray<Restriction>(); 14947b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock mAudioRestrictions.put(code, usageRestrictions); 14951af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 14967b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock usageRestrictions.remove(usage); 14971af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (mode != AppOpsManager.MODE_ALLOWED) { 14981af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final Restriction r = new Restriction(); 14991af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock r.mode = mode; 15001af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (exceptionPackages != null) { 15011af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final int N = exceptionPackages.length; 15021af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock r.exceptionPackages = new ArraySet<String>(N); 15031af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock for (int i = 0; i < N; i++) { 15041af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final String pkg = exceptionPackages[i]; 15051af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (pkg != null) { 15061af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock r.exceptionPackages.add(pkg.trim()); 15071af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15081af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15091af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15107b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock usageRestrictions.put(usage, r); 15111af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15121af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15132d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 15142d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 15153a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov AppOpsService::notifyWatchersOfChange, this, code, UID_ANY)); 15161af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 15171af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 15181af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock @Override 1519911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey public int checkPackage(int uid, String packageName) { 1520f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov Preconditions.checkNotNull(packageName); 1521911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey synchronized (this) { 1522a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, 1523a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa true /* uidMismatchExpected */); 1524a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa if (ops != null) { 1525911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ALLOWED; 1526911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } else { 1527911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 1528911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 1529911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 1530911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 1531911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey 1532911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey @Override 153399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov public int noteProxyOperation(int code, String proxyPackageName, 153499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov int proxiedUid, String proxiedPackageName) { 153599b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov verifyIncomingOp(code); 1536f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov final int proxyUid = Binder.getCallingUid(); 1537f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName); 1538f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolveProxyPackageName == null) { 1539f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.MODE_IGNORED; 1540f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1541f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov final int proxyMode = noteOperationUnchecked(code, proxyUid, 1542f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov resolveProxyPackageName, -1, null); 154399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) { 154499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov return proxyMode; 154599b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov } 1546f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolveProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName); 1547f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolveProxiedPackageName == null) { 1548f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.MODE_IGNORED; 1549f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1550f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName, 1551f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov proxyMode, resolveProxyPackageName); 155299b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov } 155399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov 155499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov @Override 155535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int noteOperation(int code, int uid, String packageName) { 1556f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 1557961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 1558f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolvedPackageName = resolvePackageName(uid, packageName); 1559f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolvedPackageName == null) { 1560f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.MODE_IGNORED; 1561f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1562f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return noteOperationUnchecked(code, uid, resolvedPackageName, 0, null); 156399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov } 156499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov 156599b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov private int noteOperationUnchecked(int code, int uid, String packageName, 156699b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov int proxyUid, String proxyPackageName) { 1567a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 1568cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, 1569a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 1570f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 15712d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (DEBUG) Slog.d(TAG, "noteOperation: no op for code " + code + " uid " + uid 15725e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 1573911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 1574a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1575cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Op op = getOpLocked(ops, code, true); 1576442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (isOpRestrictedLocked(uid, code, packageName)) { 157762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk return AppOpsManager.MODE_IGNORED; 157862062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 1579cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final UidState uidState = ops.uidState; 158035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.duration == -1) { 158135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName 1582cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn + " code " + code + " time=" + op.time[uidState.state] 1583cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn + " duration=" + op.duration); 1584a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 158535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = 0; 1586f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 15871984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov // If there is a non-default per UID policy (we set UID op mode only if 15881984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov // non-default) it takes over, otherwise use the per package policy. 15891984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) { 15902378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final int uidMode = uidState.evalMode(uidState.opModes.get(switchCode)); 15912af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidMode != AppOpsManager.MODE_ALLOWED) { 15922378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code " 15932af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov + switchCode + " (" + code + ") uid " + uid + " package " 15942af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov + packageName); 1595cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = System.currentTimeMillis(); 15962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return uidMode; 15972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 15981984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov } else { 15991984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 16002378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final int mode = switchOp.getMode(); 16012378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (mode != AppOpsManager.MODE_ALLOWED) { 16022378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code " 16031984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov + switchCode + " (" + code + ") uid " + uid + " package " 16041984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov + packageName); 1605cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = System.currentTimeMillis(); 16062378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return mode; 16071984bba8c80d9b9abb73836f7824428807d34a50Svetoslav Ganov } 16085e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 16092d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (DEBUG) Slog.d(TAG, "noteOperation: allowing code " + code + " uid " + uid 16105e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 1611cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[uidState.state] = System.currentTimeMillis(); 1612cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = 0; 161399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov op.proxyUid = proxyUid; 161499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov op.proxyPackageName = proxyPackageName; 16155e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 1616a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1617a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1618a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1619a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 16202d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov public void startWatchingActive(int[] ops, IAppOpsActiveCallback callback) { 1621f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov int watchedUid = -1; 16223b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int callingUid = Binder.getCallingUid(); 16233b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final int callingPid = Binder.getCallingPid(); 1624f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS) 1625f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov != PackageManager.PERMISSION_GRANTED) { 16263b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn watchedUid = callingUid; 1627f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov } 16282d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (ops != null) { 16292d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Preconditions.checkArrayElementsInRange(ops, 0, 16302d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsManager._NUM_OP - 1, "Invalid op code in: " + Arrays.toString(ops)); 16312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16322d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (callback == null) { 16332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return; 16342d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16352d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov synchronized (this) { 16362d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov SparseArray<ActiveCallback> callbacks = mActiveWatchers.get(callback.asBinder()); 16372d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (callbacks == null) { 16382d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov callbacks = new SparseArray<>(); 16392d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mActiveWatchers.put(callback.asBinder(), callbacks); 16402d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16413b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn final ActiveCallback activeCallback = new ActiveCallback(callback, watchedUid, 16423b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn callingUid, callingPid); 16432d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int op : ops) { 16442d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov callbacks.put(op, activeCallback); 16452d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16462d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16472d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16482d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 16492d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov @Override 16502d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov public void stopWatchingActive(IAppOpsActiveCallback callback) { 16512d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (callback == null) { 16522d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return; 16532d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16542d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov synchronized (this) { 16552d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final SparseArray<ActiveCallback> activeCallbacks = 16562d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mActiveWatchers.remove(callback.asBinder()); 16572d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (activeCallbacks == null) { 16582d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return; 16592d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16602d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int callbackCount = activeCallbacks.size(); 16612d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < callbackCount; i++) { 16622d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // Apps ops are mapped to a singleton 16632d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (i == 0) { 16642d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov activeCallbacks.valueAt(i).destroy(); 16652d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16662d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16672d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16682d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 16692d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 16702d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov @Override 1671f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov public int startOperation(IBinder token, int code, int uid, String packageName, 1672f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov boolean startIfModeDefault) { 1673f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 1674961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 1675f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolvedPackageName = resolvePackageName(uid, packageName); 1676f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolvedPackageName == null) { 1677f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.MODE_IGNORED; 1678f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1679e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 1680a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 1681cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */, 1682a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 1683f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 16842d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid 1685f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov + " package " + resolvedPackageName); 1686911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 1687a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1688cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Op op = getOpLocked(ops, code, true); 1689442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { 169062062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk return AppOpsManager.MODE_IGNORED; 169162062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 1692f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 1693cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final UidState uidState = ops.uidState; 16942d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // If there is a non-default per UID policy (we set UID op mode only if 16952d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // non-default) it takes over, otherwise use the per package policy. 16962d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) { 16972378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final int uidMode = uidState.evalMode(uidState.opModes.get(switchCode)); 1698f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (uidMode != AppOpsManager.MODE_ALLOWED 1699f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov && (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) { 17002378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code " 17012af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov + switchCode + " (" + code + ") uid " + uid + " package " 1702f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov + resolvedPackageName); 1703cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = System.currentTimeMillis(); 17042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return uidMode; 17052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 17062d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } else { 17072d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 17082378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final int mode = switchOp.getMode(); 17092378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (mode != AppOpsManager.MODE_ALLOWED 17102378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn && (!startIfModeDefault || mode != AppOpsManager.MODE_DEFAULT)) { 17112378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (DEBUG) Slog.d(TAG, "startOperation: reject #" + mode + " for code " 17122d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov + switchCode + " (" + code + ") uid " + uid + " package " 17132d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov + resolvedPackageName); 1714cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = System.currentTimeMillis(); 17152378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return mode; 17162d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17172af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 17182d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid 1719f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov + " package " + resolvedPackageName); 1720cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting == 0) { 1721cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.startRealtime = SystemClock.elapsedRealtime(); 1722cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[uidState.state] = System.currentTimeMillis(); 1723cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[uidState.state] = 0; 172435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = -1; 17252d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, true); 1726a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1727cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.startNesting++; 1728cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn uidState.startNesting++; 1729e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 1730e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn client.mStartedOps.add(op); 1731e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1732a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 17332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 17342d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return AppOpsManager.MODE_ALLOWED; 1735a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1736a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1737a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 1738e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void finishOperation(IBinder token, int code, int uid, String packageName) { 1739f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 1740961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 1741f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov String resolvedPackageName = resolvePackageName(uid, packageName); 1742f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (resolvedPackageName == null) { 1743f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return; 1744f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1745f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (!(token instanceof ClientState)) { 1746f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return; 1747f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1748f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov ClientState client = (ClientState) token; 1749a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 1750f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov Op op = getOpLocked(code, uid, resolvedPackageName, true); 1751a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 1752a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 1753a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1754f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (!client.mStartedOps.remove(op)) { 1755f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov // We finish ops when packages get removed to guarantee no dangling 1756f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov // started ops. However, some part of the system may asynchronously 1757f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov // finish ops for an already gone package. Hence, finishing an op 1758f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov // for a non existing package is fine and we don't log as a wtf. 1759f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov final long identity = Binder.clearCallingIdentity(); 1760f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov try { 1761f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov if (LocalServices.getService(PackageManagerInternal.class).getPackageUid( 1762f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov resolvedPackageName, 0, UserHandle.getUserId(uid)) < 0) { 1763f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov Slog.i(TAG, "Finishing op=" + AppOpsManager.opToName(code) 1764f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov + " for non-existing package=" + resolvedPackageName 1765f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov + " in uid=" + uid); 1766f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov return; 1767f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov } 1768f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov } finally { 1769f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov Binder.restoreCallingIdentity(identity); 1770f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov } 1771f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov Slog.wtf(TAG, "Operation not started: uid=" + op.uid + " pkg=" 1772f5d5af1389827884ad0173485e15678ff16e6866Svet Ganov + op.packageName + " op=" + AppOpsManager.opToName(op.op)); 177331d83ae577c47fff132d4205f1941cd7af13f020Svet Ganov return; 1774e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1775a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov finishOperationLocked(op, /*finishNested*/ false); 1776cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting <= 0) { 17772d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, false); 17782d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17792d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17802d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17812d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 17822d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov private void scheduleOpActiveChangedIfNeededLocked(int code, int uid, String packageName, 17832d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov boolean active) { 17842d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ActiveCallback> dispatchedCallbacks = null; 17852d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int callbackListCount = mActiveWatchers.size(); 17862d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < callbackListCount; i++) { 17872d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final SparseArray<ActiveCallback> callbacks = mActiveWatchers.valueAt(i); 17882d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ActiveCallback callback = callbacks.get(code); 17892d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (callback != null) { 17903b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn if (callback.mWatchingUid >= 0 && callback.mWatchingUid != uid) { 1791f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov continue; 1792f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov } 17932d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (dispatchedCallbacks == null) { 17942d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov dispatchedCallbacks = new ArraySet<>(); 17952d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17962d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov dispatchedCallbacks.add(callback); 17972d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17982d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 17992d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (dispatchedCallbacks == null) { 18002d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov return; 18012d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 18022d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 18032d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov AppOpsService::notifyOpActiveChanged, 18042d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov this, dispatchedCallbacks, code, uid, packageName, active)); 18052d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 18062d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov 18072d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov private void notifyOpActiveChanged(ArraySet<ActiveCallback> callbacks, 18082d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov int code, int uid, String packageName, boolean active) { 18092d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // There are components watching for mode changes such as window manager 18102d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // and location manager which are in our process. The callbacks in these 18112d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov // components may require permissions our remote caller does not have. 18122d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 18132d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov try { 18142d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int callbackCount = callbacks.size(); 18152d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < callbackCount; i++) { 18162d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ActiveCallback callback = callbacks.valueAt(i); 18172d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov try { 18182d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov callback.mCallback.opActiveChanged(code, uid, packageName, active); 18192d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } catch (RemoteException e) { 18202d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov /* do nothing */ 18212d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 18222d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 18232d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } finally { 18242d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov Binder.restoreCallingIdentity(identity); 1825e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1826e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1827e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 1828b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov @Override 1829b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov public int permissionToOpCode(String permission) { 1830f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov if (permission == null) { 1831f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return AppOpsManager.OP_NONE; 1832f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 1833b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov return AppOpsManager.permissionToOpCode(permission); 1834b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov } 1835b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov 1836a7a0db6c93a57b70bc22682536c2506a2738180fSvet Ganov void finishOperationLocked(Op op, boolean finishNested) { 1837cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting <= 1 || finishNested) { 1838cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting == 1 || finishNested) { 1839cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.duration = (int)(SystemClock.elapsedRealtime() - op.startRealtime); 1840cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[op.uidState.state] = System.currentTimeMillis(); 184135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 1842e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg " 1843e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + op.packageName + " code " + op.op + " time=" + op.time 1844cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn + " duration=" + op.duration + " nesting=" + op.startNesting); 1845cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 1846cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting >= 1) { 1847cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.uidState.startNesting -= op.startNesting; 1848a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1849cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.startNesting = 0; 1850e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 1851cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.startNesting--; 1852cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.uidState.startNesting--; 1853a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1854a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1855a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1856f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private void verifyIncomingUid(int uid) { 1857a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (uid == Binder.getCallingUid()) { 1858f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 1859a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1860a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (Binder.getCallingPid() == Process.myPid()) { 1861f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 1862a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1863a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 1864a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 1865a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1866a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 1867961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn private void verifyIncomingOp(int op) { 1868961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn if (op >= 0 && op < AppOpsManager._NUM_OP) { 1869961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn return; 1870961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 1871961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn throw new IllegalArgumentException("Bad operation #" + op); 1872961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 1873961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn 18742af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov private UidState getUidStateLocked(int uid, boolean edit) { 18752af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.get(uid); 18762af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState == null) { 18772af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (!edit) { 18782af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return null; 18792af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 18802af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState = new UidState(uid); 18812af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.put(uid, uidState); 18822378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } else { 18832378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState.pendingStateCommitTime != 0) { 18842378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState.pendingStateCommitTime < mLastUptime) { 188565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn commitUidPendingStateLocked(uidState); 18862378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } else { 18872378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn mLastUptime = SystemClock.uptimeMillis(); 18882378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState.pendingStateCommitTime < mLastUptime) { 188965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn commitUidPendingStateLocked(uidState); 18902378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 18912378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 18922378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 18932af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 18942af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return uidState; 18952af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 18962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 189765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn private void commitUidPendingStateLocked(UidState uidState) { 1898e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn final boolean lastForeground = uidState.state <= UID_STATE_LAST_NON_RESTRICTED; 1899e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn final boolean nowForeground = uidState.pendingState <= UID_STATE_LAST_NON_RESTRICTED; 190065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.state = uidState.pendingState; 190165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.pendingStateCommitTime = 0; 1902e93ab41d2a98f154f5e2a58c10da93226921c462Dianne Hackborn if (uidState.hasForegroundWatchers && lastForeground != nowForeground) { 190365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) { 190465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!uidState.foregroundOps.valueAt(fgi)) { 190565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 190665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 190765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final int code = uidState.foregroundOps.keyAt(fgi); 190865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 190965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); 191065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (callbacks != null) { 191165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { 191265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final ModeCallback callback = callbacks.valueAt(cbi); 191365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0 191465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn || !callback.isWatchingUid(uidState.uid)) { 191565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 191665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 191765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean doAllPackages = uidState.opModes != null 191865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; 191965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (uidState.pkgOps != null) { 192065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { 192165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final Op op = uidState.pkgOps.valueAt(pkgi).get(code); 192265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (doAllPackages || (op != null 192365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && op.mode == AppOpsManager.MODE_FOREGROUND)) { 192465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mHandler.sendMessage(PooledLambda.obtainMessage( 192565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn AppOpsService::notifyOpChanged, 192665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn this, callback, code, uidState.uid, 192765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.pkgOps.keyAt(pkgi))); 192865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 192965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 193665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 1937a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa private Ops getOpsRawLocked(int uid, String packageName, boolean edit, 1938a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa boolean uidMismatchExpected) { 19392af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, edit); 19402af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState == null) { 19412af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov return null; 19422af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 19432af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 19442af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.pkgOps == null) { 194535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 194635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 194735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 19482af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.pkgOps = new ArrayMap<>(); 1949a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 19502af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 19512af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov Ops ops = uidState.pkgOps.get(packageName); 1952a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (ops == null) { 195335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 195435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 195535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 19561c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk boolean isPrivileged = false; 1957a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // This is the first time we have seen this package name under this uid, 1958a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // so let's make sure it is valid. 1959514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid != 0) { 1960514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 1961a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 1962514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int pkgUid = -1; 1963514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 19641c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk ApplicationInfo appInfo = ActivityThread.getPackageManager() 1965cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey .getApplicationInfo(packageName, 1966cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageManager.MATCH_DEBUG_TRIAGED_MISSING, 1967cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey UserHandle.getUserId(uid)); 19681c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk if (appInfo != null) { 19691c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk pkgUid = appInfo.uid; 1970b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin isPrivileged = (appInfo.privateFlags 1971b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 19721c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } else { 197382f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov pkgUid = resolveUid(packageName); 197482f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov if (pkgUid >= 0) { 197575cade0a5fd5ec432870de9977f81091ab389423Chien-Yu Chen isPrivileged = false; 19761c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 1977713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn } 19781c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } catch (RemoteException e) { 19791c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk Slog.w(TAG, "Could not contact PackageManager", e); 1980514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 1981514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgUid != uid) { 1982514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // Oops! The package name is not valid for the uid they are calling 1983514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // under. Abort. 1984a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa if (!uidMismatchExpected) { 1985a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa RuntimeException ex = new RuntimeException("here"); 1986a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa ex.fillInStackTrace(); 1987a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Slog.w(TAG, "Bad call: specified package " + packageName 1988a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa + " under uid " + uid + " but it is really " + pkgUid, ex); 1989a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa } 1990514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn return null; 1991514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 1992514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } finally { 1993514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Binder.restoreCallingIdentity(ident); 1994002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } 1995a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 19962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov ops = new Ops(packageName, uidState, isPrivileged); 19972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.pkgOps.put(packageName, ops); 1998a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 199972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return ops; 200072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 200172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 20025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteLocked() { 20035e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 20045e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 20055e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.postDelayed(mWriteRunner, WRITE_DELAY); 20065e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 20075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 20085e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 20097b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn private void scheduleFastWriteLocked() { 20107b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn if (!mFastWriteScheduled) { 20115e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 20127b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn mFastWriteScheduled = true; 20137b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn mHandler.removeCallbacks(mWriteRunner); 20147b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn mHandler.postDelayed(mWriteRunner, 10*1000); 20155e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 20165e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 20175e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 201872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Op getOpLocked(int code, int uid, String packageName, boolean edit) { 2019a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops ops = getOpsRawLocked(uid, packageName, edit, 2020a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 202172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 202272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 202372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 2024f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return getOpLocked(ops, code, edit); 2025f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn } 2026f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn 2027f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private Op getOpLocked(Ops ops, int code, boolean edit) { 2028a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.get(code); 2029a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 203035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 203135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 203235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 2033cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op = new Op(ops.uidState, ops.packageName, code); 2034a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ops.put(code, op); 2035a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 20365e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (edit) { 20375e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteLocked(); 203835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 2039a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return op; 2040a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 2041a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 2042442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov private boolean isOpRestrictedLocked(int uid, int code, String packageName) { 204362062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk int userHandle = UserHandle.getUserId(uid); 20449cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov final int restrictionSetCount = mOpUserRestrictions.size(); 204529931bc684bde6b430923122777684178ee2681cRuben Brunk 20469cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov for (int i = 0; i < restrictionSetCount; i++) { 204729931bc684bde6b430923122777684178ee2681cRuben Brunk // For each client, check that the given op is not restricted, or that the given 204829931bc684bde6b430923122777684178ee2681cRuben Brunk // package is exempt from the restriction. 2049a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); 2050ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla if (restrictionState.hasRestriction(code, packageName, userHandle)) { 2051ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla if (AppOpsManager.opAllowSystemBypassRestriction(code)) { 2052ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla // If we are the system, bypass user restrictions for certain codes 2053ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla synchronized (this) { 2054a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, 2055a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* uidMismatchExpected */); 2056ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla if ((ops != null) && ops.isPrivileged) { 2057ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla return false; 2058ffddadb04a8df12f05f42721cc59e242e78c2a64Suprabh Shukla } 20591c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 20601c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 20619cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov return true; 20621c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 206362062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 206462062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk return false; 206562062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 206662062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 206735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readState() { 20683ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla int oldVersion = NO_VERSION; 206935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 207035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 207135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileInputStream stream; 207235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 207335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.openRead(); 207435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (FileNotFoundException e) { 207535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty"); 207635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 207735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 207835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean success = false; 20794d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn mUidStates.clear(); 208035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 208135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 20829e9e2e73c6ec7bece20268196dc89ad0c8bafad4Wojciech Staszkiewicz parser.setInput(stream, StandardCharsets.UTF_8.name()); 208335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 208435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 208535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 208635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ; 208735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 208835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 208935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type != XmlPullParser.START_TAG) { 209035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn throw new IllegalStateException("no start tag found"); 209135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 209235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 20933ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla final String versionString = parser.getAttributeValue(null, "v"); 20943ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (versionString != null) { 20953ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla oldVersion = Integer.parseInt(versionString); 20963ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 20973ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 209835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 209935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 210035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 210135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 210235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 210335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 210435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 210535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 210635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("pkg")) { 21070997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readPackage(parser); 2108215b44a1c2c883e628e1ab5b945a1a4aa04ee392Svetoslav } else if (tagName.equals("uid")) { 21092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov readUidOps(parser); 211035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 211135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <app-ops>: " 211235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 211335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 211435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 211535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 211635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn success = true; 211735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IllegalStateException e) { 211835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 211935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NullPointerException e) { 212035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 212135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NumberFormatException e) { 212235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 212335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (XmlPullParserException e) { 212435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 212535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 212635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 212735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IndexOutOfBoundsException e) { 212835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 212935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } finally { 213035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!success) { 21312af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov mUidStates.clear(); 213235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 213335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 213435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream.close(); 213535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 213635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 213735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 213835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 213935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 21403ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla synchronized (this) { 21413ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla upgradeLocked(oldVersion); 21423ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21433ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21443ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 21453ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla private void upgradeRunAnyInBackgroundLocked() { 21463ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla for (int i = 0; i < mUidStates.size(); i++) { 21473ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla final UidState uidState = mUidStates.valueAt(i); 21483ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (uidState == null) { 21493ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla continue; 21503ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21513ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (uidState.opModes != null) { 21523ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla final int idx = uidState.opModes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND); 21533ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (idx >= 0) { 21543ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla uidState.opModes.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, 21553ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla uidState.opModes.valueAt(idx)); 21563ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21573ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21583ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (uidState.pkgOps == null) { 21593ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla continue; 21603ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21612378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean changed = false; 21623ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla for (int j = 0; j < uidState.pkgOps.size(); j++) { 21633ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla Ops ops = uidState.pkgOps.valueAt(j); 21643ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (ops != null) { 21653ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND); 21663ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (op != null && op.mode != AppOpsManager.opToDefaultMode(op.op)) { 2167cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Op copy = new Op(op.uidState, op.packageName, 21683ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla AppOpsManager.OP_RUN_ANY_IN_BACKGROUND); 21693ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla copy.mode = op.mode; 21703ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy); 21712378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn changed = true; 21723ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21733ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21743ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21752378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (changed) { 217665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.evalForegroundOps(mOpModeWatchers); 21772378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 21783ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21793ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21803ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 21813ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla private void upgradeLocked(int oldVersion) { 21823ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla if (oldVersion >= CURRENT_VERSION) { 21833ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla return; 21843ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21853ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla Slog.d(TAG, "Upgrading app-ops xml from version " + oldVersion + " to " + CURRENT_VERSION); 21863ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla switch (oldVersion) { 21873ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla case NO_VERSION: 21883ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla upgradeRunAnyInBackgroundLocked(); 21893ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla // fall through 21903ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla case 1: 21913ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla // for future upgrades 21923ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 21933ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla scheduleFastWriteLocked(); 219435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 219535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 21962af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov void readUidOps(XmlPullParser parser) throws NumberFormatException, 21972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov XmlPullParserException, IOException { 21982af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 21992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov int outerDepth = parser.getDepth(); 22002af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov int type; 22012af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 22022af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 22032af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 22042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 22052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 22062af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 22072af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov String tagName = parser.getName(); 22082af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (tagName.equals("op")) { 22092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int code = Integer.parseInt(parser.getAttributeValue(null, "n")); 22102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int mode = Integer.parseInt(parser.getAttributeValue(null, "m")); 22112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, true); 22122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.opModes == null) { 22132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes = new SparseIntArray(); 22142af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 22152af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.opModes.put(code, mode); 22162af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } else { 22172af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov Slog.w(TAG, "Unknown element under <uid-ops>: " 22182af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov + parser.getName()); 22192af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov XmlUtils.skipCurrentTag(parser); 22202af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 22212af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 22222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 22232af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 22240997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readPackage(XmlPullParser parser) throws NumberFormatException, 222535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 222635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String pkgName = parser.getAttributeValue(null, "n"); 222735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 222835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 222935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 223035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 223135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 223235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 223335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 223435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 223535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 223635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("uid")) { 22370997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readUid(parser, pkgName); 223835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 223935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 224035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 224135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 224235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 224335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 224435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 224535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 22460997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException, 224735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 224835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 22491c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk String isPrivilegedString = parser.getAttributeValue(null, "p"); 22501c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk boolean isPrivileged = false; 22511c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk if (isPrivilegedString == null) { 22521c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk try { 22531c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk IPackageManager packageManager = ActivityThread.getPackageManager(); 22541c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk if (packageManager != null) { 22551c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk ApplicationInfo appInfo = ActivityThread.getPackageManager() 22561c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk .getApplicationInfo(pkgName, 0, UserHandle.getUserId(uid)); 22571c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk if (appInfo != null) { 2258b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin isPrivileged = (appInfo.privateFlags 2259b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 22601c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 22611c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } else { 22621c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk // Could not load data, don't add to cache so it will be loaded later. 22631c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk return; 22641c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 22651c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } catch (RemoteException e) { 22661c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk Slog.w(TAG, "Could not contact PackageManager", e); 22671c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 22681c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } else { 22691c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk isPrivileged = Boolean.parseBoolean(isPrivilegedString); 22701c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 227135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 227235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 227335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 227435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 227535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 227635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 227735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 227835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 227935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 228035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("op")) { 22812af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = getUidStateLocked(uid, true); 22822af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.pkgOps == null) { 22832af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.pkgOps = new ArrayMap<>(); 228435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 22852af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 2286cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Op op = new Op(uidState, pkgName, 2287cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Integer.parseInt(parser.getAttributeValue(null, "n"))); 2288cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 2289cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int i = parser.getAttributeCount()-1; i >= 0; i--) { 2290cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final String name = parser.getAttributeName(i); 2291cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final String value = parser.getAttributeValue(i); 2292cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn switch (name) { 2293cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "m": 2294cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.mode = Integer.parseInt(value); 2295cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2296cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "d": 2297cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.duration = Integer.parseInt(value); 2298cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2299cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "pu": 2300cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.proxyUid = Integer.parseInt(value); 2301cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2302cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "pp": 2303cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.proxyPackageName = value; 2304cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2305cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tp": 2306cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_PERSISTENT] = Long.parseLong(value); 2307cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2308cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tt": 2309cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value); 2310cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2311cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tfs": 2312cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_FOREGROUND_SERVICE] 2313cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2314cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2315cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tf": 2316cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_FOREGROUND] = Long.parseLong(value); 2317cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2318cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tb": 2319cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_BACKGROUND] = Long.parseLong(value); 2320cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2321cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "tc": 2322cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_CACHED] = Long.parseLong(value); 2323cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2324cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rp": 2325cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_PERSISTENT] 2326cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2327cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2328cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rt": 2329cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value); 2330cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2331cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rfs": 2332cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND_SERVICE] 2333cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2334cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2335cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rf": 2336cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND] 2337cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2338cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2339cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rb": 2340cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_BACKGROUND] 2341cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2342cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2343cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "rc": 2344cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_CACHED] 2345cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn = Long.parseLong(value); 2346cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2347cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "t": 2348cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn // Backwards compat. 2349cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value); 2350cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2351cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn case "r": 2352cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn // Backwards compat. 2353cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value); 2354cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2355cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn default: 2356cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Slog.w(TAG, "Unknown attribute in 'op' tag: " + name); 2357cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2358cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2359cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2360cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 23612af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov Ops ops = uidState.pkgOps.get(pkgName); 236235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (ops == null) { 23632af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov ops = new Ops(pkgName, uidState, isPrivileged); 23642af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov uidState.pkgOps.put(pkgName, ops); 236535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 236635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops.put(op.op, op); 236735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 236835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 236935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 237035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 237135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 237235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 23732378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn UidState uidState = getUidStateLocked(uid, false); 23742378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState != null) { 237565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn uidState.evalForegroundOps(mOpModeWatchers); 23762378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 237735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 237835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 237935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void writeState() { 238035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 238135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileOutputStream stream; 238235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 238335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.startWrite(); 238435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 238535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state: " + e); 238635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 238735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 238835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 2389e17b445b6c813f6f9bc93a5e3811128a197ef50bDianne Hackborn List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); 2390e17b445b6c813f6f9bc93a5e3811128a197ef50bDianne Hackborn 239135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 239235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 23939e9e2e73c6ec7bece20268196dc89ad0c8bafad4Wojciech Staszkiewicz out.setOutput(stream, StandardCharsets.UTF_8.name()); 239435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startDocument(null, true); 23954d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn out.startTag(null, "app-ops"); 23963ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla out.attribute(null, "v", String.valueOf(CURRENT_VERSION)); 23972af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 23982af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int uidStateCount = mUidStates.size(); 23992af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i = 0; i < uidStateCount; i++) { 24002af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.valueAt(i); 24012af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (uidState.opModes != null && uidState.opModes.size() > 0) { 24022af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.startTag(null, "uid"); 24032af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.attribute(null, "n", Integer.toString(uidState.uid)); 24042af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov SparseIntArray uidOpModes = uidState.opModes; 24052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int opCount = uidOpModes.size(); 24062af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int j = 0; j < opCount; j++) { 24072af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int op = uidOpModes.keyAt(j); 24082af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int mode = uidOpModes.valueAt(j); 24092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.startTag(null, "op"); 24102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.attribute(null, "n", Integer.toString(op)); 24112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.attribute(null, "m", Integer.toString(mode)); 24122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.endTag(null, "op"); 24132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 24142af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov out.endTag(null, "uid"); 24152af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 24162af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 241735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 241835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allOps != null) { 241935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String lastPkg = null; 242035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<allOps.size(); i++) { 242135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps pkg = allOps.get(i); 242235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!pkg.getPackageName().equals(lastPkg)) { 242335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 242435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 242535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 242635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn lastPkg = pkg.getPackageName(); 242735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "pkg"); 242835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", lastPkg); 242935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 243035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "uid"); 243135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(pkg.getUid())); 24321c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk synchronized (this) { 2433a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), 2434a965d65cd382c381b5b83e460213174ac82ec2e0Yohei Yukawa false /* edit */, false /* uidMismatchExpected */); 24351c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk // Should always be present as the list of PackageOps is generated 24361c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk // from Ops. 24371c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk if (ops != null) { 24381c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk out.attribute(null, "p", Boolean.toString(ops.isPrivileged)); 24391c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } else { 24401c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk out.attribute(null, "p", Boolean.toString(false)); 24411c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 24421c7c319bb89b9988bfd12afc3e8d89449fd163fcJason Monk } 244335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.OpEntry> ops = pkg.getOps(); 244435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int j=0; j<ops.size(); j++) { 244535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.OpEntry op = ops.get(j); 244635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "op"); 244735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(op.getOp())); 2448f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) { 24495e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "m", Integer.toString(op.getMode())); 24505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 2451cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int k = 0; k < _NUM_UID_STATE; k++) { 24522378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final long time = op.getLastTimeFor(k); 2453cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (time != 0) { 2454cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn out.attribute(null, UID_STATE_TIME_ATTRS[k], 2455cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Long.toString(time)); 2456cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 24572378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final long rejectTime = op.getLastRejectTimeFor(k); 2458cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (rejectTime != 0) { 2459cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn out.attribute(null, UID_STATE_REJECT_ATTRS[k], 2460cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn Long.toString(rejectTime)); 2461cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 24625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 24635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int dur = op.getDuration(); 24645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != 0) { 24655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "d", Integer.toString(dur)); 24665e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 246799b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov int proxyUid = op.getProxyUid(); 246899b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov if (proxyUid != -1) { 246999b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov out.attribute(null, "pu", Integer.toString(proxyUid)); 247099b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov } 247199b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov String proxyPackageName = op.getProxyPackageName(); 247299b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov if (proxyPackageName != null) { 247399b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov out.attribute(null, "pp", proxyPackageName); 247499b6043dad9d215cf15810b885b6b8c215dd5b5aSvet Ganov } 247535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "op"); 247635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 247735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "uid"); 247835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 247935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 248035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 248135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 248235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 248335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 248435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "app-ops"); 248535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endDocument(); 248635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.finishWrite(stream); 248735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 248835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state, restoring backup.", e); 248935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.failWrite(stream); 249035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 249135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 249235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 249335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 2494268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn static class Shell extends ShellCommand { 2495268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn final IAppOpsService mInterface; 2496268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn final AppOpsService mInternal; 2497268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2498268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int userId = UserHandle.USER_SYSTEM; 2499268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn String packageName; 2500268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn String opStr; 2501e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn String modeStr; 2502268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int op; 2503e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn int mode; 2504268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int packageUid; 2505c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int nonpackageUid; 25066cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds final static Binder sBinder = new Binder(); 25076cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds IBinder mToken; 2508268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2509268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn Shell(IAppOpsService iface, AppOpsService internal) { 2510268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn mInterface = iface; 2511268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn mInternal = internal; 25126cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds try { 25136cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds mToken = mInterface.getToken(sBinder); 25146cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } catch (RemoteException e) { 25156cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 2516268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2517268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2518268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn @Override 2519268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn public int onCommand(String cmd) { 2520268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return onShellCommand(this, cmd); 2521268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2522268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2523268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn @Override 2524268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn public void onHelp() { 2525268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn PrintWriter pw = getOutPrintWriter(); 2526268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn dumpCommandHelp(pw); 2527268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2528268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 25292378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn static private int strOpToOp(String op, PrintWriter err) { 2530268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2531268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return AppOpsManager.strOpToOp(op); 2532268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } catch (IllegalArgumentException e) { 2533268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2534268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2535268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return Integer.parseInt(op); 2536268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } catch (NumberFormatException e) { 2537268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2538268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2539268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return AppOpsManager.strDebugOpToOp(op); 2540268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } catch (IllegalArgumentException e) { 2541268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn err.println("Error: " + e.getMessage()); 2542268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2543268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2544268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2545268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 254665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn static int strModeToMode(String modeStr, PrintWriter err) { 25472378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn for (int i = AppOpsManager.MODE_NAMES.length - 1; i >= 0; i--) { 25482378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (AppOpsManager.MODE_NAMES[i].equals(modeStr)) { 2549cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn return i; 2550cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2551e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2552e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn try { 2553e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return Integer.parseInt(modeStr); 2554e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } catch (NumberFormatException e) { 2555e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2556e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn err.println("Error: Mode " + modeStr + " is not valid"); 2557e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return -1; 2558e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2559e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn 2560e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn int parseUserOpMode(int defMode, PrintWriter err) throws RemoteException { 2561e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn userId = UserHandle.USER_CURRENT; 2562e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn opStr = null; 2563e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn modeStr = null; 2564e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn for (String argument; (argument = getNextArg()) != null;) { 2565e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if ("--user".equals(argument)) { 2566e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn userId = UserHandle.parseUserArg(getNextArgRequired()); 2567e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } else { 2568e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (opStr == null) { 2569e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn opStr = argument; 2570e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } else if (modeStr == null) { 2571e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn modeStr = argument; 2572e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn break; 2573e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2574e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2575e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2576e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (opStr == null) { 2577e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn err.println("Error: Operation not specified."); 2578e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return -1; 2579e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2580e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn op = strOpToOp(opStr, err); 2581e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (op < 0) { 2582e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return -1; 2583e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2584e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (modeStr != null) { 2585e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if ((mode=strModeToMode(modeStr, err)) < 0) { 2586e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return -1; 2587e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2588e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } else { 2589e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn mode = defMode; 2590e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2591e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return 0; 2592e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2593e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn 2594268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int parseUserPackageOp(boolean reqOp, PrintWriter err) throws RemoteException { 2595268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn userId = UserHandle.USER_CURRENT; 2596268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn packageName = null; 2597268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn opStr = null; 2598268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn for (String argument; (argument = getNextArg()) != null;) { 2599268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if ("--user".equals(argument)) { 2600268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn userId = UserHandle.parseUserArg(getNextArgRequired()); 2601268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2602268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (packageName == null) { 2603268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn packageName = argument; 2604268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else if (opStr == null) { 2605268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn opStr = argument; 2606268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn break; 2607268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2608268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2609268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2610268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (packageName == null) { 2611268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn err.println("Error: Package name not specified."); 2612268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2613268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else if (opStr == null && reqOp) { 2614268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn err.println("Error: Operation not specified."); 2615268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2616268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2617268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (opStr != null) { 2618268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn op = strOpToOp(opStr, err); 2619268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (op < 0) { 2620268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2621268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2622268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2623268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn op = AppOpsManager.OP_NONE; 2624268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2625268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (userId == UserHandle.USER_CURRENT) { 2626268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn userId = ActivityManager.getCurrentUser(); 2627268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2628c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn nonpackageUid = -1; 2629c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn try { 2630c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn nonpackageUid = Integer.parseInt(packageName); 2631c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } catch (NumberFormatException e) { 2632268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2633c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (nonpackageUid == -1 && packageName.length() > 1 && packageName.charAt(0) == 'u' 2634c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn && packageName.indexOf('.') < 0) { 2635c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int i = 1; 2636c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn while (i < packageName.length() && packageName.charAt(i) >= '0' 2637c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn && packageName.charAt(i) <= '9') { 2638c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn i++; 2639c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2640c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (i > 1 && i < packageName.length()) { 2641c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn String userStr = packageName.substring(1, i); 2642c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn try { 2643c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int user = Integer.parseInt(userStr); 2644c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn char type = packageName.charAt(i); 2645c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn i++; 2646c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int startTypeVal = i; 2647c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn while (i < packageName.length() && packageName.charAt(i) >= '0' 2648c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn && packageName.charAt(i) <= '9') { 2649c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn i++; 2650c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2651c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (i > startTypeVal) { 2652c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn String typeValStr = packageName.substring(startTypeVal, i); 2653c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn try { 2654c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn int typeVal = Integer.parseInt(typeValStr); 2655c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (type == 'a') { 2656c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn nonpackageUid = UserHandle.getUid(user, 2657c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn typeVal + Process.FIRST_APPLICATION_UID); 2658c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } else if (type == 's') { 2659c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn nonpackageUid = UserHandle.getUid(user, typeVal); 2660c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2661c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } catch (NumberFormatException e) { 2662c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2663c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2664c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } catch (NumberFormatException e) { 2665c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2666c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2667c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2668c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (nonpackageUid != -1) { 2669c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn packageName = null; 2670c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } else { 267182f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov packageUid = resolveUid(packageName); 267282f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov if (packageUid < 0) { 2673c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn packageUid = AppGlobals.getPackageManager().getPackageUid(packageName, 2674c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 2675c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2676c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (packageUid < 0) { 2677c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn err.println("Error: No UID for " + packageName + " in user " + userId); 2678c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn return -1; 2679c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2680268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2681268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2682268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2683268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2684268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2685268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, 2686354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn FileDescriptor err, String[] args, ShellCallback callback, 2687354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn ResultReceiver resultReceiver) { 2688354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn (new Shell(this, this)).exec(this, in, out, err, args, callback, resultReceiver); 2689268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2690268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2691268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn static void dumpCommandHelp(PrintWriter pw) { 2692268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("AppOps service (appops) commands:"); 2693268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" help"); 2694268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" Print this help text."); 26956cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds pw.println(" start [--user <USER_ID>] <PACKAGE | UID> <OP> "); 26966cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds pw.println(" Starts a given operation for a particular application."); 26976cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds pw.println(" stop [--user <USER_ID>] <PACKAGE | UID> <OP> "); 26986cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds pw.println(" Stops a given operation for a particular application."); 2699c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn pw.println(" set [--user <USER_ID>] <PACKAGE | UID> <OP> <MODE>"); 2700268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" Set the mode for a particular application and operation."); 2701c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn pw.println(" get [--user <USER_ID>] <PACKAGE | UID> [<OP>]"); 2702268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" Return the mode for a particular application and optional operation."); 2703e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn pw.println(" query-op [--user <USER_ID>] <OP> [<MODE>]"); 2704e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn pw.println(" Print all packages that currently have the given op in the given mode."); 2705268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" reset [--user <USER_ID>] [<PACKAGE>]"); 2706268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" Reset the given application or all applications to default modes."); 27074d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println(" write-settings"); 27084d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println(" Immediately write pending changes to storage."); 27094d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println(" read-settings"); 27104d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println(" Read the last written settings, replacing current state in RAM."); 2711268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" options:"); 2712268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" <PACKAGE> an Android package name."); 2713268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" <OP> an AppOps operation."); 2714268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" <MODE> one of allow, ignore, deny, or default"); 2715268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" <USER_ID> the user id under which the package is installed. If --user is not"); 2716268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(" specified, the current user is assumed."); 2717268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2718268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2719268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn static int onShellCommand(Shell shell, String cmd) { 2720268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (cmd == null) { 2721268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return shell.handleDefaultCommands(cmd); 2722268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2723268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn PrintWriter pw = shell.getOutPrintWriter(); 2724268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn PrintWriter err = shell.getErrPrintWriter(); 2725268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2726268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn switch (cmd) { 2727268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn case "set": { 2728268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int res = shell.parseUserPackageOp(true, err); 2729268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (res < 0) { 2730268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return res; 2731268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2732268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn String modeStr = shell.getNextArg(); 2733268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (modeStr == null) { 2734268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn err.println("Error: Mode not specified."); 2735268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2736268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2737268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2738e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn final int mode = shell.strModeToMode(modeStr, err); 2739e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (mode < 0) { 2740e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return -1; 2741268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2742268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2743c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (shell.packageName != null) { 2744c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.mInterface.setMode(shell.op, shell.packageUid, shell.packageName, 2745c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn mode); 2746c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } else { 2747c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.mInterface.setUidMode(shell.op, shell.nonpackageUid, mode); 2748c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2749268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2750268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2751268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn case "get": { 2752268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int res = shell.parseUserPackageOp(false, err); 2753268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (res < 0) { 2754268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return res; 2755268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2756268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2757c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn List<AppOpsManager.PackageOps> ops; 2758c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn if (shell.packageName != null) { 2759c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn ops = shell.mInterface.getOpsForPackage( 2760c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.packageUid, shell.packageName, 2761c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.op != AppOpsManager.OP_NONE ? new int[]{shell.op} : null); 2762c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } else { 2763c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn ops = shell.mInterface.getUidOps( 2764c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.nonpackageUid, 2765c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn shell.op != AppOpsManager.OP_NONE ? new int[]{shell.op} : null); 2766c7214a3ade62db082c89b933a51a0ddd9f57b49dDianne Hackborn } 2767268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (ops == null || ops.size() <= 0) { 2768268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("No operations."); 276982f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov if (shell.op > AppOpsManager.OP_NONE && shell.op < AppOpsManager._NUM_OP) { 27702378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println("Default mode: " + AppOpsManager.modeToName( 277182f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov AppOpsManager.opToDefaultMode(shell.op))); 277282f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } 2773268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2774268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2775268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn final long now = System.currentTimeMillis(); 2776268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn for (int i=0; i<ops.size(); i++) { 2777268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn List<AppOpsManager.OpEntry> entries = ops.get(i).getOps(); 2778268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn for (int j=0; j<entries.size(); j++) { 2779268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn AppOpsManager.OpEntry ent = entries.get(j); 2780268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(AppOpsManager.opToName(ent.getOp())); 2781268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(": "); 27822378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(AppOpsManager.modeToName(ent.getMode())); 2783268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (ent.getTime() != 0) { 2784268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("; time="); 2785268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn TimeUtils.formatDuration(now - ent.getTime(), pw); 2786268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(" ago"); 2787268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2788268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (ent.getRejectTime() != 0) { 2789268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("; rejectTime="); 2790268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn TimeUtils.formatDuration(now - ent.getRejectTime(), pw); 2791268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(" ago"); 2792268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2793268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (ent.getDuration() == -1) { 2794268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(" (running)"); 2795268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else if (ent.getDuration() != 0) { 2796268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("; duration="); 2797268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn TimeUtils.formatDuration(ent.getDuration(), pw); 2798268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2799268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println(); 2800268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2801e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2802e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return 0; 2803e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2804e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn case "query-op": { 2805e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn int res = shell.parseUserOpMode(AppOpsManager.MODE_IGNORED, err); 2806e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (res < 0) { 2807e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return res; 2808e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2809e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn List<AppOpsManager.PackageOps> ops = shell.mInterface.getPackagesForOps( 2810e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn new int[] {shell.op}); 2811e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (ops == null || ops.size() <= 0) { 2812e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn pw.println("No operations."); 2813e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn return 0; 2814e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2815e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn for (int i=0; i<ops.size(); i++) { 2816e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn final AppOpsManager.PackageOps pkg = ops.get(i); 2817e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn boolean hasMatch = false; 2818e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps(); 2819e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn for (int j=0; j<entries.size(); j++) { 2820e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn AppOpsManager.OpEntry ent = entries.get(j); 2821e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (ent.getOp() == shell.op && ent.getMode() == shell.mode) { 2822e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn hasMatch = true; 2823e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn break; 2824e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2825e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2826e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn if (hasMatch) { 2827e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn pw.println(pkg.getPackageName()); 2828e91f3e7e8d8aec8b880e6ed284a3889f849dfd91Dianne Hackborn } 2829268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2830268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2831268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2832268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn case "reset": { 2833268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn String packageName = null; 2834268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn int userId = UserHandle.USER_CURRENT; 2835268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn for (String argument; (argument = shell.getNextArg()) != null;) { 2836268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if ("--user".equals(argument)) { 2837268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn String userStr = shell.getNextArgRequired(); 2838268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn userId = UserHandle.parseUserArg(userStr); 2839268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2840268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (packageName == null) { 2841268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn packageName = argument; 2842268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2843268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn err.println("Error: Unsupported argument: " + argument); 2844268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2845268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2846268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2847268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2848268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2849268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (userId == UserHandle.USER_CURRENT) { 2850268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn userId = ActivityManager.getCurrentUser(); 2851268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2852268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2853268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn shell.mInterface.resetAllModes(userId, packageName); 2854268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("Reset all modes for: "); 2855268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (userId == UserHandle.USER_ALL) { 2856268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("all users"); 2857268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2858268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("user "); pw.print(userId); 2859268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2860268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print(", "); 2861268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn if (packageName == null) { 2862268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("all packages"); 2863268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } else { 2864268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.print("package "); pw.println(packageName); 2865268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2866268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2867268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2868268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn case "write-settings": { 2869d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn shell.mInternal.enforceManageAppOpsModes(Binder.getCallingPid(), 2870d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn Binder.getCallingUid(), -1); 2871268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn long token = Binder.clearCallingIdentity(); 2872268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2873268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn synchronized (shell.mInternal) { 2874268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn shell.mInternal.mHandler.removeCallbacks(shell.mInternal.mWriteRunner); 2875268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2876268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn shell.mInternal.writeState(); 2877268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("Current settings written."); 2878268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } finally { 2879268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn Binder.restoreCallingIdentity(token); 2880268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2881268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2882268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2883268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn case "read-settings": { 2884d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn shell.mInternal.enforceManageAppOpsModes(Binder.getCallingPid(), 2885d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn Binder.getCallingUid(), -1); 2886268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn long token = Binder.clearCallingIdentity(); 2887268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn try { 2888268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn shell.mInternal.readState(); 2889268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("Last settings read."); 2890268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } finally { 2891268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn Binder.restoreCallingIdentity(token); 2892268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2893268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return 0; 2894268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 28956cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds case "start": { 28966cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds int res = shell.parseUserPackageOp(true, err); 28976cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds if (res < 0) { 28986cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return res; 28996cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 29006cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds 29016cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds if (shell.packageName != null) { 29026cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds shell.mInterface.startOperation(shell.mToken, 29036cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds shell.op, shell.packageUid, shell.packageName, true); 29046cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } else { 29056cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return -1; 29066cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 29076cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return 0; 29086cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 29096cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds case "stop": { 29106cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds int res = shell.parseUserPackageOp(true, err); 29116cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds if (res < 0) { 29126cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return res; 29136cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 29146cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds 29156cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds if (shell.packageName != null) { 29166cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds shell.mInterface.finishOperation(shell.mToken, 29176cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds shell.op, shell.packageUid, shell.packageName); 29186cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } else { 29196cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return -1; 29206cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 29216cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds return 0; 29226cb5fcc40d9af1825e00e7b35207d58334159b7eJulia Reynolds } 2923268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn default: 2924268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return shell.handleDefaultCommands(cmd); 2925268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2926268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } catch (RemoteException e) { 2927268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("Remote exception: " + e); 2928268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2929268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn return -1; 2930268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn } 2931268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn 2932268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn private void dumpHelp(PrintWriter pw) { 2933268e4e3d00df6ea0eae6fca321e474a3d512fb7eDianne Hackborn pw.println("AppOps service (appops) dump options:"); 29342378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" -h"); 29352378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" Print this help text."); 29362378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" --op [OP]"); 29372378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" Limit output to data associated with the given app op code."); 293865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" --mode [MODE]"); 293965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" Limit output to data associated with the given app op mode."); 294065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" --package [PACKAGE]"); 294165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" Limit output to data associated with the given package name."); 29424d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } 29434d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn 2944cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn private void dumpTimesLocked(PrintWriter pw, String firstPrefix, String prefix, long[] times, 2945cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn long now, SimpleDateFormat sdf, Date date) { 2946cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn boolean hasTime = false; 2947cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int i = 0; i < _NUM_UID_STATE; i++) { 2948cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (times[i] != 0) { 2949cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn hasTime = true; 2950cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn break; 2951cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2952cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2953cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (!hasTime) { 2954cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn return; 2955cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2956cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn boolean first = true; 2957cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn for (int i = 0; i < _NUM_UID_STATE; i++) { 2958cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (times[i] != 0) { 2959cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(first ? firstPrefix : prefix); 2960cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn first = false; 2961cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(UID_STATE_NAMES[i]); 2962cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" = "); 2963cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn date.setTime(times[i]); 2964cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(sdf.format(date)); 2965cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" ("); 2966cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn TimeUtils.formatDuration(times[i]-now, pw); 2967cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(")"); 2968cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2969cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2970cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 2971cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn 2972a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 2973a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 29746df866a8510af2776c48425a361f708ae7f5d7d6Jeff Sharkey if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 2975a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 29762378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn int dumpOp = -1; 297765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn String dumpPackage = null; 297865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn int dumpUid = -1; 297965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn int dumpMode = -1; 29802378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 29814d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn if (args != null) { 29824d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn for (int i=0; i<args.length; i++) { 29834d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn String arg = args[i]; 29844d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn if ("-h".equals(arg)) { 29854d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn dumpHelp(pw); 29864d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn return; 29878f1ea834f9af5ccf6cea1f529f63e727cd13b6a8Tim Kilbourn } else if ("-a".equals(arg)) { 29888f1ea834f9af5ccf6cea1f529f63e727cd13b6a8Tim Kilbourn // dump all data 29892378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } else if ("--op".equals(arg)) { 29902378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn i++; 29912378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (i >= args.length) { 29922378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println("No argument for --op option"); 29932378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return; 29942378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 29952378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn dumpOp = Shell.strOpToOp(args[i], pw); 29962378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp < 0) { 29972378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn return; 29982378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 299965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } else if ("--package".equals(arg)) { 300065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn i++; 300165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (i >= args.length) { 300265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println("No argument for --package option"); 300365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return; 300465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 300565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn dumpPackage = args[i]; 300665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn try { 300765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn dumpUid = AppGlobals.getPackageManager().getPackageUid(dumpPackage, 300865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn PackageManager.MATCH_KNOWN_PACKAGES | PackageManager.MATCH_INSTANT, 300965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn 0); 301065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } catch (RemoteException e) { 301165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 301265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpUid < 0) { 301365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println("Unknown package: " + dumpPackage); 301465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return; 301565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 301665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn dumpUid = UserHandle.getAppId(dumpUid); 301765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } else if ("--mode".equals(arg)) { 301865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn i++; 301965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (i >= args.length) { 302065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println("No argument for --mode option"); 302165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return; 302265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 302365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn dumpMode = Shell.strModeToMode(args[i], pw); 302465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpMode < 0) { 302565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn return; 302665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 30274d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 30284d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println("Unknown option: " + arg); 30294d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn return; 30304d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } else { 30314d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn pw.println("Unknown command: " + arg); 30324d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn return; 30334d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } 30344d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } 30354d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn } 30364d34bb8304ae2e85c2b12628c9a6346c6835de5dDianne Hackborn 3037a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 3038a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Current AppOps Service state:"); 303965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn mConstants.dump(pw); 304065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(); 30415e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn final long now = System.currentTimeMillis(); 3042cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final long nowElapsed = SystemClock.elapsedRealtime(); 30432378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final long nowUptime = SystemClock.uptimeMillis(); 3044cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 3045cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn final Date date = new Date(); 3046e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn boolean needSep = false; 3047d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn if (dumpOp < 0 && dumpMode < 0 && dumpPackage == null && mProfileOwners != null) { 3048d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.println(" Profile owners:"); 3049d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn for (int poi = 0; poi < mProfileOwners.size(); poi++) { 3050d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.print(" User #"); 3051d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.print(mProfileOwners.keyAt(poi)); 3052d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.print(": "); 3053d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn UserHandle.formatUid(pw, mProfileOwners.valueAt(poi)); 3054d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.println(); 3055d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 3056d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn pw.println(); 3057d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 3058e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mOpModeWatchers.size() > 0) { 30592378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedHeader = false; 3060e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mOpModeWatchers.size(); i++) { 30612378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp >= 0 && dumpOp != mOpModeWatchers.keyAt(i)) { 30622378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 30632378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 306465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean printedOpHeader = false; 30652d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> callbacks = mOpModeWatchers.valueAt(i); 3066e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 306765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final ModeCallback cb = callbacks.valueAt(j); 306865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && cb.mWatchingUid >= 0 306965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && dumpUid != UserHandle.getAppId(cb.mWatchingUid)) { 307065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 307165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 307265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn needSep = true; 307365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!printedHeader) { 307465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" Op mode watchers:"); 307565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn printedHeader = true; 307665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 307765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!printedOpHeader) { 307865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(" Op "); 307965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i))); 308065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(":"); 308165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn printedOpHeader = true; 308265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 3083e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 308465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(cb); 3085e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3086e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3087e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 308865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (mPackageModeWatchers.size() > 0 && dumpOp < 0) { 308965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean printedHeader = false; 3090e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mPackageModeWatchers.size(); i++) { 309165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && !dumpPackage.equals(mPackageModeWatchers.keyAt(i))) { 309265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 309365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 309465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn needSep = true; 309565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!printedHeader) { 309665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" Package mode watchers:"); 309765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn printedHeader = true; 309865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 3099e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Pkg "); pw.print(mPackageModeWatchers.keyAt(i)); 3100e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 31012d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> callbacks = mPackageModeWatchers.valueAt(i); 3102e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 3103e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 310468d76555582ebd414158af9874f64bae3832540cDianne Hackborn pw.println(callbacks.valueAt(j)); 3105e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3106e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3107e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 31082378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (mModeWatchers.size() > 0 && dumpOp < 0) { 310965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean printedHeader = false; 3110e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mModeWatchers.size(); i++) { 311165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final ModeCallback cb = mModeWatchers.valueAt(i); 311265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && cb.mWatchingUid >= 0 311365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && dumpUid != UserHandle.getAppId(cb.mWatchingUid)) { 311465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 311565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 311665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn needSep = true; 311765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!printedHeader) { 311865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(" All op mode watchers:"); 311965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn printedHeader = true; 312065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 31213b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(" "); 31223b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(Integer.toHexString(System.identityHashCode(mModeWatchers.keyAt(i)))); 312365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(": "); pw.println(cb); 3124e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3125e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 312665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (mActiveWatchers.size() > 0 && dumpMode < 0) { 31272d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov needSep = true; 31282378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedHeader = false; 31292d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (int i = 0; i < mActiveWatchers.size(); i++) { 31302d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final SparseArray<ActiveCallback> activeWatchers = mActiveWatchers.valueAt(i); 31312d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (activeWatchers.size() <= 0) { 31322d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov continue; 31332d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 313465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final ActiveCallback cb = activeWatchers.valueAt(0); 31352378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp >= 0 && activeWatchers.indexOfKey(dumpOp) < 0) { 31362378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 31372378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 313865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && cb.mWatchingUid >= 0 313965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && dumpUid != UserHandle.getAppId(cb.mWatchingUid)) { 314065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 314165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 31422378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (!printedHeader) { 31432378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" All op active watchers:"); 31442378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn printedHeader = true; 31452378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 31463b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(" "); 31473b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(Integer.toHexString(System.identityHashCode( 31483b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn mActiveWatchers.keyAt(i)))); 31493b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.println(" ->"); 31503b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(" ["); 31512d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final int opCount = activeWatchers.size(); 31522d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov for (i = 0; i < opCount; i++) { 31532378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (i > 0) { 31542378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(' '); 31552378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 31562d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov pw.print(AppOpsManager.opToName(activeWatchers.keyAt(i))); 31572d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov if (i < opCount - 1) { 31582d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov pw.print(','); 31592d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 31602d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 31613b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.println("]"); 31623b563fcb998db1d8d5eaf9f8dbc12eec4a497ff3Dianne Hackborn pw.print(" "); 316365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(cb); 31642d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 31652d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov } 316665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (mClients.size() > 0 && dumpMode < 0) { 3167e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 31682378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedHeader = false; 3169e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mClients.size(); i++) { 31702378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedClient = false; 3171e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.valueAt(i); 3172f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (cs.mStartedOps.size() > 0) { 31732378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedStarted = false; 3174e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<cs.mStartedOps.size(); j++) { 3175e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = cs.mStartedOps.get(j); 31762378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp >= 0 && op.op != dumpOp) { 31772378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 31782378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 317965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && !dumpPackage.equals(op.packageName)) { 318065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 318165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 31822378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (!printedHeader) { 31832378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" Clients:"); 31842378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn printedHeader = true; 31852378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 31862378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (!printedClient) { 31872378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":"); 31882378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" "); pw.println(cs); 31892378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn printedClient = true; 31902378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 31912378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (!printedStarted) { 31922378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" Started ops:"); 31932378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn printedStarted = true; 31942378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3195e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print("uid="); pw.print(op.uid); 3196e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" pkg="); pw.print(op.packageName); 3197e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" op="); pw.println(AppOpsManager.opToName(op.op)); 3198e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3199e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3200e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 3201e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 320265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (mAudioRestrictions.size() > 0 && dumpOp < 0 && dumpPackage != null 320365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && dumpMode < 0) { 32041af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock boolean printedHeader = false; 32051af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock for (int o=0; o<mAudioRestrictions.size(); o++) { 32061af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final String op = AppOpsManager.opToName(mAudioRestrictions.keyAt(o)); 32071af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final SparseArray<Restriction> restrictions = mAudioRestrictions.valueAt(o); 32081af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock for (int i=0; i<restrictions.size(); i++) { 32091af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (!printedHeader){ 32101af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock pw.println(" Audio Restrictions:"); 32111af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock printedHeader = true; 32121af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock needSep = true; 32131af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 32147b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock final int usage = restrictions.keyAt(i); 32151af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock pw.print(" "); pw.print(op); 32167b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock pw.print(" usage="); pw.print(AudioAttributes.usageToString(usage)); 32171af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock Restriction r = restrictions.valueAt(i); 32182378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(": mode="); pw.println(AppOpsManager.modeToName(r.mode)); 32191af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (!r.exceptionPackages.isEmpty()) { 32201af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock pw.println(" Exceptions:"); 32211af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock for (int j=0; j<r.exceptionPackages.size(); j++) { 32221af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock pw.print(" "); pw.println(r.exceptionPackages.valueAt(j)); 32231af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 32241af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 32251af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 32261af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 32271af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 3228e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (needSep) { 3229e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(); 3230e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 32312af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int i=0; i<mUidStates.size(); i++) { 32322af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov UidState uidState = mUidStates.valueAt(i); 32332378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final SparseIntArray opModes = uidState.opModes; 32342378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn final ArrayMap<String, Ops> pkgOps = uidState.pkgOps; 32352378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn 323665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpOp >= 0 || dumpPackage != null || dumpMode >= 0) { 323765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean hasOp = dumpOp < 0 || (uidState.opModes != null 323865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn && uidState.opModes.indexOfKey(dumpOp) >= 0); 323965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean hasPackage = dumpPackage == null; 324065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn boolean hasMode = dumpMode < 0; 324165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!hasMode && opModes != null) { 324265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int opi = 0; !hasMode && opi < opModes.size(); opi++) { 324365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (opModes.valueAt(opi) == dumpMode) { 324465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasMode = true; 324565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 324665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 324765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 32482378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (pkgOps != null) { 324965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int pkgi = 0; 325065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn (!hasOp || !hasPackage || !hasMode) && pkgi < pkgOps.size(); 325165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pkgi++) { 32522378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn Ops ops = pkgOps.valueAt(pkgi); 325365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!hasOp && ops != null && ops.indexOfKey(dumpOp) >= 0) { 32542378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn hasOp = true; 32552378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 325665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!hasMode) { 325765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn for (int opi = 0; !hasMode && opi < ops.size(); opi++) { 325865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (ops.valueAt(opi).mode == dumpMode) { 325965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasMode = true; 326065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!hasPackage && dumpPackage.equals(ops.packageName)) { 326465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasPackage = true; 326565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 326865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (uidState.foregroundOps != null && !hasOp) { 326965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (uidState.foregroundOps.indexOfKey(dumpOp) > 0) { 327065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn hasOp = true; 32712378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 32722378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 327365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (!hasOp || !hasPackage || !hasMode) { 32742378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 32752378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 32762378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 32772af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 32782af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov pw.print(" Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":"); 3279cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" state="); 3280cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(UID_STATE_NAMES[uidState.state]); 32812378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState.state != uidState.pendingState) { 32822378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" pendingState="); 32832378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(UID_STATE_NAMES[uidState.pendingState]); 32842378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 32852378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (uidState.pendingStateCommitTime != 0) { 32862378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" pendingStateCommitTime="); 32872378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowUptime, pw); 32882378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(); 32892378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3290cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (uidState.startNesting != 0) { 3291cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" startNesting="); 3292cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(uidState.startNesting); 3293cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 329465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (uidState.foregroundOps != null && (dumpMode < 0 329565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn || dumpMode == AppOpsManager.MODE_FOREGROUND)) { 32962378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println(" foregroundOps:"); 32972378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn for (int j = 0; j < uidState.foregroundOps.size(); j++) { 329865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpOp >= 0 && dumpOp != uidState.foregroundOps.keyAt(j)) { 329965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 330065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 330165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(" "); 330265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(AppOpsManager.opToName(uidState.foregroundOps.keyAt(j))); 330365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(": "); 330465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(uidState.foregroundOps.valueAt(j) ? "WATCHER" : "SILENT"); 33052378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 330665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(" hasForegroundWatchers="); 330765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.println(uidState.hasForegroundWatchers); 33082378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 3309ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov needSep = true; 33102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 33112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (opModes != null) { 33122af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int opModeCount = opModes.size(); 33132af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov for (int j = 0; j < opModeCount; j++) { 33142af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int code = opModes.keyAt(j); 33152af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov final int mode = opModes.valueAt(j); 33162378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp >= 0 && dumpOp != code) { 33172378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 33182378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 331965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpMode >= 0 && dumpMode != mode) { 332065a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 332165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 33222af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov pw.print(" "); pw.print(AppOpsManager.opToName(code)); 33232378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(": mode="); pw.println(AppOpsManager.modeToName(mode)); 33242af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 33252af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 33262af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 33272af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov if (pkgOps == null) { 33282af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov continue; 33292af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 33302af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov 33312378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn for (int pkgi = 0; pkgi < pkgOps.size(); pkgi++) { 333265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final Ops ops = pkgOps.valueAt(pkgi); 333365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpPackage != null && !dumpPackage.equals(ops.packageName)) { 333465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 333565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 33362378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn boolean printedPackage = false; 3337a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int j=0; j<ops.size(); j++) { 333865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final Op op = ops.valueAt(j); 33392378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (dumpOp >= 0 && dumpOp != op.op) { 33402378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn continue; 33412378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 334265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (dumpMode >= 0 && dumpMode != op.mode) { 334365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn continue; 334465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 33452378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn if (!printedPackage) { 33462378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); 33472378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn printedPackage = true; 33482378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn } 33495e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" "); pw.print(AppOpsManager.opToName(op.op)); 33502378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.print(" ("); pw.print(AppOpsManager.modeToName(op.mode)); 335165a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final int switchOp = AppOpsManager.opToSwitch(op.op); 335265a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn if (switchOp != op.op) { 335365a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(" / switch "); 335465a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print(AppOpsManager.opToName(switchOp)); 335565a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn final Op switchObj = ops.get(switchOp); 335665a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn int mode = switchObj != null 335765a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn ? switchObj.mode : AppOpsManager.opToDefaultMode(switchOp); 335865a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn pw.print("="); pw.print(AppOpsManager.modeToName(mode)); 335965a4f251c7e14307f46911e376db49c8c7a1a8bbDianne Hackborn } 33602378a4a3faa989a51c1aea8a4dd325c9f0235a58Dianne Hackborn pw.println("): "); 3361cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn dumpTimesLocked(pw, 3362cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn " Access: ", 3363cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn " ", op.time, now, sdf, date); 3364cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn dumpTimesLocked(pw, 3365cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn " Reject: ", 3366cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn " ", op.rejectTime, now, sdf, date); 3367a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op.duration == -1) { 3368cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" Running start at: "); 3369cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn TimeUtils.formatDuration(nowElapsed-op.startRealtime, pw); 3370cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(); 33717b7c58b3842d47c4c8df4876e2e2248c58477d97Dianne Hackborn } else if (op.duration != 0) { 3372cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" duration="); 3373cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn TimeUtils.formatDuration(op.duration, pw); 3374cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(); 3375cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn } 3376cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn if (op.startNesting != 0) { 3377cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.print(" startNesting="); 3378cd1f30b4392ed7fdb50befa2f2190e1be4eada43Dianne Hackborn pw.println(op.startNesting); 3379a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3380a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3381a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3382a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3383ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (needSep) { 3384ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.println(); 3385ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3386ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov 3387ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov final int userRestrictionCount = mOpUserRestrictions.size(); 3388ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov for (int i = 0; i < userRestrictionCount; i++) { 3389ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov IBinder token = mOpUserRestrictions.keyAt(i); 3390ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i); 3391ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.println(" User restrictions for token " + token + ":"); 3392ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov 3393ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov final int restrictionCount = restrictionState.perUserRestrictions != null 3394ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov ? restrictionState.perUserRestrictions.size() : 0; 3395ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (restrictionCount > 0) { 3396ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.println(" Restricted ops:"); 3397ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov for (int j = 0; j < restrictionCount; j++) { 3398ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov int userId = restrictionState.perUserRestrictions.keyAt(j); 3399ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov boolean[] restrictedOps = restrictionState.perUserRestrictions.valueAt(j); 3400ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (restrictedOps == null) { 3401ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov continue; 3402ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3403ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov StringBuilder restrictedOpsValue = new StringBuilder(); 3404ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov restrictedOpsValue.append("["); 3405ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov final int restrictedOpCount = restrictedOps.length; 3406ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov for (int k = 0; k < restrictedOpCount; k++) { 3407ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (restrictedOps[k]) { 3408ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (restrictedOpsValue.length() > 1) { 3409ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov restrictedOpsValue.append(", "); 3410ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3411ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov restrictedOpsValue.append(AppOpsManager.opToName(k)); 3412ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3413ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3414ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov restrictedOpsValue.append("]"); 3415ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.print(" "); pw.print("user: "); pw.print(userId); 3416ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.print(" restricted ops: "); pw.println(restrictedOpsValue); 3417ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3418ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3419ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov 3420ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov final int excludedPackageCount = restrictionState.perUserExcludedPackages != null 3421ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov ? restrictionState.perUserExcludedPackages.size() : 0; 3422ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov if (excludedPackageCount > 0) { 3423ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.println(" Excluded packages:"); 3424ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov for (int j = 0; j < excludedPackageCount; j++) { 3425ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov int userId = restrictionState.perUserExcludedPackages.keyAt(j); 3426ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov String[] packageNames = restrictionState.perUserExcludedPackages.valueAt(j); 3427ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.print(" "); pw.print("user: "); pw.print(userId); 3428ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov pw.print(" packages: "); pw.println(Arrays.toString(packageNames)); 3429ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3430ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3431ee438d4a99eef0dc391f66698b0bf6129b0a6ce9Svet Ganov } 3432a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3433a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 34341af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 34351af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock private static final class Restriction { 34361af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock private static final ArraySet<String> NO_EXCEPTIONS = new ArraySet<String>(); 34371af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock int mode; 34381af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock ArraySet<String> exceptionPackages = NO_EXCEPTIONS; 34391af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 344062062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 344162062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk @Override 34429cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov public void setUserRestrictions(Bundle restrictions, IBinder token, int userHandle) { 344362062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk checkSystemUid("setUserRestrictions"); 3444f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov Preconditions.checkNotNull(restrictions); 34459cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov Preconditions.checkNotNull(token); 3446a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov for (int i = 0; i < AppOpsManager._NUM_OP; i++) { 344762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk String restriction = AppOpsManager.opToRestriction(i); 344864e0dcb989f27fc9246f3b2f40accd261f574d7eSuprabh Shukla if (restriction != null) { 344964e0dcb989f27fc9246f3b2f40accd261f574d7eSuprabh Shukla setUserRestrictionNoCheck(i, restrictions.getBoolean(restriction, false), token, 345064e0dcb989f27fc9246f3b2f40accd261f574d7eSuprabh Shukla userHandle, null); 3451a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 34529cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 34539cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 34549cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov 34559cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov @Override 345629931bc684bde6b430923122777684178ee2681cRuben Brunk public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, 345729931bc684bde6b430923122777684178ee2681cRuben Brunk String[] exceptionPackages) { 34589cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov if (Binder.getCallingPid() != Process.myPid()) { 34599cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS, 34609cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov Binder.getCallingPid(), Binder.getCallingUid(), null); 34619cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 34629cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov if (userHandle != UserHandle.getCallingUserId()) { 34639cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov if (mContext.checkCallingOrSelfPermission(Manifest.permission 34649cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov .INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED 34659cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov && mContext.checkCallingOrSelfPermission(Manifest.permission 34669cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov .INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) { 34679cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov throw new SecurityException("Need INTERACT_ACROSS_USERS_FULL or" 34689cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov + " INTERACT_ACROSS_USERS to interact cross user "); 346962062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 347062062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 34719cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov verifyIncomingOp(code); 34729cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov Preconditions.checkNotNull(token); 347329931bc684bde6b430923122777684178ee2681cRuben Brunk setUserRestrictionNoCheck(code, restricted, token, userHandle, exceptionPackages); 34749cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 34759cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov 34769cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token, 347729931bc684bde6b430923122777684178ee2681cRuben Brunk int userHandle, String[] exceptionPackages) { 3478442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov synchronized (AppOpsService.this) { 3479442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov ClientRestrictionState restrictionState = mOpUserRestrictions.get(token); 3480442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov 3481442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (restrictionState == null) { 3482442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov try { 3483442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov restrictionState = new ClientRestrictionState(token); 3484442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov } catch (RemoteException e) { 3485442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov return; 3486442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov } 3487442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov mOpUserRestrictions.put(token, restrictionState); 348829931bc684bde6b430923122777684178ee2681cRuben Brunk } 348929931bc684bde6b430923122777684178ee2681cRuben Brunk 3490442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (restrictionState.setRestriction(code, restricted, exceptionPackages, userHandle)) { 34912d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov mHandler.sendMessage(PooledLambda.obtainMessage( 34923a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov AppOpsService::notifyWatchersOfChange, this, code, UID_ANY)); 3493442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov } 3494442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov 3495442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov if (restrictionState.isDefault()) { 3496442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov mOpUserRestrictions.remove(token); 3497442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov restrictionState.destroy(); 3498442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov } 34999cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 3500bb21c25b3f927eeb1a1e56fa3023093f0d74204cJulia Reynolds } 3501bb21c25b3f927eeb1a1e56fa3023093f0d74204cJulia Reynolds 35023a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov private void notifyWatchersOfChange(int code, int uid) { 35032d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final ArraySet<ModeCallback> clonedCallbacks; 35049cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov synchronized (this) { 35052d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); 35069cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov if (callbacks == null) { 35079cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov return; 35089cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 350968d76555582ebd414158af9874f64bae3832540cDianne Hackborn clonedCallbacks = new ArraySet<>(callbacks); 35109cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 35119cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov 35123a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov notifyOpChanged(clonedCallbacks, code, uid, null); 351362062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 351462062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 351562062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk @Override 351662062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk public void removeUser(int userHandle) throws RemoteException { 351762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk checkSystemUid("removeUser"); 3518442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov synchronized (AppOpsService.this) { 3519442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov final int tokenCount = mOpUserRestrictions.size(); 3520442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov for (int i = tokenCount - 1; i >= 0; i--) { 3521442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov ClientRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i); 3522442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov opRestrictions.removeUser(userHandle); 3523442ed57e4b68e0904813b22ab6bb4c55e56bb984Svet Ganov } 3524bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka removeUidsForUserLocked(userHandle); 3525bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka } 3526bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka } 3527bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka 352835e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey @Override 352935e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey public boolean isOperationActive(int code, int uid, String packageName) { 3530f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (Binder.getCallingUid() != uid) { 3531f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS) 3532f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov != PackageManager.PERMISSION_GRANTED) { 3533f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov return false; 3534f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov } 3535f7b4725375dfb5f6b65433f1679c44501c2478e3Svet Ganov } 353635e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey verifyIncomingOp(code); 35372d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov final String resolvedPackageName = resolvePackageName(uid, packageName); 353835e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey if (resolvedPackageName == null) { 353935e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey return false; 354035e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey } 35412d20fb47f4a7162450f993728876c74762b93112Svetoslav Ganov synchronized (AppOpsService.this) { 354235e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey for (int i = mClients.size() - 1; i >= 0; i--) { 354335e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey final ClientState client = mClients.valueAt(i); 354435e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey for (int j = client.mStartedOps.size() - 1; j >= 0; j--) { 354535e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey final Op op = client.mStartedOps.get(j); 354635e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey if (op.op == code && op.uid == uid) return true; 354735e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey } 354835e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey } 354935e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey } 355035e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey return false; 355135e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey } 355235e46d297255363a20ccde62af3c58c4ce3c13c5Jeff Sharkey 3553bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka private void removeUidsForUserLocked(int userHandle) { 3554bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka for (int i = mUidStates.size() - 1; i >= 0; --i) { 3555bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka final int uid = mUidStates.keyAt(i); 3556bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka if (UserHandle.getUserId(uid) == userHandle) { 3557bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka mUidStates.removeAt(i); 3558bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka } 35599cea80cdddbecadb304eb7c8373cf1ed397f433aSvet Ganov } 356062062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 356162062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 356262062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk private void checkSystemUid(String function) { 356362062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk int uid = Binder.getCallingUid(); 356462062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk if (uid != Process.SYSTEM_UID) { 356562062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk throw new SecurityException(function + " must by called by the system"); 356662062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 356762062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk } 356862062996dd256df8b575b2ba1f0bf97109c4e0baJason Monk 3569f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov private static String resolvePackageName(int uid, String packageName) { 357082f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov if (uid == Process.ROOT_UID) { 3571f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return "root"; 3572f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } else if (uid == Process.SHELL_UID) { 3573f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return "com.android.shell"; 357482f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } else if (uid == Process.MEDIA_UID) { 357582f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return "media"; 357682f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } else if (uid == Process.AUDIOSERVER_UID) { 357782f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return "audioserver"; 357882f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } else if (uid == Process.CAMERASERVER_UID) { 357982f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return "cameraserver"; 3580f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } else if (uid == Process.SYSTEM_UID && packageName == null) { 3581f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return "android"; 3582f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 3583f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov return packageName; 3584f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov } 3585f73adb6c7249a1655bcd2ec17760ec754502f59dSvetoslav Ganov 358682f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov private static int resolveUid(String packageName) { 358782f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov if (packageName == null) { 358882f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return -1; 358982f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } 359082f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov switch (packageName) { 359182f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov case "root": 359282f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return Process.ROOT_UID; 359382f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov case "shell": 359482f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return Process.SHELL_UID; 359582f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov case "media": 359682f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return Process.MEDIA_UID; 359782f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov case "audioserver": 359882f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return Process.AUDIOSERVER_UID; 359982f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov case "cameraserver": 360082f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return Process.CAMERASERVER_UID; 360182f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } 360282f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov return -1; 360382f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov } 360482f09bcf93cc2e0f9a363f40bf8a64bcaa6d8b9fSvet Ganov 36052af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov private static String[] getPackagesForUid(int uid) { 3606f3807aa57267117eba83cc2a3b13add59d4a251aSvet Ganov String[] packageNames = null; 36072af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov try { 360840b300fd80708fd100d22f22ff6100db20ee467friddle_hsu packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid); 36092af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } catch (RemoteException e) { 36102af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov /* ignore - local call */ 36112af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3612f3807aa57267117eba83cc2a3b13add59d4a251aSvet Ganov if (packageNames == null) { 3613f3807aa57267117eba83cc2a3b13add59d4a251aSvet Ganov return EmptyArray.STRING; 3614f3807aa57267117eba83cc2a3b13add59d4a251aSvet Ganov } 3615f3807aa57267117eba83cc2a3b13add59d4a251aSvet Ganov return packageNames; 36162af5708ab0e55fe68f1810cefdc6e3889233c186Svet Ganov } 3617a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3618a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov private final class ClientRestrictionState implements DeathRecipient { 3619a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov private final IBinder token; 3620a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov SparseArray<boolean[]> perUserRestrictions; 3621a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov SparseArray<String[]> perUserExcludedPackages; 3622a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3623a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public ClientRestrictionState(IBinder token) 3624a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov throws RemoteException { 3625a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov token.linkToDeath(this, 0); 3626a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov this.token = token; 3627a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3628a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3629a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public boolean setRestriction(int code, boolean restricted, 3630a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov String[] excludedPackages, int userId) { 3631a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov boolean changed = false; 3632a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3633a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserRestrictions == null && restricted) { 3634a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov perUserRestrictions = new SparseArray<>(); 3635a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3636a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3637e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann int[] users; 3638e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (userId == UserHandle.USER_ALL) { 3639e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann List<UserInfo> liveUsers = UserManager.get(mContext).getUsers(false); 3640e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 3641e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann users = new int[liveUsers.size()]; 3642e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann for (int i = 0; i < liveUsers.size(); i++) { 3643e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann users[i] = liveUsers.get(i).id; 3644a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3645e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } else { 3646e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann users = new int[]{userId}; 3647e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3648a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3649e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (perUserRestrictions != null) { 3650e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann int numUsers = users.length; 3651e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 3652e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann for (int i = 0; i < numUsers; i++) { 3653e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann int thisUserId = users[i]; 3654e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 3655e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann boolean[] userRestrictions = perUserRestrictions.get(thisUserId); 3656e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (userRestrictions == null && restricted) { 3657e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann userRestrictions = new boolean[AppOpsManager._NUM_OP]; 3658e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserRestrictions.put(thisUserId, userRestrictions); 3659a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3660e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (userRestrictions != null && userRestrictions[code] != restricted) { 3661e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann userRestrictions[code] = restricted; 3662e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (!restricted && isDefault(userRestrictions)) { 3663e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserRestrictions.remove(thisUserId); 3664e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann userRestrictions = null; 3665a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3666a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov changed = true; 3667a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3668e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann 3669e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (userRestrictions != null) { 3670e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackages); 3671e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (perUserExcludedPackages == null && !noExcludedPackages) { 3672e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserExcludedPackages = new SparseArray<>(); 3673e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3674e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (perUserExcludedPackages != null && !Arrays.equals(excludedPackages, 3675e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserExcludedPackages.get(thisUserId))) { 3676e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (noExcludedPackages) { 3677e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserExcludedPackages.remove(thisUserId); 3678e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann if (perUserExcludedPackages.size() <= 0) { 3679e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserExcludedPackages = null; 3680e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3681e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } else { 3682e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann perUserExcludedPackages.put(thisUserId, excludedPackages); 3683e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3684e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann changed = true; 3685e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3686e683f19c4939ce683c7a7d6fe4286b16e372324fPhilip P. Moltmann } 3687a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3688a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3689a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3690a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return changed; 3691a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3692a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3693a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public boolean hasRestriction(int restriction, String packageName, int userId) { 3694a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserRestrictions == null) { 3695a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return false; 3696a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3697a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov boolean[] restrictions = perUserRestrictions.get(userId); 3698a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (restrictions == null) { 3699a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return false; 3700a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3701a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (!restrictions[restriction]) { 3702a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return false; 3703a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3704a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserExcludedPackages == null) { 3705a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return true; 3706a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3707a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov String[] perUserExclusions = perUserExcludedPackages.get(userId); 3708a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserExclusions == null) { 3709a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return true; 3710a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3711a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return !ArrayUtils.contains(perUserExclusions, packageName); 3712a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3713a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3714a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public void removeUser(int userId) { 3715a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserExcludedPackages != null) { 3716a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov perUserExcludedPackages.remove(userId); 3717a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserExcludedPackages.size() <= 0) { 3718a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov perUserExcludedPackages = null; 3719a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3720a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3721bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka if (perUserRestrictions != null) { 3722bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka perUserRestrictions.remove(userId); 3723bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka if (perUserRestrictions.size() <= 0) { 3724bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka perUserRestrictions = null; 3725bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka } 3726bc2fadd080d1f190a51184a538f4a0990c1c1cceSudheer Shanka } 3727a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3728a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3729a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public boolean isDefault() { 3730a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return perUserRestrictions == null || perUserRestrictions.size() <= 0; 3731a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3732a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3733a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov @Override 3734a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public void binderDied() { 3735a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov synchronized (AppOpsService.this) { 3736a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov mOpUserRestrictions.remove(token); 3737a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (perUserRestrictions == null) { 3738a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return; 3739a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3740a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov final int userCount = perUserRestrictions.size(); 3741a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov for (int i = 0; i < userCount; i++) { 3742a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov final boolean[] restrictions = perUserRestrictions.valueAt(i); 3743a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov final int restrictionCount = restrictions.length; 3744a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov for (int j = 0; j < restrictionCount; j++) { 3745a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (restrictions[j]) { 3746a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov final int changedCode = j; 37473a95f837f32ce4a18f922b7a6409a66b480e2f9cSvet Ganov mHandler.post(() -> notifyWatchersOfChange(changedCode, UID_ANY)); 3748a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3749a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3750a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3751a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov destroy(); 3752a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3753a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3754a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3755a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov public void destroy() { 3756a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov token.unlinkToDeath(this, 0); 3757a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3758a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov 3759a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov private boolean isDefault(boolean[] array) { 3760a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (ArrayUtils.isEmpty(array)) { 3761a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return true; 3762a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3763a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov for (boolean value : array) { 3764a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov if (value) { 3765a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return false; 3766a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3767a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3768a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov return true; 3769a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3770a8bbd76d9b5249c64ef31aa162e9a84abaad39baSvetoslav Ganov } 3771d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn 3772d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal { 3773d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn @Override public void setDeviceAndProfileOwners(SparseIntArray owners) { 3774d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn synchronized (AppOpsService.this) { 3775d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn mProfileOwners = owners; 3776d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 3777d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 3778d52544183e2532f22cee33df582bc7bece400837Dianne Hackborn } 3779a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn} 3780