Allow apps to collect which appops were noted
If private user data is send to an app the data provider should note an app-op. This change adds a new API AppOpsManager#setNotedAppOpsCollector that allows an app to get notified every time such an private data access happens. This will allow apps to monitor their own private data usage. Esp. with big, old apps, distributed teams or 3rd party libraries it might not always be clear what subsystems access private data. There are three different situations how private data can be accessed and an app op is noted: 1. Private data access inside a two-way binder call. E.g. LocationManager#getLastKnownLocation. When we start a two way binder transaction, we remember the calling uid via AppOpsManager#collectNotedAppOps. Then when the data providing code calls AppOpsManager#noteOp->AppOpsManager#markAppOpNoted the noted app-op is remembered in AppOpsManager#sAppOpsNotedInThisBinderTransaction. Then when returning from the binder call, we add the list of noted app-ops to the reply-parcel via AppOpsManager#prefixParcelWithAppOpsIfNeeded. On the calling side we check if there were any app-ops noted in AppOpsManager#readAndLogNotedAppops and then call the collector while still in the binder code. This allows the collector e.g. collect a stack trace which can be used to figure out what app code caused the private data access. 2. Very complex apps might do permissions checks internal to themself. I.e. an app notes an op for itself. We detect this case in AppOpsManager#markAppOpNoted and immediately call the collector similar to case (1). 3. Sometimes private data is accessed outside of a two-way binder call. E.g. if an app registers a LocationListener an app-op is noted each time a new location is send to the app. In this case it is not clear to the framework which app-action triggered this app-op-note. Hence the data provider has to describe in a AsyncNotedAppOp object when an why the access happened. These objects are then send to the system server via IAppOpsService#noteAsyncOp and then the collector in the app. There are rare cases where a private data access happens before the app is running (e.g. when a geo-fence is triggered). In this case we cache a small amount of AsyncNotedAppOps (in AppOpsService#mUnforwardedAsyncNotedOps) and deliver them when the app is ready for these events (in AppOpsManager#setNotedAppOpsCollector). Test: atest CtsAppOpsTestCases (includes new tests covering this functionality) Bug: 136505050 Change-Id: I96ded4a8d8d9bcb37a4555d9b1281cb57945ffa9
Loading
Please register or sign in to comment