The privacy timeline
Android's privacy model changed from a single install-time gate to a per-capability, per-duration, per-accuracy negotiation. Each release removed a specific capability that apps had been abusing.
Privacy on Android was not designed once. It was negotiated, release by release, against the specific things apps had started doing. That history explains why the permission model is so uneven: it is an accumulation, not a plan.
TL;DR#
- 2008–2015: permissions are granted at install. One screen, all or nothing.
- 2015 (6.0): runtime permissions. Dangerous permissions are requested in context and can be denied.
- 2019 (10): scoped storage, separate background location, and restrictions on non-resettable identifiers.
- 2020 (11): one-time permissions and permission auto-reset — consent gains a duration.
- 2021 (12): Privacy Dashboard, mic/camera indicators and toggles, approximate location, clipboard toast.
- 2022–2024: granular media permissions and the Photo Picker (13), selected photos (14), Private Space (15).
- The trend: from what the app may access to how much, how often, and for how long.
Mental model#
Think of a building where the front desk used to hand out a master key at check-in.
For years, checking in meant receiving keys to every room you had plausibly claimed a need for. The desk did not check back, and the key worked forever.
Then the building installed per-door locks (runtime permissions): you ask at the door, the door can refuse, and the refusal is total. Then it added time-limited keys (one-time permissions): the key stops working when you leave the floor. Then it added partial keys (approximate location, selected photos): the key opens the room but not the filing cabinet. Then it added a log of every door that opened (Privacy Dashboard, data access auditing).
The resident can now see the logs, and the locks are on more doors than before.
Where the analogy breaks#
A building has one locksmith. Android has a permission system, an app ops layer beneath it, and a set of per-subsystem policies in between — media, location, notifications, background. A single capability can be gated by more than one of them, and they do not always agree. That layering is the subject of App Ops.
The big picture#
Text description of this diagram
A five-lane timeline from 2013 to 2026: permission model, identifiers, location, storage and media, and user visibility. Events include install-time permissions and App Ops existing as an internal control in 2013; runtime permissions in 2015; ANDROID_ID scoped per app and signer in 2017; IMEI restrictions, scoped storage and separated background location in 2019; one-time permissions and auto-reset in 2020; the Privacy Dashboard, mic and camera indicators, approximate location and clipboard toast in 2021; granular media permissions, the notification permission and the Photo Picker in 2022; selected photos in 2023; Private Space in 2024; and the local network permission in 2026. A replay panel below shows a hypothetical 2013 flashlight app requesting camera, contacts, fine location, storage and phone state, and what each of those requests yields at each API level.
The replay panel is the useful part. Pick API 19 and then API 34 and watch the same five requests produce completely different answers.
Deep dive#
Install-time permissions (API 1–22)#
The original model is the simplest possible: an app declares permissions in its manifest, and installing the app grants all of them. The user sees one screen and can accept or refuse the whole package.
Two properties follow:
- The user cannot use the app and withhold one permission. It is all or nothing.
- Apps learn nothing from the grant, because there is no per-permission decision to observe.
The result was predictable. Apps requested everything they might ever need, because the marginal cost of another permission was one more line in a list nobody read.1
Two things were happening underneath. First, the protection level of a permission
(normal, dangerous, signature) determined whether the user saw it at all. Second, App Ops
already existed as an internal, per-operation control that the user could not see. The modern
privacy model is, in a sense, App Ops becoming visible.2
Runtime permissions (API 23, Android 6.0)#
Android 6.0 split permissions into install-time (normal) and runtime (dangerous). The runtime
dialog is owned by the system, so an app cannot fake or restyle it, and the user can deny.
The three-state answer matters more than most people realise:
- Granted — the permission works.
- Denied — the app may ask again.
- Denied with "don't ask again" — subsequent requests are ignored silently, and the app must detect this and send the user to Settings.
Android 8.0 and 9: tightening the data#
The privacy story of these releases is less about dialogs and more about what data an app could reach at all.
- Android 8.0:
ANDROID_IDbecomes scoped to the app-signing key, breaking its use as a device-wide identifier. - Android 9: background access to sensors and location is throttled; non-SDK interface restrictions begin to close private APIs that apps used to read.3
- Android 10: IMEI and serial numbers require a privileged permission,
ANDROID_IDis further scoped, and MAC address randomisation becomes standard.4
The identifier story is its own page, because it is the clearest example of Android removing a capability rather than asking about it.
Android 10 and 11: scoped storage and consent with a duration#
Scoped storage (10, enforced for all apps in 11) removed direct filesystem access to shared storage. An app can reach its own directory, the MediaStore collections it has permission for, and files the user hands it through the Storage Access Framework. Everything else is gone.4
Background location became a separate grant in 10, and in 11 it became a separate request the user could refuse independently.
One-time permissions (11) added a duration to consent: camera, microphone and location can be granted for a single session, expiring when the app leaves the foreground. Permission auto-reset (11) revokes permissions from apps that have not been used for a few months.5
Android 12: making the invisible visible#
Android 12's contribution was not new restrictions. It was visibility.
- Privacy Dashboard: a screen showing which apps used camera, microphone and location, and when.
- Indicators: a dot in the status bar while the camera or microphone is in use.
- Toggles: system-wide switches that disable the camera or microphone entirely.
- Approximate location: the user can grant coarse location only.
- Clipboard toast: reading the clipboard shows a toast.6
The design logic is that many users do not want to configure permissions; they want to notice misuse. Indicators and a dashboard serve that better than another dialog.
The platform side of this is data access auditing: apps can register an AppOpsManager
callback and be told when their own accesses are recorded. That is the same data the Dashboard
reads.7
Android 13 and 14: granular data, partial access#
- Granular media permissions:
READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIOreplace the blanket storage read. - Photo Picker: the user hands over specific items without granting library access at all.
- Notification permission:
POST_NOTIFICATIONSbecomes a runtime permission. - Selected photos (14):
READ_MEDIA_VISUAL_USER_SELECTEDmakes partial media access a persistent state rather than a one-off handoff.89
Android 15 and beyond: profiles and local networks#
Private Space (15) adds a separately locked profile whose apps and data are hidden from the main user. For app developers the impact is indirect but real: the number of profiles is no longer something to assume, and package visibility across profiles is filtered.10
Android 17 adds ACCESS_LOCAL_NETWORK as a runtime permission for local network access, and
delays SMS OTP delivery for apps that are not the intended recipient. Both follow the same pattern:
a capability that used to be ambient becomes a grant.11
The shape of the curve#
Plot the releases by how much they changed for a typical app and the curve is not smooth. It is a long flat period followed by a staircase.
- 2008–2014: almost nothing changes. Install-time permissions are stable for six years.
- 2015–2017: one big change (runtime permissions) followed by consolidation.
- 2018–2021: four years of continuous tightening — identifiers, storage, location, visibility.
- 2022–2026: smaller, more targeted changes, often behind a flag or a Mainline module.
The staircase pattern is what you would expect from a platform that cannot break existing apps: a big change, then a period of adaptation, then the next big change. The Mainline module structure at the end of the period is the mechanism that makes the later steps smaller and faster.
The permission corpus, by API level#
The shape of the permission model is visible in the data. There are 43 dangerous permissions in the current corpus, and their distribution over time tells the story better than a list of features: seventeen arrived with Android 1.0, then a slow trickle, then clusters at API 29 and API 31 when storage, location and Bluetooth were each split into finer pieces.
| API | New | Examples |
|---|---|---|
| 1 | 17 | ACCESS_FINE_LOCATION, CAMERA, READ_CONTACTS, RECORD_AUDIO |
| 4 | 1 | WRITE_EXTERNAL_STORAGE |
| 16 | 3 | READ_CALL_LOG, READ_EXTERNAL_STORAGE, WRITE_CALL_LOG |
| 20 | 1 | BODY_SENSORS |
| 26 | 2 | ANSWER_PHONE_CALLS, READ_PHONE_NUMBERS |
| 28 | 1 | ACCEPT_HANDOVER |
| 29 | 3 | ACCESS_BACKGROUND_LOCATION, ACCESS_MEDIA_LOCATION, ACTIVITY_RECOGNITION |
| 31 | 4 | BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, BLUETOOTH_SCAN, UWB_RANGING |
| 33 | 6 | POST_NOTIFICATIONS, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, NEARBY_WIFI_DEVICES |
| 34 | 1 | READ_MEDIA_VISUAL_USER_SELECTED |
| 37 | 1 | ACCESS_LOCAL_NETWORK |
The clusters are the interesting part. API 31's four new permissions are all Bluetooth and UWB — one
capability that used to be covered by BLUETOOTH and ACCESS_FINE_LOCATION, split into three so
that a user can grant "scan for nearby devices" without granting "connect to them". API 33's six are
the media split and the notification permission. In both cases the platform did not add a new
capability; it subdivided an existing one so consent could be narrower.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 18 | 4.3 Jelly Bean |
|
| 23 | 6.0 Marshmallow |
|
| 28 | 9 Pie |
|
| 29 | 10 |
|
| 30 | 11 |
|
| 31 | 12 |
|
| 33 | 13 Tiramisu |
|
| 37 | 17 Cinnamon Bun |
|
Under the hood#
- PermissionManagerService.javagrant, revoke and the protection-level checks
- AppOpsService.javathe operation-level state beneath permissions
- AppOpsManager.javathe client API, including the auditing callbacks
- where the privacy indicators are drawn
- UserManagerService.javaprofiles, including Private Space
Curiosity corner#
- App Ops shipped in Android 4.3 with a hidden settings UI. It was removed from the visible Settings app and lived on as an internal service until the Privacy Dashboard gave it a public face.
- The mic and camera toggles are not permissions. They are a system-level sensor block; an app with a granted permission still gets silence or a black frame.
READ_EXTERNAL_STORAGEstill exists, but on API 33+ it is effectively ignored for media in favour of the granular permissions.
Try it#
adb shell dumpsys package com.example.app | grep -A20 "runtime permissions"
Example output
android.permission.CAMERA: granted=true
android.permission.POST_NOTIFICATIONS: granted=falseadb shell appops get com.example.app
Example output
CAMERA: allow; time=+1h2m3s agoadb shell am start -a android.settings.PRIVACY_SETTINGS
Example output
Starting: Intent { act=android.settings.PRIVACY_SETTINGS }Build it#
Write a screen that requests camera, location and notifications, and log the result of each request
including whether shouldShowRequestPermissionRationale is true. Then deny one permanently and
observe the difference. The three-state model becomes concrete in about two minutes.
Check yourself#
Check yourself
Put these privacy changes in the order they arrived.
Drag, or use the arrows to reorder.
- 1Selected photos access
- 2Privacy Dashboard, mic and camera indicators, approximate location
- 3Scoped storage and background location as a separate grant
- 4Runtime permissions
- 5One-time permissions and permission auto-reset
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsPermissions on Android | Privacydeveloper.android.comaccessed 2026-10-27↩
- docsModular system componentssource.android.comaccessed 2026-10-27↩
- docsPerubahan perilaku: aplikasi yang menargetkan API level 28+developer.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 10developer.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 11developer.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 12developer.android.comaccessed 2026-10-27↩
- docsData access auditingdeveloper.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 13 or higherdeveloper.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 14developer.android.comaccessed 2026-10-27↩
- docsPrivate Spacesource.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 17developer.android.comaccessed 2026-10-27↩
- docsManifest.permission | API referencedeveloper.android.comaccessed 2026-10-27↩
- docsAndroid 6.0 Changesdeveloper.android.comaccessed 2026-10-27↩
- docsPerubahan Perilaku Android 8.0developer.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 15 or higherdeveloper.android.comaccessed 2026-10-27↩