<CarlosDev/>

Current

Android 6.0 Marshmallow: permissions at runtime

API 23, October 2015. Apps began asking for dangerous permissions while running, Doze cut background work on idle phones, and the security patch level became a date.

Published
Reading
14 min
Write-up
Stable
Series
Part 5 of 19 · Android, version by version
Android 6.0 Marshmallow banner, with the version logo.
In this record10 sections

Android 6.0 Marshmallow is the release where apps stopped getting every permission at install. From API 23, an app asks for a dangerous permission while it runs, and the user can say no. It also added Doze, which parks background work on an idle phone, and a security patch level that devices report as a date.

The Android 6.0 home screen in the emulator: a Google search bar, a clock widget, a Camera shortcut and a dock with Phone, Contacts, the app drawer, Messaging and Browser
Stock Android 6.0 home screen, in the Android emulator with a Nexus 5 profile. Wikimedia Commons · Apache License 2.0

At a glance

VersionAndroid 6.0
API level23
NameMarshmallow, public
Build.VERSION_CODESM
Final SDK17 August 2015
ReleaseNexus rollout began 5 October 2015
Launch devicesNexus 5X (LG) and Nexus 6P (Huawei), announced 29 September 2015
Google Play target-API deadlineNone. Play’s target-API rule started in 2018, at API 26

Google released the first developer preview, then called Android M, at Google I/O on 28 May 2015. On 17 August it published the final SDK, named the release Marshmallow and opened Play to apps targeting API 23. On 29 September it announced the rollout to the Nexus 5, 6, 7 (2013), 9, Nexus Player and Android One “starting next week”. The Official Android Blog announced on 5 October that the rollout was starting that day, and Phone Scoop reported the same date. The three developer previews before the release are the parts that follow this note: Preview 1, Preview 2 and Preview 3.

The same 29 September event showed the Pixel C tablet, which runs Marshmallow; its first builds in AOSP are Android 6.0.1. Android 6.0.1 arrived on 7 December 2015 with the December security patch, the Unicode 8 emoji and the return of “until next alarm” in Do Not Disturb.

