Audit access to data | Android Developers
source link: https://developer.android.com/guide/topics/data/audit-access
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Audit access to databookmark_border
You can gain insights into how your app and its dependencies access private data
from users by performing data access auditing. This process, available on
devices that run Android 11 (API level 30) and higher, allows you to better
identify potentially unexpected data access. Your app can register an instance
of AppOpsManager.OnOpNotedCallback
, which can perform
actions each time one of the following events occurs:
- Your app's code accesses private data. To help you determine which logical part of your app invoked the event, you can audit data access by attribution tag.
- Code in a dependent library or SDK accesses private data.
Data access auditing is invoked on the thread where the data request takes
place. This means that, if a 3rd-party SDK or library in your app calls an API
that accesses private data, data access auditing allows your
OnOpNotedCallback
to examine information about the call. Usually, this
callback object can tell whether the call came from your app or the SDK by
looking at the app's current status, such as the current thread's stack trace.
Log access of data
To perform data access auditing using an instance of
AppOpsManager.OnOpNotedCallback
, implement the callback logic in the component
where you intend to audit data access, such as within an activity's onCreate()
method.
Application
, and define
AppOpsManager.OnOpNotedCallback
in the onCreate()
method of your subclass.The following code snippet defines an AppOpsManager.OnOpNotedCallback
for
auditing data access within a single activity:
override fun onCreate(savedInstanceState: Bundle?) {
val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() {
private fun logPrivateDataAccess(opCode: String, trace: String) {
Log.i(MY_APP_TAG, "Private data accessed. " +
"Operation: $opCode\nStack Trace:\n$trace")
}
override fun onNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(
syncNotedAppOp.op, Throwable().stackTrace.toString())
}
override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(
syncNotedAppOp.op, Throwable().stackTrace.toString())
}
override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) {
logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.message)
}
}
val appOpsManager =
getSystemService(AppOpsManager::class.java) as AppOpsManager
appOpsManager.setOnOpNotedCallback(mainExecutor, appOpsCallback)
}
The onAsyncNoted()
and onSelfNoted()
methods are called in specific
situations:
onAsyncNoted()
is called if the data access doesn't happen during your app's API call. The most common example is when your app registers a listener and the data access happens each time the listener's callback is invoked.The
AsyncNotedOp
argument that's passed intoonAsyncNoted()
contains a method calledgetMessage()
. This method provides more information about the data access. In the case of the location callbacks, the message contains the system-identity-hash of the listener.onSelfNoted()
is called in the very rare case when an app passes its own UID intonoteOp()
.
Audit data access by attribution tag
Your app might have several primary use cases, such as allowing users to capture
photos and share these photos with their contacts. If you develop such a
multi-purpose app, you can apply an attribution tag to each part of your app
when you audit its data access. The attributionTag
context is returned back
in the objects passed to the calls to onNoted()
.
This helps you more easily trace data access back to logical parts of your
code.
To define attribution tags in your app, complete the steps in the following sections.
Create attribution tags
In the
onCreate()
method of the activity where you access data, such as the activity where you
request location or access the user's list of contacts, call
createAttributionContext()
,
passing in the attribution tag that you wish to associate with a part of your
app.
The following code snippet demonstrates how to create an attribution tag for a "photo location sharing" part of an app:
class SharePhotoLocationActivity : AppCompatActivity() {
lateinit var attributionContext: Context
override fun onCreate(savedInstanceState: Bundle?) {
attributionContext = createAttributionContext("sharePhotos")
}
fun getLocation() {
val locationManager = attributionContext.getSystemService(
LocationManager::class.java) as LocationManager
// Use "locationManager" to access device location information.
}
}
Include attribution tags in access logs
Update your AppOpsManager.OnOpNotedCallback
callback so that your app's logs
include the names of the attribution tags that you've defined.
null
, this means that
the current Context
object is
associated with the main part of your app.The following code snippet shows updated logic that logs attribution tags:
val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() {
private fun logPrivateDataAccess(
opCode: String, attributionTag: String, trace: String) {
Log.i(MY_APP_TAG, "Private data accessed. " +
"Operation: $opCode\n " +
"Attribution Tag:$attributionTag\nStack Trace:\n$trace")
}
override fun onNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(syncNotedAppOp.op,
syncNotedAppOp.attributionTag,
Throwable().stackTrace.toString())
}
override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(syncNotedAppOp.op,
syncNotedAppOp.attributionTag,
Throwable().stackTrace.toString())
}
override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) {
logPrivateDataAccess(asyncNotedAppOp.op,
asyncNotedAppOp.attributionTag,
asyncNotedAppOp.message)
}
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK