App Ops Developer FAQ

Since Android 4.3’s “App Ops” has hit Techcrunch, The Verge, and and GigaOM in addition to the original reporting from AndroidPolice, developers need to start thinking about what App Ops’ availability will mean to their apps.

What follows is a set of questions and answers about App Ops. Since nobody has really asked me these questions, I have compiled them into a fictionally-asked questions (FAQ) list. I will update this post from time to time as details emerge. Feel free to contact me if you have additional details that you believe belong in this FAQ, or if you have corrections to anything reported here.

What is App Ops?

App Ops is an activity, within the Settings app, that allows users to enable or disable operations on a per-app basis. These operations cover many common scenarios identified by permissions (e.g., read contacts, write contacts, access location), though it is not a pure one-to-one mapping.

Operations blocked by App Ops are inaccessible by the affected app, though that may vary by device.

So, Users Can Get to App Ops Through Settings?

Well, no.

While App Ops is an activity in Settings, it is not linked to by the main Settings screen. At present, there’s no known way for a user to get to App Ops just through Settings.

However, the activity is exported and has an <intent-filter>. There are already several apps on the Play Store that effectively serve as “launchers” for getting to the App Ops activity. One might imagine that various security/privacy-related apps may also give their users the option of visiting App Ops.

{UPDATE 2013-08-13} Also, a mid-August 2013 change to the AOSP Settings app’s manifest comments out the App Ops activity, suggesting that access to it may be removed in future Android 4.3 patch releases. More details on this can be found in another blog post.

{UPDATE 2013-11-26} Well, not only did it not get removed from production Android 4.3 builds (e.g., Galaxy Nexus), but it exists in Android 4.4 as well, albeit with a slightly different launch mechanism.

What Devices Have App Ops?

App Ops is part of the Android 4.3 edition of the Settings app. It is definitely available on the retail Nexus 7 (2013) devices, and is also definitely available for the production images that you can flash on various Nexus-series devices. It is also likely that App Ops will be part of the OTA updates for those same Nexus devices, as they roll out.

{UPDATE 2013-08-13} App Ops was removed from the AOSP manifest.

Whether App Ops will be available on other Android devices that ship with (or are upgraded to) Android 4.3 remains to be seen. Device manufacturers are capable of disabling this activity, and some may elect to do just that.

{UPDATE 2013-11-26} Android 4.4 offers hidden access to App Ops again, at least on Nexus series devices.

Does App Ops Revoke Permissions?

No. An app that has a operation blocked by App Ops still retains its permission, and calls to checkPermission() on PackageManager will happily report that the app holds the permission.

What Can the User Control?

The following list represents the different operation categories seen in App Ops so far:

  • location
  • read calendar
  • modify calendar
  • read contacts
  • read call log
  • modify contacts
  • modify call log
  • read SMS
  • write SMS
  • receive SMS
  • receive MMS
  • send SMS
  • receive WAP push
  • vibrate
  • modify settings
  • access notifications
  • call phone
  • record audio
  • camera
  • draw on top
  • post notification

{UPDATE 2013-11-26} Android 4.4 adds the ability to block “keep awake”, which presumably offers a per-app effect akin to SONY’s STAMINA mode Also, a post by AndroidPolice suggests that there are ways to perhaps block changes to audio volume and audio focus changes, though I have not seen that in the App Ops UI itself.

What Happens When An App Tries to Perform a Blocked Operation?

That depends on what the operation is and the behavior of App Ops on the device itself.

Not all devices appear to implement App Ops in the same way. There are reports of some operations (e.g., accessing location) working on some devices despite being blocked in the App Ops activity.

For devices that do actually block the operation, what happens to the calling app varies by operation. For example, here are the results for some operations performed on a Nexus 7 (2013) running Android 4.3:

  • location: no location data supplied, but isProviderEnabled() reports true
  • read calendar: empty query results
  • read contacts: empty query results
  • record audio: no effect (MediaRecorder still records audio)
  • camera: getNumberOfCameras() returns the proper data, getCameraInfo() returns the proper data, but open() crashes with generic RuntimeException
  • post notification: notification not displayed

{UPDATE 2013-07-29} A Nexus 4, with the OTA update to Android 4.3, shows the same results, plus:

  • vibration: requests to vibrate the device are ignored

{UPDATE 2013-07-31} A Galaxy Nexus, with the OTA update to Android 4.3, shows the same results as does the Nexus 4.

{UPDATE 2013-08-08} A Nexus 10, with the OTA update to Android 4.3, shows the same results as does the Nexus 4.

{UPDATE 2013-08-12} A 1st-generation Nexus 7, with the OTA update to Android 4.3, shows the same results as does the Nexus 10.

{UPDATE 2013-10-19} It has been reported to me that attempting to insert() into CalendarContract fails, with an invalid Uri returned, if the “modify calendar” capability is blocked.

{UPDATE 2013-11-26} The behavior of the camera is the same with App Ops on Android 4.4. Other operations have not been re-tested at this time.

How Do We Detect That We Are Blocked?

There is no known way for an app to directly detect that one or more operations are being blocked by App Ops. Hopefully, we will find one, and hopefully, by the time App Ops is officially available, we will have some way to determine what is and is not possible.

In the absence of direct detection, we will need to work out indirect mechanisms (e.g., a RuntimeException on your open() call on Camera may mean that you are blocked by App Ops) and hope for the best.

{UPDATE 2013-11-26} It is possible that the AppOpsManager added to the Android 4.4 SDK will eventually give us the ability to detect when we are blocked. As it stands, AppOpsManager is a write-only interface, one that looks like it should only be used by system apps, begging the question of why it was added to the SDK in the first place.

What Happens As Our App Evolves?

Preliminary evidence suggests that an in-place upgrade of an app does not affect the blocks established by App Ops. However, uninstalling and re-installing the app removes any App Ops blocks placed on the original installation.

What Happens As the Device Evolves?

{UPDATE 2013-11-26} At least for the 4.3->4.4 upgrade path on a Nexus 7 (2012), anything blocked in App Ops remains blocked after the OS upgrade.

How Do I Test My App?

First, you need an Android 4.3+ environment. App Ops is available in the emulator, so if you normally test your app on the emulator, you can do so for App Ops behavior as well.

To bring up App Ops on the Android 4.3 emulator (and some devices, like the Galaxy Nexus), either use one of the App Ops launching apps on the Play Store, or run the following command at a command line on your development machine (with the device or emulator attached):

adb shell am start -a android.settings.APP_OPS_SETTINGS

Note that this command assumes that the adb utility is in your PATH. You can find adb in the platform-tools/ directory of your SDK installation.

{UPDATE 2013-11-26} To bring up App Ops on the Android 4.4 emulator (and some devices, like the Nexus 7 (2012)), the equivalent command is:

adb shell am start -a android.settings.SETTINGS \
-e ":android:show_fragment" ""

(Windows users: the \ means that this should all be on one line, shown here wrapped for readability)

App Ops initially shows a ViewPager with four categories of operations: location, personal, messaging, and device. Apps that request permissions related to those operations will appear in lists in their respective page. Tapping on an app will show some of the possible blockable operations, with Switch widgets to allow you to allow (“ON”) or deny (“OFF”) those operations.

Note that not all operations will appear right away necessarily. You may need to run your app and actually perform the operation once before it will appear in the list.

Am I Screwed?

Well, that’s difficult to answer.

Some of these should not be a big deal, insofar as there are other existing ways that the operations can be blocked:

  • location: user can disable from Settings
  • camera: device admins can disable
  • post notification: user can disable from Settings

Similarly, some of these represent conditional capabilities that cannot be filtered by <uses-feature> or the equivalent, and so the results we get are within reason:

  • read calendar: user may not have any calendars
  • read contacts: user may not have any contacts
  • read call log: user may not have any calls (e.g., tablet)
  • vibrate: device may not have a vibration motor

For those in particular, your app should already be in position to cope with being unable to perform these operations, and so the fact that they happen to be blocked by App Ops should not be significantly different, other than perhaps in how the blockage becomes apparent to you.

Others you might specifically be allowing the device to lack some capability, via android:required="false" on your <uses-feature> element:

  • location: device may not have location providers
  • read SMS: device may not have telephony
  • write SMS: device may not have telephony
  • receive SMS: device may not have telephony
  • receive MMS: device may not have telephony
  • send SMS: device may not have telephony
  • call phone: device may not have telephony
  • record audio: device may not have a microphone
  • camera: device may not have a camera

Here again, if you are allowing the app to run on devices that lack some capability (e.g., telephony), you already have logic in your app to deal with such devices.

This rolls back to the question of detecting whether you are blocked by App Ops. With that, developers can blend in App Ops detection logic with existing detection logic (e.g., hasSystemFeature() on PackageManager to handle android:required="false" on <uses-feature>).