What it brought

  • Runtime permissions. Covered in its own section below.
  • Doze. An unplugged phone that sits still with the screen off enters Doze. Network access stops, wake locks are ignored, and alarms, jobs and syncs wait for short maintenance windows.
  • App Standby. An app the user has not touched for a while, with no foreground process or visible notification, loses network access and its jobs and syncs while the phone is unplugged.
  • App Links. With android:autoVerify="true" on an intent filter, Android 6.0 checks https://<host>/.well-known/assetlinks.json at install. If it matches, links to that site open in the app without the chooser dialog.
  • Fingerprint API. FingerprintManager.authenticate() behind the USE_FINGERPRINT permission, tied to keys in the Android Keystore.
  • Auto Backup for Apps. Apps targeting API 23 get their data backed up to a private folder in the user’s Google Drive, with no code. The limit is 25 MB per app, and it does not count against the user’s Drive quota.
  • Adoptable storage. A user can format an SD card as internal storage. Apps should ask for paths with getFilesDir() and getCacheDir() instead of hard-coding them. Samsung and LG left it out of the Galaxy S7 and LG G5, so do not count on it being there.
  • Assist API. Apps can hand context to the assistant through Activity#onProvideAssistContent(). Ars Technica describes Google Now on Tap as the feature built on it: a long press on home sends the screen to Google.
  • Smaller additions. Direct Share (ChooserTargetService), voice interactions (VoiceInteractor), the camera torch (CameraManager#setTorchMode()), android.media.midi, Bluetooth stylus buttons and 4K display modes.

Security and privacy

  • Monthly security updates. On 5 August 2015 Google said Nexus devices would get an OTA “each month focused on security”. The first public bulletin, published 13 August 2015, covered the Stagefright media flaws. Nexus devices were promised security patches for three years from launch or 18 months from last sale on the Google Store, whichever is longer.
  • Security patch level. API 23 added Build.VERSION.SECURITY_PATCH, the date of the last security patch the device applied. Settings shows it as “Android security patch level” under About phone.
  • Encryption. The 6.0 CDD requires full-disk encryption on any device with a secure lock screen that is not a low-RAM device. If its AES speed is above 50 MiB/s, encryption must be on by default after setup.
  • Verified Boot. Under the same CDD, devices with AES above 50 MiB/s must support Verified Boot, from a hardware root of trust up to the system partition.
  • Hardware-isolated keys. A new HAL protects keys used by the fingerprint API, the lock screen, device encryption and client certificates against a kernel compromise.
  • Fingerprint rules. The CDD caps the false acceptance rate at 0.002%, locks out for at least 30 seconds after five failed tries, and requires matching inside the Trusted Execution Environment.
  • Hardware identifiers. WifiInfo.getMacAddress() and BluetoothAdapter.getAddress() return 02:00:00:00:00:00 for every app. Background Wi-Fi and Bluetooth scans use a randomized MAC address.
  • Smaller changes. SELinux policy got tighter (IOCTL filtering, very limited /proc). USB defaults to charge-only, and file access needs the user’s approval. A new StrictMode check flags cleartext traffic. Android moved from OpenSSL to BoringSSL. Adopted SD cards are encrypted and work in one device only.

Permissions

Permissions now come in two kinds. Normal permissions are still granted at install. Dangerous ones (location, contacts, camera, microphone, SMS and the like) have to be requested at runtime by apps that target API 23.

granted denied Allow Deny Feature needs CAMERA checkSelfPermission Use the camera requestPermissions System dialog Work without it

The system owns the dialog (dashed above), so the app cannot change its text. Call shouldShowRequestPermissionRationale() to know when to explain the request first. On Android 6.0, a second request after a denial added a “Never ask again” checkbox.

The App permissions screen in Settings, with one switch per group: Calendar, Camera, Contacts, Location, Microphone, Phone, SMS and Storage
Per-app permission switches, one per group, as added in Android 6.0. Screenshot uploaded in 2017. Wikimedia Commons · Apache License 2.0
  • Groups. Users grant and revoke by permission group. Until Android 8.0, a grant also gave the app every other permission from that group declared in its manifest.
  • Older apps. Apps targeting API 22 or lower still get their permissions at install. Users can switch them off anyway, for old and new apps alike.
  • Added. USE_FINGERPRINT.
  • Removed. READ_HISTORY_BOOKMARKS and WRITE_HISTORY_BOOKMARKS, along with Browser.getAllBookmarks() and Browser.saveBookmark().
  • Location for scans. Reading nearby hardware IDs from WifiManager.getScanResults(), BluetoothDevice.ACTION_FOUND or BluetoothLeScanner.startScan() needs ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION.
  • Device owners. DevicePolicyManager#setPermissionPolicy() lets an enterprise admin set how runtime permissions are granted.

What changed for your app

All apps on Android 6.0

ChangeWhat to do
Doze and App StandbyTest with adb shell dumpsys deviceidle force-idle and adb shell am set-inactive <package> true. Use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() for alarms that must fire. Send urgent pushes as high-priority FCM messages: they get brief network access during Doze
Apps that want out of DozeACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS sends the user to Settings. ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS asks directly, but Play policy allows it only when Doze breaks the app’s core function
Users can switch off permissions for any appTest with permissions off, even if you do not target API 23
MAC address returns 02:00:00:00:00:00Stop using it as a device ID
Bookmark APIs removedKeep bookmarks in your own storage
setStreamSolo() and setStreamMute() deprecatedUse requestAudioFocus() and adjustStreamVolume()
Keystore drops DSAUse ECDSA
Camera access goes by process priorityHandle onError() (Camera) or onDisconnected() (Camera2)
An APK missing a file named in its manifest is corruptRe-sign after removing any content

The Apache HTTP client left the SDK, so compileSdkVersion 23 no longer sees it. Switch to HttpURLConnection, or add useLibrary 'org.apache.http.legacy' to build.gradle. Devices kept the classes on the bootclasspath until Android 9.

Apps targeting API 23

ChangeWhat to do
Dangerous permissions are requested at runtimecheckSelfPermission() before each access, requestPermissions() when denied
Auto Backup is on by defaultChoose what is backed up with android:fullBackupContent, or set android:allowBackup="false"
Native libraries with text relocations are rejectedRebuild them without text relocations
Stylus buttons report BUTTON_STYLUS_PRIMARY and BUTTON_STYLUS_SECONDARYRead them through MotionEvent#getButtonState()

What lasted

  • Runtime permissions are still the model. Android 8.0 fixed the group-wide grant, Android 10 split out ACCESS_BACKGROUND_LOCATION, and Android 11 added one-time grants.
  • Doze grew in Android 7.0: part of it now applies while the phone is moving in a pocket with the screen off.
  • Verified Boot became strictly enforced in Android 7.0: a compromised device does not boot.
  • Apache HTTP left the bootclasspath in Android 9. Apps targeting 9 that still need it declare <uses-library android:name="org.apache.http.legacy" android:required="false"/>.
  • Fingerprint: Android 9 tells apps to move from FingerprintManager to BiometricPrompt.
  • Adoptable storage could not be combined with file-based encryption on Android 7.0 to 8.1. From Android 9, both work together.
  • Monthly bulletins still ship. Play’s target-API requirement, which did not exist in 2015, started in 2018 and now moves up every year.
  • End of support. The August 2018 bulletin was the last to list Android 6.0 and 6.0.1 among its updated AOSP versions. The last Marshmallow build in Google’s list, android-6.0.1_r81 (MOI10E), carries the October 2017 patch level. Google Play services now lists Android 7.0 (API 24) as its minimum; OSnews reported the drop of 6.0 on 24 July 2026.

Worth knowing

  • The M constant in AOSP carries a one-line comment: M comes after L.
  • The Easter egg is Marshmallow Land, a Flappy Bird-style game. Its code allows up to six players (MAX_PLAYERS = 6) and runs in a process named :sweetsweetdesserts.
  • 02:00:00:00:00:00 is what every app on Marshmallow reads as the Wi-Fi and Bluetooth MAC address.
  • Android Police reported in May 2015 that the internal code name was Macadamia Nut Cookie, which is where the mnc-dev branch in AOSP got its name.

Part 1 of 3

2 min

M Developer Preview 1: Android M at I/O

28 May 2015. The first build of Android M, shown at Google I/O, brought runtime permissions, App Links, Doze and the fingerprint APIs to four Nexus devices.

Read on its own: M Developer Preview 1: Android M at I/O

Google announced Android M at Google I/O on 28 May 2015 and released the first developer preview the same day, right after the keynote. The release had no number and no name yet: the SDK called it “Android MNC Preview”, and projects built against it with compileSdkVersion 'android-MNC'.

Release date28 May 2015
BuildMPZ44Q
DevicesNexus 5, Nexus 6, Nexus 9 and Nexus Player, by flashing system images
Emulatorx86 and ARM, 32- and 64-bit
Google Play services7.5
API statusPreview APIs, not final; no API level yet

What Preview 1 introduced

Google’s announcement framed M as “improving the fundamentals”. The headline changes for developers were already in this build:

  • Runtime permissions. Apps request permissions in context while running, and users can grant or refuse each one and change it later in settings. Google told developers to “account for permissions that don’t get granted”.
  • App Links. An autoVerify attribute in the manifest lets a verified app open its own URLs with no disambiguation prompt.
  • Doze. When significant motion detection shows the device has been left unattended, Android backs off background activity. Google pointed chat apps to high-priority messages to wake them.
  • Fingerprint. New APIs let apps authorise with the fingerprint sensor, the same mechanism behind Android Pay and Play purchases.
  • Now on tap. Assist APIs feed the current screen to Google Now; Google asked developers to implement App Indexing to appear in it.

Google released Android Studio 1.3 Preview, with C and C++ editing and debugging for the NDK, and the Android Design Support Library alongside it.

The planned timeline

This time Google promised “a clear timeline”. The preview site set it out: Preview 2 in “late June/early July”, Preview 3 “near final, late July”, and the final SDK later in the third quarter. Devices already on a preview build would get each update over the air.

Part 2 of 3

2 min

M Developer Preview 2: near-final APIs

9 July 2015. The second preview reshaped the permission model, made external storage a runtime permission and set USB connections to charge-only by default.

Read on its own: M Developer Preview 2: near-final APIs

Preview 2 arrived on 9 July 2015, within the “late June/early July” window Google had set. Google described it as “near-final APIs” with fixes from developer feedback. Most of its changes were to the permission model.

Release date9 July 2015
BuildMPZ79M (Nexus 5, 6, 9); MPZ79N (Nexus Player)
DevicesSame four Nexus devices; over the air from MPZ44Q, or by flashing
Emulatorx86 and ARM, 32- and 64-bit, through the SDK Manager
Google Play services7.6
API statusNear-final

How Preview 2 reshaped permissions

  • Storage. WRITE_EXTERNAL_STORAGE became “dangerous”, so apps must ask for it at runtime. It and READ_EXTERNAL_STORAGE form the STORAGE group.
  • Fingerprint. USE_FINGERPRINT became “normal” and no longer needs the user’s approval. It does not give access to fingerprint enrolment.
  • Wi-Fi and Bluetooth. BLUETOOTH, BLUETOOTH_ADMIN, CHANGE_WIFI_STATE, CHANGE_WIMAX_STATE and CHANGE_WIFI_MULTICAST_STATE became “normal”. Reading the MAC address of a remote Bluetooth or Wi-Fi device now needs ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION.
  • Accounts. Some account and identity permissions moved into the CONTACTS group; USE_CREDENTIALS, MANAGE_ACCOUNTS and AUTHENTICATE_ACCOUNTS were left ungrouped “pending further changes”. Bookmark and subscribed-feed permissions were removed.
  • System apps. Apps in the system image stopped getting dangerous permissions automatically.
  • Rationale. Activity.shouldShowRequestPermissionRationale(String) tells an app whether the user has already refused a permission, so it can explain why it needs it.

Other Preview 2 changes

  • USB connections default to charge-only; the user must allow data access.
  • android.app.AssistContent and AssistStructure moved to the new android.app.assist package.
  • The stylus listeners were renamed: View.OnContextClickListener and GestureDetector.OnContextClickListener replace the OnStylusButtonPress versions.
  • InputDevice.hasMicrophone() reports whether an input device has a microphone.

The “Dark” system theme from Preview 1 was gone. 9to5Google later quoted a Googler on the preview issue tracker: “This will not be included in the M release.”

Part 3 of 3

2 min

M Developer Preview 3: final SDK, a name

17 August 2015. The last preview shipped the official Android 6.0 SDK at API 23, named the release Marshmallow and opened Google Play to apps targeting it.

Read on its own: M Developer Preview 3: final SDK, a name

Preview 3 came out on 17 August 2015, with the official Android 6.0 SDK. The same post named the release Marshmallow and fixed it at API level 23. Google Play began accepting apps that target API 23 on every channel: Alpha, Beta and Production.

Release date17 August 2015
BuildMPA44I
DevicesNexus 5, Nexus 6, Nexus 9 and Nexus Player, over the air or by flashing
Emulatorx86 and ARM, 32- and 64-bit; Android 6.0 SDK through the SDK Manager
Google Play services7.8
API statusFinal, API level 23; system images near final and not meant for consumer use

It was late. The plan had been “near final, late July”; on 31 July Android Police reported that Google would miss that date. The first Preview 3 images were build MPA44G, and Google replaced them the same day with MPA44I, which the preview site lists as the Preview 3 build.

What Preview 3 finalised

Google called the API changes since Preview 2 “fairly incremental”:

  • Permissions UI. The permission dialogs and settings took their final form, with some behaviour changes.
  • GET_ACCOUNTS. It joined the CONTACTS group as “dangerous”, so apps targeting API 23 must request it at runtime. READ_PROFILE and WRITE_PROFILE left the CONTACTS group.
  • Wi-Fi and Bluetooth LE scans. Apps targeting API 23 need a location permission to get scan results. Apps targeting API 22 or lower still get them, but only in the foreground.
  • Fingerprint API. Better error reporting, a better enrolment flow and enumeration support.

Support Library 23 shipped the same day, with new customtabs, percent, recommendation and preference libraries, and backward-compatible helpers for the permission and fingerprint APIs.

Preview builds could not take consumer updates. To get the public release, which reached Nexus devices on 5 October, testers had to flash a factory image by hand.

Filed under

Citations

58

External references