diff options
Diffstat (limited to 'docs/html/preview')
21 files changed, 2677 insertions, 405 deletions
diff --git a/docs/html/preview/api-changes.jd b/docs/html/preview/api-changes.jd index e4be2a1..8ea91dd 100644 --- a/docs/html/preview/api-changes.jd +++ b/docs/html/preview/api-changes.jd @@ -1,6 +1,6 @@ page.title=Behavior Changes page.keywords=preview,sdk,compatibility -sdk.platform.apiLevel=23 +page.tags=previewresources, androidm @jd:body <div id="qv-wrapper"> diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd index 5ab4b89..bf5eec4 100644 --- a/docs/html/preview/api-overview.jd +++ b/docs/html/preview/api-overview.jd @@ -1,7 +1,8 @@ page.title=API Overview page.keywords=preview,sdk,compatibility +page.tags=previewresources, androidm sdk.platform.apiLevel=22-mnc -page.image=images/cards/card-key-changes_16-9_2x.png +page.image=images/cards/card-api-overview_16-9_2x.png @jd:body @@ -14,8 +15,7 @@ page.image=images/cards/card-key-changes_16-9_2x.png <span class="less" style="display:none">show less</span></a></h2> <ol id="toc44" class="hide-nested"> - <li><a href="#backup">Auto Backup for Apps</a></li> - <li><a href="#notifications">Notifications</a></li> + <li><a href="#backup">Automatic App Data Backup</a></li> <li><a href="#authentication">Authentication</a> <ul> <li><a href="#fingerprint-authentication">Fingerprint Authentication</a></li> @@ -24,14 +24,27 @@ page.image=images/cards/card-key-changes_16-9_2x.png </li> <li><a href="#direct-share">Direct Share</a></li> <li><a href="#voice-interactions">Voice Interactions</a></li> + <li><a href="#assist">Assist API</a></li> + <li><a href="#notifications">Notifications</a></li> <li><a href="#bluetooth-stylus">Bluetooth Stylus Support</a></li> - <li><a href="#audio">New Audio Features</a></li> - <li><a href="#afw">New Android for Work Features</a></li> + <li><a href="#ble-scanning">Improved Bluetooth Low Energy Scanning</a></li> + <li><a href="#hotspot">Hotspot 2.0 Release 1 Support</a></li> + <li><a href="#4K-display">4K Display Mode</a></li> + <li><a href="#behavior-themeable-colorstatelists">Themeable ColorStateLists</a></li> + <li><a href="#audio">Audio Features</a></li> + <li><a href="#video">Video Features</a></li> + <li><a href="#camera">Camera Features</a> + <ul> + <li><a href="#flashlight">Flashlight API</a></li> + <li><a href="#reprocessing">Camera Reprocessing</a></li> + </ul> + </li> + <li><a href="#afw">Android for Work Features</a></li> </ol> <h2>API Differences</h2> <ol> -<li><a href="">API level 22 to M »</a> </li> +<li><a href="{@docRoot}preview/download.html">API level 22 to M Preview »</a> </li> </ol> </div> @@ -55,40 +68,24 @@ methods that do not yet have reference material available on <a href="{@docRoot}">developer.android.com</a>. These API elements are formatted in {@code code style} in this document (without hyperlinks). For the preliminary API documentation for these elements, download the <a -href="http://storage.googleapis.com/androiddevelopers/preview/m-developer-preview-reference.zip"> -preview reference</a>.</p> +href="{@docRoot}preview/download.html#docs"> preview reference</a>.</p> <h3>Important behavior changes</h3> <p>If you have previously published an app for Android, be aware that your app might be affected -by changes in M.</p> +by changes in the platform.</p> -<p>Please see <a href="api-changes.html">Behavior Changes</a> for complete information.</p> +<p>Please see <a href="behavior-changes.html">Behavior Changes</a> for complete information.</p> -<h2 id="backup">Auto Backup for Apps</h2> +<h2 id="backup">Automatic App Data Backup</h2> <p>The system now performs automatic full data backup and restore for apps. This behavior is -enabled by default for apps targeting M; you do not need to add any additional code. If users -delete their Google account, their backup data is deleted as well.</p> -<p>To learn how this feature works and how to configure what to back up on the file system, -see the <a href="">App Backup for Apps guide</a>.</p> - -<h2 id="notifications">Notifications</h2> -<p>M adds the following API changes for notifications:</p> -<ul> - <li>New {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} filter level that - corresponds to the new <em>Alarms only</em> do not disturb mode.</li> - <li>New {@code Notification.CATEGORY_REMINDER} category value that is used to distinguish - user-scheduled reminders from other events - ({@link android.app.Notification#CATEGORY_EVENT}) and alarms - ({@link android.app.Notification#CATEGORY_ALARM}).</li> - <li>New {@code android.graphics.drawable.Icon} class which can be attached to your notifications - via the Notification.Builder.setIcon() and Notification.Builder.setLargeIcon() methods.</li> - <li>New {@code NotificationManager.getActiveNotifications()} method that allows your apps to - find out which of their notifications are currently alive.</li> -</ul> +enabled by default for apps targeting M Preview; you do not need to add any additional code. If +users delete their Google accounts, their backup data is deleted as well. To learn how this feature +works and how to configure what to back up on the file system, see +<a href="{@docRoot}preview/backup/index.html">Automatic App Data Backup</a>.</p> <h2 id="authentication">Authentication</h2> -<p>The M release offers new APIs to let you authenticate users by using their fingerprint scans on +<p>This preview offers new APIs to let you authenticate users by using their fingerprint scans on supported devices, and check how recently the user was last authenticated using a device unlocking mechanism (such as a lockscreen password). Use these APIs in conjunction with the <a href="{@docRoot}training/articles/keystore.html">Android Keystore system</a>.</p> @@ -97,17 +94,15 @@ the <a href="{@docRoot}training/articles/keystore.html">Android Keystore system< <p>To authenticate users via fingerprint scan, get an instance of the new {@code android.hardware.fingerprint.FingerprintManager} class and call the -{@code FingerprintManager.authenticate()} method. Your app must be running on a device with a -fingerprint sensor. You must implement the user interface for the fingerprint -authentication flow on your app, and use the standard fingerprint Android icon in your UI. -If you are developing multiple apps that use fingerprint authentication, note that each app must -authenticate the user’s fingerprint independently. +{@code FingerprintManager.authenticate()} method. Your app must be running on a compatible +device with a fingerprint sensor. You must implement the user interface for the fingerprint +authentication flow on your app, and use the standard Android fingerprint icon in your UI. +The Android fingerprint icon ({@code c_fp_40px.png}) is included in the +<a href="https://github.com/googlesamples/android-FingerprintDialog" +class="external-link">sample app</a>. If you are developing multiple apps that use fingerprint +authentication, note that each app must authenticate the user’s fingerprint independently. </p> -<img src="{@docRoot}preview/images/fingerprint-screen_2x.png" -srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, preview/images/fingerprint-screen_2x.png 2x" -style="margin:0 0 10px 20px" width="282" height="476" /> - <p>To use this feature in your app, first add the {@code USE_FINGERPRINT} permission in your manifest.</p> @@ -116,34 +111,34 @@ manifest.</p> android:name="android.permission.USE_FINGERPRINT" /> </pre> -<p>The following snippet shows how you might listen for fingerprint events in your -{@code FingerprintManager.AuthenticationCallback} implementation.</p> +<img src="{@docRoot}preview/images/fingerprint-screen.png" +srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" +style="float:right; margin:0 0 10px 20px" width="282" height="476" /> -<pre> -// Call this to start listening for fingerprint events -public void startListening(FingerprintManager.CryptoObject cryptoObject) { - if (!isFingerprintAuthAvailable()) { - return; - } - mCancellationSignal = new CancellationSignal(); - mSelfCancelled = false; - mFingerprintManager.authenticate(cryptoObject, - mCancellationSignal, this, 0 /* flags */); - // Icon to display when prompting users to start a fingerprint scan - mIcon.setImageResource(R.drawable.ic_fp_40px); -} - -// Helper method to check if the device supports fingerprint -// scanning and if the user has enrolled at least one fingerprint. -public boolean isFingerprintAuthAvailable() { - return mFingerprintManager.isHardwareDetected() - && mFingerprintManager.hasEnrolledFingerprints(); -} +<p>To see an app implementation of fingerprint authentication, refer to the +<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link"> + Fingerprint Dialog sample</a>.</p> + +<p>If you are testing this feature, follow these steps:</p> +<ol> +<li>Enroll a new fingerprint in the emulator by going to +<strong>Settings > Security > Fingerprint</strong>, then follow the enrollment instructions.</li> +<li>Install Android SDK Tools Revision 24.3, if you have not done so.</li> +<li>Use an emulator to emulate fingerprint touch events with the +following command. Use the same command to emulate fingerprint touch events on the lockscreen or +in your app. +<pre class="no-prettyprint"> +adb -e emu finger touch <finger_id> </pre> +<p>On Windows, you may have to run {@code telnet 127.0.0.1 <emulator-id>} followed by + {@code finger touch <finger_id>}. +</p> +</li> +</ol> <h3 id="confirm-credentials">Confirm Credentials</h3> <p>Your app can authenticate users based on how recently they last unlocked their device. You can -use the same public or secret key to authenticate users into multiple apps. This feature frees +use the same public or secret key to authenticate users. This feature frees users from having to remember additional app-specific passwords, and avoids the need for you to implement your own authentication user interface.</p> @@ -152,46 +147,14 @@ generating or importing. To set the constraints for using a key, use the {@code android.security.KeyPairGeneratorSpec.Builder} and {@code android.security.KeyGeneratorSpec.Builder} classes for public key pairs and secret keys respectively. If you are importing keys, use the {@link android.security.KeyStoreParameter.Builder} -class to set your constraints.</p> - -<p>The following example shows how you might create a symmetric key in the Keystore which can only be -used if the user has successfully unlocked the device within the last 5 minutes.</p> - -<pre> -private void createKey() { - // Generate a key to decrypt payment credentials, tokens, etc. - // This will most likely be a registration step for the user when - // they are setting up your app. - try { - KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); - ks.load(null); - KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", - "AndroidKeyStore"); - keyGenerator.init(new KeyGeneratorSpec.Builder(this) - // Alias of the entry in Android KeyStore where the key will appear - .setAlias(KEY_NAME) - // Key use constraints - .setPurposes(KeyStoreKeyProperties.Purpose.ENCRYPT - | KeyStoreKeyProperties.Purpose.DECRYPT) - .setBlockModes("CBC") - .setUserAuthenticationRequired(true) - // Require that the user has unlocked in the last 5 minutes - .setUserAuthenticationValidityDurationSeconds(5 * 60) - .setEncryptionPaddings("PKCS7Padding") - .build()); - keyGenerator.generateKey(); - } catch (NoSuchAlgorithmException | NoSuchProviderException - | InvalidAlgorithmParameterException | KeyStoreException - | CertificateException | IOException e) { - throw new RuntimeException(e); - } -} -</pre> +class to set your constraints. You can use the +{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} +method to re-authenticate the user within your app if the timeout expired. +</p> -<p>To determine the last time users logged into their account, call the -{@code android.accounts.AccountManager.confirmCredentials()} method. If the call is successful, the -method returns an bundle that includes a {@code KEY_LAST_AUTHENTICATED_TIME} value which indicates -the last time, in milliseconds, that the credential for that account was validated or created.</p> +<p>To see an app implementation of this feature, refer to the +<a href="https://github.com/googlesamples/android-ConfirmDeviceCredentials" class="external-link"> + Confirm Device Credentials sample</a>.</p> <h2 id="direct-share">Direct Share</h2> @@ -199,7 +162,7 @@ the last time, in milliseconds, that the credential for that account was validat srcset="{@docRoot}preview/images/direct-share-screen.png 1x, preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="385" /> -<p>This release provides you with APIs to makes sharing intuitive and quick for users. You can now +<p>This preview provides you with APIs to makes sharing intuitive and quick for users. You can now define <em>deep links</em> that target a specific activity in your app. These deep links are exposed to users via the <em>Share</em> menu. This feature allows users to share content to targets, such as contacts, within other apps. For example, the deep link might launch an @@ -214,9 +177,6 @@ friend or community in that app.</p> {@code SERVICE_INTERFACE} action.</p> <p>The following example shows how you might declare the {@code ChooserTargetService} in your manifest.</p> -<br> -<br> -<br> <pre> <service android:name=".ChooserTargetService" android:label="@string/service_name" @@ -243,37 +203,142 @@ manifest.</p> android:value=".ChooserTargetService" /> </activity> </pre> +<p>To see an app implementation of this feature, refer to the +<a href="https://github.com/googlesamples/android-DeepLinkSharing" class="external-link"> + Deep Link Sharing sample</a>.</p> + <h2 id="voice-interactions">Voice Interactions</h2> <p> -This release provides a new voice interaction API which, together with +This preview provides a new voice interaction API which, together with <a href="https://developers.google.com/voice-actions/" class="external-link">Voice Actions</a>, allows you to build conversational voice experiences into your apps. Call the {@code android.app.Activity.isVoiceInteraction()} method to determine if your activity was started in response to a voice action. If so, your app can use the {@code android.app.VoiceInteractor} class to request a voice confirmation from the user, select -from a list of options, and more.</p> -<p>To learn more about implementing voice actions, see the voice interaction API +from a list of options, and more. To learn more about implementing voice actions, see the <a href="https://developers.google.com/voice-actions/interaction/" -class="external-link">guide</a>. +class="external-link">Voice Actions developer site</a>. </p> +<h2 id="assist">Assist API</h2> +<p> +This preview offers a new way for users to engage with your apps through an assistant. To use this +feature, the user must enable the assistant to use the current context. Once enabled, the user +can summon the assistant within any app, by long-pressing on the <strong>Home</strong> button.</p> +<p>The platform passes the current context to the assistant. In addition to the standard set of +information that the platform passes to the assistant, your app can share additional information +by using the new {@code android.app.Activity.AssistContent} class.</p> + +<p>To provide the assistant with additional context from your app, follow these steps:</p> + +<ol> +<li>Implement the {@link android.app.Application.OnProvideAssistDataListener} interface.</li> +<li>Register this listener by using +{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li> +<li>In order to provide activity-specific contextual information, override the +{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} +callback and, optionally, the new {@code Activity.onProvideAssistContent()} callback. +</ol> + +<h2 id="notifications">Notifications</h2> +<p>This preview adds the following API changes for notifications:</p> +<ul> + <li>New {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} filter level that + corresponds to the new <em>Alarms only</em> do not disturb mode.</li> + <li>New {@code Notification.CATEGORY_REMINDER} category value that is used to distinguish + user-scheduled reminders from other events + ({@link android.app.Notification#CATEGORY_EVENT}) and alarms + ({@link android.app.Notification#CATEGORY_ALARM}).</li> + <li>New {@code android.graphics.drawable.Icon} class which can be attached to your notifications + via the {@code Notification.Builder.setSmallIcon(Icon)} and + {@code Notification.Builder.setLargeIcon(Icon)} methods.</li> + <li>New {@code NotificationManager.getActiveNotifications()} method that allows your apps to + find out which of their notifications are currently alive. To see an app implementation that + uses this feature, see the <a href="https://github.com/googlesamples/android-ActiveNotifications" + class="external-link">Active Notifications sample</a>.</li> +</ul> + <h2 id="bluetooth-stylus">Bluetooth Stylus Support</h2> -<p>The M release provides improved support for user input using a Bluetooth stylus. If the user -touches a stylus with a button on the screen of your app, the -{@link android.view.MotionEvent#getToolType(int) getTooltype()} method now returns -{@code TOOL_TYPE_STYLUS}. The {@link android.view.MotionEvent#getButtonState() getButtonState()} -method returns {@link android.view.MotionEvent#BUTTON_SECONDARY} when the user +<p>This preview provides improved support for user input using a Bluetooth stylus. Users can pair +and connect a compatible Bluetooth stylus with their phone or tablet. While connected, position +information from the touch screen is fused with pressure and button information from the stylus to +provide a greater range of expression than with the touch screen alone. Your app can listen for +stylus button presses and perform secondary actions, by registering the new +{@code View.onStylusButtonPressListener} and {@code GestureDetector.OnStylusButtonPressListener} +callbacks in your activity.</p> + +<p>Use the {@link android.view.MotionEvent} methods and constants to detect stylus button +interactions:</p> +<ul> +<li>If the user touches a stylus with a button on the screen of your app, the +{@link android.view.MotionEvent#getToolType(int) getTooltype()} method returns +{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li> +<li>For apps targeting M Preview, the +{@link android.view.MotionEvent#getButtonState() getButtonState()} +method returns {@code MotionEvent.STYLUS_BUTTON_PRIMARY} when the user presses the primary stylus button. If the stylus has a second button, the same method returns -{@link android.view.MotionEvent#BUTTON_TERTIARY} when the user presses it. If the user presses -both buttons simultaneously, the method returns both these values. In addition, the system reports -the user button-press action to the new {@code View.onStylusButtonPressListener} and -{@code GestureDetector.OnStylusButtonPressListener} callbacks in your activity, if you have -registered these listeners in your app.</p> +{@code MotionEvent.STYLUS_BUTTON_SECONDARY} when the user presses it. If the user presses +both buttons simultaneously, the method returns both values OR'ed together +({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).</li> +<li> +For apps targeting a lower platform version, the +{@link android.view.MotionEvent#getButtonState() getButtonState()} method returns +{@link android.view.MotionEvent#BUTTON_SECONDARY} (for primary stylus button press), +{@link android.view.MotionEvent#BUTTON_TERTIARY} (for secondary stylus button press), or both. +</li> +</ul> + +<h2 id="ble-scanning">Improved Bluetooth Low Energy Scanning</h2> +<p> +If your app performs performs Bluetooth Low Energy scans, you can use the new +{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} method to specify that +you want callbacks to only be notified when an advertisement packet matching the set +{@link android.bluetooth.le.ScanFilter} is first found, and when it is not seen for a period of +time. This approach to scanning is more power-efficient than what’s provided in the previous +platform version. +</p> -<h2 id="audio">New Audio Features</h2> +<h2 id="hotspot">Hotspot 2.0 Release 1 Support</h2> +<p> +This preview adds support for the Hotspot 2.0 Release 1 spec on Nexus 6 and Nexus 9 devices. To +provision Hotspot 2.0 credentials in your app, use the new methods of the +{@link android.net.wifi.WifiEnterpriseConfig} class, such as {@code setPlmn()} and +{@code setRealm()}. In the {@link android.net.wifi.WifiConfiguration} object, you can set the +{@link android.net.wifi.WifiConfiguration#FQDN} and the {@code providerFriendlyName} fields. +The new {@code ScanResult.PasspointNetwork} property indicates if a detected +network represents a Hotspot 2.0 access point. +</p> -<p>This release adds enhancements to audio processing on Android, including: </p> +<h2 id="4K-display">4K Display Mode</h2> +<p>The platform now allows apps to request that the display resolution be upgraded to 4K rendering +on compatible hardware. To query the current physical resolution, use the new +{@code android.view.Display.Mode} APIs. If the UI is drawn at a lower logical resolution and is +upscaled to a larger physical resolution, be aware that the physical resolution the +{@code Display.Mode.getPhysicalWidth()} method returns may differ from the logical +resolution reported by {@link android.view.Display#getSize(android.graphics.Point) getSize()}.</p> + +<p>You can request the system to change the physical resolution in your app as it runs, by setting +the {@code WindowManager.LayoutParams.preferredDisplayModeId} property of your app’s window. This +feature is useful if you want to switch to 4K display resolution. While in 4K display mode, the +UI continues to be rendered at the original resolution (such as 1080p) and is upscaled to 4K, but +{@link android.view.SurfaceView} objects may show content at the native resolution.</p> + +<p>To test the new 4K display mode, simulate a secondary display of a larger resolution using the +<strong>Developer Options</strong> settings.</p> + +<h2 id="behavior-themeable-colorstatelists">Themeable ColorStateLists</h2> +<p>Theme attributes are now supported in +{@link android.content.res.ColorStateList} for devices running the M Preview. The +{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} and +{@link android.content.res.Resources#getColor(int) getColor()} methods have been deprecated. If +you are calling these APIs, call the new {@code Context.getColorStateList()} or +{@code Context.getColor()} methods instead. These methods are also available in the +v4 appcompat library via {@link android.support.v4.content.ContextCompat}.</p> + +<h2 id="audio">Audio Features</h2> + +<p>This preview adds enhancements to audio processing on Android, including: </p> <ul> <li>Support for the <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> protocol, with the new {@code android.media.midi} APIs. Use these APIs to send and receive MIDI @@ -293,8 +358,78 @@ attached source and sink audio devices. You can also specify an when an audio device is connected or disconnected.</li> </ul> -<h2 id="afw">New Android for Work Features</h2> -<p>This release includes the following new APIs for Android for Work:</p> +<h2 id="video">Video Features</h2> +<p>This preview adds new capabilities to the video processing APIs, including:</p> +<ul> +<li>New {@code android.media.MediaSync} class which helps applications to synchronously render +audio and video streams. The audio buffers are submitted in non-blocking fashion and are +returned via a callback. It also supports dynamic playback rate. +</li> +<li>New {@code MediaDrm.EVENT_SESSION_RECLAIMED} event, which indicates that a session opened by +the app has been reclaimed by the resource manager. If your app uses DRM sessions, you should +handle this event and make sure not to use a reclaimed session. +</li> +<li>New {@code MediaCodec.CodecException.ERROR_RECLAIMED} error code, which indicates that the +resource manager reclaimed the media resource used by the codec. With this exception, the codec +must be released, as it has moved to terminal state. +</li> +<li>New {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} interface to get a +hint for the max number of the supported concurrent codec instances. +</li> +<li>New {@code MediaPlayer.setPlaybackParams()} method to set the media playback rate for fast or +slow motion playback. It also stretches or speeds up the audio playback automatically in +conjunction with the video.</li> +</ul> + +<h2 id="camera">Camera Features</h2> +<p>This preview includes the following new APIs for accessing the camera’s flashlight and for +camera reprocessing of images:</p> + +<h3 id="flashlight">Flashlight API</h3> +<p>If a camera device has a flash unit, you can call the {@code CameraManager.setTorchMode()} +method to switch the flash unit’s torch mode on or off without opening the camera device. The app +does not have exclusive ownership of the flash unit or the camera device. The torch mode is turned +off and becomes unavailable whenever the camera device becomes unavailable, or when other camera +resources keeping the torch on become unavailable. Other apps can also call {@code setTorchMode()} +to turn off the torch mode. When the last app that turned on the torch mode is closed, the torch +mode is turned off.</p> + +<p>You can register a callback to be notified about torch mode status by calling the +{@code CameraManager.registerTorchCallback()} method. The first time the callback is registered, +it is immediately called with the torch mode status of all currently known camera devices with a +flash unit. If the torch mode is turned on or off successfully, the +{@code CameraManager.TorchCallback.onTorchModeChanged()} method is invoked.</p> + +<h3 id="reprocessing">Reprocessing API</h3> +<p>The {@link android.hardware.camera2 Camera2} API is extended to support YUV and private +opaque format image reprocessing. Your app determine if the reprocessing capabilities are available +via {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}. If a device supports reprocessing, +you can create a reprocessable camera capture session by calling +{@code CameraDevice.createReprocessableCaptureSession()}, and create requests for input +buffer reprocessing.</p> + +<p>Use the {@code ImageWriter} class to connect the input buffer flow to the camera reprocessing +input. To get an empty buffer, follow this programming model:</p> + +<ol> +<li>Call the {@code ImageWriter.dequeueInputImage()} method.</li> +<li>Fill the data into the input buffer.</li> +<li>Send the buffer to the camera by calling the {@code ImageWriter.queueInputImage()} method.</li> +</ol> + +<p>If you are using a {@code ImageWriter} object together with an +{@code android.graphics.ImageFormat.PRIVATE} image, your app cannot access the image +data directly. Instead, pass the {@code ImageFormat.PRIVATE} image directly to the +{@code ImageWriter} by calling the {@code ImageWriter.queueInputImage()} method without any +buffer copy.</p> + +<p>The {@code ImageReader} class now supports {@code android.graphics.ImageFormat.PRIVATE} format +image streams. This support allows your app to maintain a circular image queue of +{@code ImageReader} output images, select one or more images, and send them to the +{@code ImageWriter} for camera reprocessing.</p> + +<h2 id="afw">Android for Work Features</h2> +<p>This preview includes the following new APIs for Android for Work:</p> <ul> <li><strong>Enhanced controls for Corporate-Owned, Single-Use devices:</strong> The Device Owner can now control the following settings to improve management of @@ -325,13 +460,13 @@ without user interaction.</li> <li><strong>Auto-acceptance of system updates.</strong> By setting a system update policy with {@code DevicePolicyManager.setSystemUpdatePolicy()}, a Device Owner can now auto-accept a system update, for instance in the case of a kiosk device, or postpone the update and prevent it being -taken by the user for up to 30 days. Furthermore, an administrator can set a time window in which an -update must be taken, for example during the hours when a kiosk device is not in use. When a -system update is available, the system checks if the Work Policy Controller app has set a system +taken by the user for up to 30 days. Furthermore, an administrator can set a daily time window in +which an update must be taken, for example during the hours when a kiosk device is not in use. When +a system update is available, the system checks if the Work Policy Controller app has set a system update policy, and behaves accordingly. </li> <li> -<strong>Delegated certificate installation.</strong> A Profile or Device Owner can now grant a +<strong>Delegated certificate installation:</strong> A Profile or Device Owner can now grant a third-party app the ability to call these {@link android.app.admin.DevicePolicyManager} certificate management APIs: <ul> @@ -349,21 +484,49 @@ uninstallAllUserCaCerts()}</li> installKeyPair()}</li> </ul> </li> -<li><strong>Enterprise factory reset protection.</strong> When provisioning a Device Owner, you can -now configure parameters for bypassing Factory Reset Protection (FRP), by setting the +<li><strong>Enterprise factory reset protection:</strong> When provisioning a Device Owner, you can +now configure parameters to unlock Factory Reset Protection (FRP) by setting the {@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} bundle. An NFC Programmer -app can provide these parameters after a device has been reset to bypass FRP and provision the device, +app can provide these parameters after a device has been reset to unlock FRP and provision the device, without requiring the previously configured Google account. If you don't modify these parameters, FRP remains in-place and prevents the device from being activated without the previously activated -Google credentials.</li> -<li><strong>Data usage tracking.</strong> A Profile or Device Owner can now query for the data -usage statistics visible in <em>Settings > Data</em> usage by using the new +Google credentials. +<p>Additionally, by setting app restrictions on Google Play services, Device Owners can specify +alternative Google accounts for unlocking FRP to replace the ones activated on the device.</p> +</li> +<li><strong>Data usage tracking.</strong> A Profile or Device Owner can now query for the +data usage statistics visible in <strong>Settings > Data</strong> usage by using the new {@code android.app.usage.NetworkStatsManager} methods. Profile Owners are automatically granted permission to query data on the profile they manage, while Device Owners get access to usage data of the managed primary user.</li> +<li><strong>Runtime permission management:</strong> With the new runtime permissions model, a +Profile or Device Owner can now silently grant or revoke an app’s permissions by calling +{@code DevicePolicyManager.setPermissionGranted()}. Granting or revoking a single permission applies +that setting to all permissions within that runtime permission group; the user is not prompted +at runtime when any permission from that runtime permission group is required. Furthermore, the +user cannot modify the selection made by the Profile or Device Owner within the app’s permissions +screen in <strong>Settings</strong>. +<img src="{@docRoot}preview/images/work-profile-screen_2x.png" +srcset="{@docRoot}preview/images/work-profile-screen.png 1x, preview/images/work-profile-screen_2x.png 2x" +style="float:right; margin:0 0 10px 20px" width="282" height="476" /> +<p>A Profile or Device Owner can also set a permission policy +for all runtime requests of all applications using +{@code DevicePolicyManager.setPermissionPolicy()}, to either prompt the user to grant the +permission as normal or automatically grant or deny the permission silently. If the latter policy +is set, the user cannot modify the selection made by the Profile or Device Owner within the +app’s permissions screen in <strong>Settings</strong>.</p></li> +<li><strong>VPN in Settings:</strong> VPN apps are now visible in + <strong>Settings > More > VPN</strong>. +Additionally, the notifications that accompany VPN usage are now specific to whether that VPN is +configured for a managed profile or the entire device.</li> +<li><strong>Work status notification:</strong> A status bar briefcase icon now appears whenever +an app from the managed profile has an activity in the foreground. Furthermore, if the device is +unlocked directly to the activity of an app in the managed profile, a toast is displayed notifying +the user that they are within the work profile. +</li> </ul> <p class="note"> For a detailed view of all API changes in the M Developer Preview, see the <a href= - "{@docRoot}preview/reference.html">API Differences Report</a>. + "{@docRoot}preview/download.html">API Differences Report</a>. </p>
\ No newline at end of file diff --git a/docs/html/preview/backup/index.jd b/docs/html/preview/backup/index.jd index 8610b82..5953e30 100644 --- a/docs/html/preview/backup/index.jd +++ b/docs/html/preview/backup/index.jd @@ -1,5 +1,6 @@ page.title=Auto Backup for Apps -page.tags=backup +page.tags=backup, previewresources, androidm +page.keywords=backup, autobackup, preview @jd:body diff --git a/docs/html/preview/behavior-changes.jd b/docs/html/preview/behavior-changes.jd new file mode 100644 index 0000000..0dd549b --- /dev/null +++ b/docs/html/preview/behavior-changes.jd @@ -0,0 +1,407 @@ +page.title=Behavior Changes +page.keywords=preview,sdk,compatibility +sdk.platform.apiLevel=23 +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>In this document</h2> + +<ol id="toc44" class="hide-nested"> + <li><a href="#behavior-runtime-permissions">Runtime Permissions</a></li> + <li><a href="#behavior-project-volta">Project Volta</a> + <ol> + <li><a href="#behavior-doze">Doze mode</a></li> + <li><a href="#behavior-app-standby">App Standby</a></li> + </ol> + </li> + <li><a href="#behavior-adoptable-storage">Adoptable Storage Devices</a></li> + <li><a href="#behavior-apache-http-client">Apache HTTP Client Removal</a></li> + <li><a href="#behavior-audiomanager-Changes">AudioManager Changes</a></li> + <li><a href="#behavior-test-selection">Text Selection</a></li> + <li><a href="#behavior-keystore">Android Keystore Changes</a></li> + <li><a href="#night-mode">Night Mode</a></li> + <li><a href="#behavior-network">Wi-Fi and Networking Changes</a></li> + <li><a href="#behavior-camera">Camera Service Changes</a></li> + <li><a href="#behavior-art-runtime">ART Runtime</a></li> + <li><a href="#behavior-apk-validation">APK Validation</a></li> + <li><a href="#behavior-afw">Android for Work Changes</a></li> +</ol> + +<h2>API Differences</h2> +<ol> +<li><a href="{@docRoot}preview/download.html">API level 22 to M Preview »</a> </li> +</ol> + + +<h2>See Also</h2> +<ol> +<li><a href="{@docRoot}preview/api-overview.html">M Developer Preview API Overview</a> </li> +</ol> + +</div> +</div> + +<p>API Level: M</p> +<p>Along with new features and capabilities, the M Developer Preview includes a variety of +system changes and API behavior changes. This document highlights +some of the key changes that you should be understand and account for in your apps.</p> + +<p>If you have previously published an app for Android, be aware that your app + might be affected by these changes in the platform.</p> + +<h2 id="behavior-runtime-permissions">Runtime Permissions</h1> +<p>This preview introduces a new runtime permissions model, where users can now directly manage +their app permissions at runtime. This model gives users improved visibility and control over +permissions, while streamlining the installation and auto-update processes for app developers. +Users can set permissions on or off for all apps running on the M Preview. However, apps that +don’t target the M Preview cannot request permissions at runtime.</p> + +<p>On your apps that target the M Preview, make sure to check and request for permissions at +runtime. To determine if your app has been granted a permission, call the +new {@code Context.checkSelfPermission()} method. To request for a permission, call the new +{@code Activity.requestPermission()} method.</p> + +<p>For more information on supporting the new permissions model in your app, see +<a href="{@docRoot}preview/features/runtime-permissions.html"> +Android M Preview Runtime Permissions</a>.</p> + +<h2 id="behavior-project-volta">Project Volta</h2> +<p>This preview introduces new power-saving optimizations for idle devices and apps.</p> + +<h3 id="behavior-doze">Doze mode</h3> +<p>If a device is unplugged and left stationary with the screen off for a period of time, it +goes into <em>Doze</em> mode where it attempts to keep the system in a sleep state. In this mode, +devices periodically resume normal operations for brief periods of time so that app syncing can +occur and the system can perform any pending operations.</p> + +<p>The following restrictions apply to your apps while in Doze mode:</p> +<ul> +<li>Network access is disabled, unless your app receives a high priority Google Cloud Messaging +tickle.</li> +<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake locks</a> are ignored.</li> +<li>Alarms scheduled with the {@link android.app.AlarmManager} class are disabled, except for +alarms that you've set with the {@link android.app.AlarmManager#setAlarmClock setAlarmClock()} +method and {@code AlarmManager.setAndAllowWhileIdle()}.</li> +<li>WiFi scans are not performed.</li> +<li>Syncs and jobs for your sync adapters and {@link android.app.job.JobScheduler} are not +permitted to run.</li> +</ul> +</p> +<p>When the device exists doze mode, it executes any jobs and syncs that are pending.</p> +<p>You can test this feature by connecting a device running the M Preview to your development +machine and calling the following commands: +</p> +<pre class="no-prettyprint"> +$ adb shell dumpsys battery unplug +$ adb shell dumpsys deviceidle step +$ adb shell dumpsys deviceidle -h +</pre> +<p class="note"><strong>Note</strong>: The upcmoning +<a href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> release lets you designate +high-priority messages. If your app receives high-priority GCM messages, it’s granted +brief network access even when the device is in doze mode. +</p> + +<h3 id="behavior-app-standby">App standby</h3> +<p>With this preview, the system may determine that apps are idle when they are not in active +use. Your app is considered idle after a period of time, unless the system detects +any of these signals:</p> + +<ul> +<li>The app has a process currently in the foreground (either as an activity or foreground service, +or in use by another activity or foreground service).</li> +<li>The app generates a notification that users see on the lock screen or in the +notification tray.</li> +<li>The user explicitly asks for the app to be exempt from optimizations, +via <strong>Settings</strong>.</li> +</ul> + +<p>If the device is unplugged, apps deemed idle will have their network access disabled +and their syncs and jobs suspended. When the device is plugged into a power supply, these apps are +allowed network access and can execute any jobs and syncs that are pending. If the +device is idle for long periods of time, idle apps are allowed network access around once a day.</p> + +<p>You can test this feature by connecting a device running the M Preview to your development +machine and calling the following commands: +</p> +<pre class="no-prettyprint"> +$ adb shell am broadcast -a android.os.action.DISCHARGING +$ adb shell am set-idle <packageName> true +$ adb shell am set-idle <packageName> false +$ adb shell am get-idle <packageName> +</pre> + +<p class="note"><strong>Note</strong>: The upcoming +<a href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> (GCM) release lets you +designate high-priority messages. If your app receives high-priority GCM messages, it’s granted +brief network access even when the app is idle. +</p> + +<h2 id="behavior-adoptable-storage">Adoptable Storage Devices</h2> +<p> +With this preview, users can <em>adopt</em> external storage devices such as SD cards. Adopting an +external storage device encrypts and formats the device to behave like internal storage. This +feature allows users to move both apps and private data of those apps between storage devices. When +moving apps, the system respects the +<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> +preference in the manifest.</p> + +<p>If your app accesses the following APIs or fields, be aware that the file paths they return +will dynamically change when the app is moved between internal and external storage devices. +When building file paths, it is strongly recommended that you always call these APIs dynamically. +Don’t use hardcoded file paths or persist fully-qualified file paths that were built previously.</p> + +<ul> +<li>{@link android.content.Context} methods: + <ul> + <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li> + <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li> + <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li> + <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li> + <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li> + <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li> + <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li> + <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li> + <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li> + </ul> +</li> +<li>{@link android.content.pm.ApplicationInfo} fields: + <ul> + <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li> + <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li> + <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li> + <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li> + <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li> + <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li> + </ul> +</li> +</ul> + +<p>To debug this feature in the developer preview, you can enable adoption of a USB drive that is +connected to an Android device through a USB On-The-Go (OTG) cable, by running this command:</p> + +<pre class="no-prettyprint"> +$ adb shell sm set-force-adoptable true +</pre> + +<h2 id="behavior-apache-http-client">Apache HTTP Client Removal</h2> +<p>This preview removes support for the Apache HTTP client. If your app is using this client and +targets Android 2.3 (API level 9) or higher, use the {@link java.net.HttpURLConnection} class +instead. This API is more efficient because it reduces network use through transparent compression +and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you +must first declare the following compile-time dependency in your {@code build.gradle} file: +</p> +<pre> +android { + useLibrary 'org.apache.http.legacy' +} +</pre> +<p>Android is moving away from OpenSSL to the +<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> +library. If you’re using the Android NDK in your app, don't link against cryptographic libraries +that are not a part of the NDK API, such as {@code libcrypto.so} and {@code libssl.so}. These +libraries are not public APIs, and may change or break without notice across releases and devices. +In addition, you may expose yourself to security vulnerabilities. Instead, modify your +native code to call the Java cryptography APIs via JNI or to statically link against a +cryptography library of your choice.</p> + +<h2 id="behavior-audiomanager-Changes">AudioManager Changes</h2> +<p>Setting the volume directly or muting specific streams via the {@link android.media.AudioManager} +class is no longer supported. The {@link android.media.AudioManager#setStreamSolo(int,boolean) +setStreamSolo()} method is deprecated, and you should call the +{@code AudioManager.requestAudioFocus()} method instead. Similarly, the +{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} method is +deprecated; instead, call the {@code AudioManager.adjustStreamVolume()} method +and pass in the direction value {@code ADJUST_MUTE} or {@code ADJUST_UNMUTE}.</p> + +<h2 id="behavior-test-selection">Text Selection</h2> + +<img src="{@docRoot}preview/images/text-selection.gif" +style="float:right; margin:0 0 20px 30px" width="360" height="640" /> + +<p>When users select text in your app, you can now display text selection actions such as +<em>Cut</em>, <em>Copy</em>, and <em>Paste</em> in a +<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" +class="external-link">floating toolbar</a>. The user interaction implementation is similar to that +for the contextual action bar, as described in +<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews"> +Enabling the contextual action mode for individual views</a>.</p> + +<p>To implement a floating toolbar for text selection, make the following changes in your existing +apps:</p> +<ol> +<li>In your {@link android.view.View} or {@link android.app.Activity} object, change your +{@link android.view.ActionMode} calls from +{@code startActionMode(Callback)} to {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li> +<li>Take your existing implementation of {@code ActionMode.Callback} and make it extend +{@code ActionMode.Callback2} instead.</li> +<li>Override the {@code Callback2.onGetContentRect()} method to provide the coordinates of the +content {@link android.graphics.Rect} object (such as a text selection rectangle) in the view.</li> +<li>If the rectangle positioning is no longer valid, and this is the only element to be invalidated, +call the {@code ActionMode.invalidateContentRect()} method.</li> +</ol> + +<p>If you are using <a href="{@docRoot}tools/support-library/index.html"> +Android Support Library</a> revision 22.2, be aware that floating toolbars are not +backward-compatible and appcompat takes control over {@link android.view.ActionMode} objects by +default. This prevents floating toolbars from being displayed. To enable +{@link android.view.ActionMode} support in an +{@link android.support.v7.app.AppCompatActivity}, call +{@code android.support.v7.app.AppCompatActivity.getDelegate()}, then call +{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} on the returned +{@link android.support.v7.app.AppCompatDelegate} object and set the input +parameter to {@code false}. This call returns control of {@link android.view.ActionMode} objects to +the framework. In devices running the M Preview, that allows the framework to support +{@link android.support.v7.app.ActionBar} or floating toolbar modes, while on pre-M Preview devices, +only the {@link android.support.v7.app.ActionBar} modes are supported.</p> + +<h2 id="behavior-keystore">Android Keystore Changes</h2> +<p>With this preview, the +<a href="{@docRoot}training/articles/keystore.html">Android Keystore provider</a> no longer supports +DSA. ECDSA is still supported.</p> + +<p>Keys which do not require encryption at rest will no longer be deleted when secure lock screen +is disabled or reset (for example, by the user or a Device Administrator). Keys which require +encryption at rest will be deleted during these events.</p> + +<h2 id="night-mode">Night Mode (User-configurable Dark Theme)</h2> +<p> +Support for the {@code -night} resource qualifier has been updated. Previously, night mode was +only available when a device was docked and in car mode. With this preview, night mode is +available on +all devices and is user-configurable via <strong>Settings > Display > Theme</strong>. You can adjust +this setting globally using {@link android.app.UiModeManager#setNightMode(int) setNightMode()}. The +Dark theme corresponds to {@link android.app.UiModeManager#MODE_NIGHT_YES}. When the device is in +night mode, the resource framework prefers resources that have the {@code -night} qualifier. To +take advantage of user-configurable Dark mode in your app, extend from the +{@code Theme.Material.DayNight} set of themes rather than {@code Theme.Material} or +{@code Theme.Material.Light}. +</p> + +<h2 id="behavior-network">Wi-Fi and Networking Changes</h2> + +<p>This preview introduces the following behavior changes to the Wi-Fi and networking APIs.</p> +<ul> +<li>Your apps can now change the state of {@link android.net.wifi.WifiConfiguration} objects only +if you created these objects. You are not permitted to modify or delete +{@link android.net.wifi.WifiConfiguration} objects created by the user or by other apps. +</li> +<li> +Previously, if an app forced the device to connect to a specific Wi-Fi network by using +{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} with the +{@code disableAllOthers=true} setting, the device disconnected from other networks such as +cellular data. In this preview, the device no longer disconnects from such other networks. If +your app’s {@code targetSdkVersion} is {@code “20”} or lower, it is pinned to the selected +Wi-Fi network. If your app’s {@code targetSdkVersion} is {@code “21”} or higher, use the +multinetwork APIs (such as +{@link android.net.Network#openConnection(java.net.URL) openConnection()}, +{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()}, and the new +{@code ConnectivityManager.bindProcessToNetwork()} method) to ensure that its network traffic is +sent on the selected network.</li> +</ul> + +<h2 id="behavior-camera">Camera Service Changes</h2> +<p>In this preview, the model for accessing shared resources in the camera service has been changed +from the previous “first come, first serve” access model to an access model where high-priority +processes are favored. Changes to the service behavior include:</p> +<ul> +<li>Access to camera subsystem resources, including opening and configuring a camera device, is +awarded based on the “priority” of the client application process. Application processes with +user-visible or foreground activities are generally given a higher-priority, making camera resource +acquisition and use more dependable.</li> +<li>Active camera clients for lower priority apps may be “evicted” when a higher priority +application attempts to use the camera. In the deprecated {@link android.hardware.Camera} API, +this results in +{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} being +called for the evicted client. In the {@link android.hardware.camera2 Camera2} API, it results in +{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()} +being called for the evicted client.</li> +<li>On devices with appropriate camera hardware, separate application processes are able to +independently open and use separate camera devices simultaneously. However, multi-process use +cases, where simultaneous access causes significant degradation of performance or capabilities of +any of the open camera devices, are now detected and disallowed by the camera service. This change +may result in “evictions” for lower priority clients even when no other app is directly +attempting to access the same camera device. +</li> +<li> +Changing the current user causes active camera clients in apps owned by the previous user account +to be evicted. Access to the camera is limited to user profiles owned by the current device user. +In practice, this means that a “Guest” account, for example, will not be able to leave running +processes that use the camera subsystem when the user has switched to a different account. +</li> +</ul> + +<h2 id="behavior-art-runtime">ART Runtime</h2> +<p>The ART runtime now properly implements access rules for the +{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} method. This +change fixes a problem where Dalvik was checking access rules incorrectly in previous versions. +If your app uses the +{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} method and you +want to override access checks, call the +{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} method with the input +parameter set to {@code true}. If your app uses the +<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat library</a> or the +<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview library</a>, +you must update your app to use to the latest versions of these libraries. Otherwise, make sure that +any custom classes referenced from XML are updated so that their class constructors are accessible.</p> + +<p>This preview updates the behavior of the dynamic linker. The dynamic linker now understands the +difference between a library’s {@code soname} and its path +(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link"> +public bug 6670</a>), and search by {@code soname} is now +implemented. Apps which previously worked that have bad {@code DT_NEEDED} entries +(usually absolute paths on the build machine’s file system) may fail when loaded.</p> + +<p>The {@code dlopen(3) RTLD_LOCAL} flag is now correctly implemented. Note that +{@code RTLD_LOCAL} is the default, so calls to {@code dlopen(3)} that didn’t explicitly use +{@code RTLD_LOCAL} will be affected (unless your app explicitly used {@code RTLD_GLOBAL}). With +{@code RTLD_LOCAL}, symbols will not be made available to libraries loaded by later calls to +{@code dlopen(3)} (as opposed to being referenced by {@code DT_NEEDED} entries).</p> +</p> + +<h2 id="behavior-apk-validation">APK Validation</h2> +<p>The platform now performs stricter validation of APKs. An APK is considered corrupt if a file is +declared in the manifest but not present in the APK itself. An APK must be re-signed if any of the +contents are removed.</p> + +<h2 id="behavior-afw">Android for Work Changes</h2> +<p>This preview includes the following behavior changes for Android for Work:</p> +<ul> +<li><strong>Work contacts in personal contexts.</strong> The Google Dialer +Call Log now displays work contacts when the user views past calls. Both +work and personal contacts are now available to devices over Bluetooth, but you can hide work +profile contacts through a device policy by calling the new +{@code DevicePolicyManager.setBluetoothContactSharingDisabled()} method. Initiating a call still +shows personal contacts, as consistent with the experience in Android 5.0. +</li> +<li><strong>WiFi configuration removal:</strong> WiFi configurations added by a Profile Owner +(for example, through calls to the +{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration) +addNetwork()} method) are now removed if that work profile is deleted.</li> +<li><strong>WiFi configuration lockdown:</strong> Any WiFi configuration created by an active Device +Owner can no longer be modified or deleted by the user. The user can still create and +modify their own WiFi configurations, so long as the {@link android.os.UserManager} constant +{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} has not been set for that user.</li> +<li><strong>Download Work Policy Controller via Google account addition:</strong> When a Google +account that requires management via a Work Policy Controller (WPC) app is added to a device +outside of a managed context, the add account flow now prompts the user to install the +appropriate WPC. This behavior also applies to accounts added via +<strong>Settings > Accounts</strong> in the initial device setup wizard.</li> +<li><strong>Changes to specific DevicePolicyManager API behaviors:</strong> +Calling the {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} +method affects the camera for the calling user only; calling it from the managed profile doesn’t +affect camera apps running on the primary user. In addition, the +{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} +method is now available for Profile Owners, in addition to Device Owners. A Profile Owner can set +these keyguard restrictions: +<ul> +<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} and + {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, which affect the + keyguard settings for the profile’s parent user.</li> +<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, which + only affects notifications generated by applications in the managed profile.</li> +</ul> +</li> +</ul> diff --git a/docs/html/preview/download.jd b/docs/html/preview/download.jd index 4341f8d..8a67a9a 100644 --- a/docs/html/preview/download.jd +++ b/docs/html/preview/download.jd @@ -1,4 +1,4 @@ -page.title=Download +page.title=Downloads page.image=images/cards/card-download_16-9_2x.png @jd:body diff --git a/docs/html/preview/features/app-linking.jd b/docs/html/preview/features/app-linking.jd new file mode 100644 index 0000000..c516f35 --- /dev/null +++ b/docs/html/preview/features/app-linking.jd @@ -0,0 +1,112 @@ +page.title=App Linking + +@jd:body + + +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#web-assoc">Declare a Website Association</a></li> + <li><a href="#verfy-links">Request App Link Verification</a></li> + <li><a href="#user-manage">Managing App Link Settings</a></li> + </ol> + </div> +</div> + +<p> + The Android Intent system is a flexible mechanism to enable apps to handle content and requests. + Multiple apps may declare matching URI patterns in their intent filters. When a user clicks on a + web link that does not have default launch handler, the platform may show a dialog for the user + to select from a list of apps that have declared matching intent filters. +</p> + +<p> + The Android M Developer Preview introduces support for app linking, which improves upon existing + link handling by allowing app developers to associate an app with a web domain they own. When + developers create this association, the platform can automatically determine the default app used + to handle a particular web link and skip asking users. +</p> + + +<h2 id="web-assoc">Declare a Website Association</h2> + +<p> + Website owners must declare associations with apps to establish an app link. The site owner + declares the relationship to an app by hosting a JSON file, named {@code statements.json}, at the + well-known location on the domain: +</p> + +<pre>http://<domain>:<optional port>/.well-known/statements.json</pre> + +<p class="note"> + <strong>Note:</strong> + During the M Developer Preview period, the JSON file is verified via http protocol. For + the official release of the platform, the file is verified over encrypted, https protocol. +</p> + +<p> + This JSON file indicates the Android app that should be used as the default handler for the URLs + under this domain. It identifies the app based on these fields: +</p> + +<ul> + <li>{@code package_name}: The package name declared in the app's manifest.</li> + + <li>{@code sha256_cert_fingerprints}: The SHA256 fingerprint of your app’s signing certificate. + You can use the Java keytool to generate the fingerprint using the following command: + <pre>keytool -list -v -keystore my-release-key.keystore</pre> + </li> +</ul> + +<p> + The following file listing shows an example of the contents and format of a + {@code statements.json} file: +</p> + +<pre> +[{ + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "<strong><package name></strong>", + "sha256_cert_fingerprints": ["<strong>6C:EC:C5:0E:34:AE....EB:0C:9B</strong>"] + } +}] +</pre> + + +<h2 id="verfy-links">Request App Link Verification</h2> + +<p> + An app can indicate to the platform to verify app links against the {@code statements.json} files + hosted on the sites defined by the host names in the <data> elements of the intent filters. + To do this, add an {@code android:autoVerify} attribute to the appropriate intent filters in the + manifest, as shown in the following manifest code snippet: +</p> + +<pre> +<activity ...> + <intent-filter <strong>android:autoVerify="true"</strong>> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + <data android:scheme="http" android:host="www.android.com" /> + <data android:scheme="https" android:host="www.android.com" /> + </intent-filter> +</activity> +</pre> + +<p> + When an app is installed, the platform attempts to verify the app links. If the platform cannot + successfully verify app links, it falls back to prompting the user the next time they open a link + that the app handles, or they will need to explicitly enable the app in the App Info settings UI. +</p> + +<h2 id="user-manage">Managing App Link Settings</h2> + +<p> + Users can change app link settings so URLs are handled the way they prefer. You can review and + manage app links in the system Settings app, under <strong>Settings > Apps > App Info > + Open by default</strong>. +</p> diff --git a/docs/html/preview/features/images/app-permissions-screen.png b/docs/html/preview/features/images/app-permissions-screen.png Binary files differnew file mode 100644 index 0000000..679b7ad --- /dev/null +++ b/docs/html/preview/features/images/app-permissions-screen.png diff --git a/docs/html/preview/features/images/app-permissions-screen@2x.png b/docs/html/preview/features/images/app-permissions-screen@2x.png Binary files differnew file mode 100644 index 0000000..e3eb13f --- /dev/null +++ b/docs/html/preview/features/images/app-permissions-screen@2x.png diff --git a/docs/html/preview/features/runtime-permissions.jd b/docs/html/preview/features/runtime-permissions.jd index 4a01010..2ee44ef 100644 --- a/docs/html/preview/features/runtime-permissions.jd +++ b/docs/html/preview/features/runtime-permissions.jd @@ -1,15 +1,53 @@ -page.title=Android M Preview Runtime Permissions - +page.title=Runtime Permissions +page.tags=previewresources, androidm +page.keywords=permissions, runtime, preview @jd:body +<div id="qv-wrapper"> + <div id="qv"> + <h2>Quickview</h2> + <ul> + <li>If your app targets the M Preview SDK, it prompts users to grant + permissions at runtime, instead of install time.</li> + <li>Users can revoke permissions at any time from the app Settings + screen.</li> + <li>Your app needs to check that it has the permissions it needs every + time it runs.</li> + </ul> + + <h2>In this document</h2> + <ol> + <li><a href="#overview">Overview</a></li> + <li><a href="#coding">Coding for Runtime Permissions</a></li> + <li><a href="#testing">Testing Runtime Permissions</a></li> + <li><a href="#best-practices">Best Practices</a></li> + </ol> + +<!-- + <h2>Related Samples</h2> + <ol> + <li></li> + </ol> +--> + +<!-- + <h2>See also</h2> + <ol> + <li></li> + </ol> +--> + </div> <!-- qv --> +</div> <!-- qv-wrapper --> + + <p> - The M Developer Preview introduces a new app permissions model which makes it - less frustrating for users to install and upgrade apps. If an app running on - M supports the new permissions model, the user does not have to grant any - permissions when they install or upgrade the app. Instead, the app requests - permissions as they are needed, and the system shows a dialog to the user - asking for the permission. + The M Developer Preview introduces a new app permissions model which + streamlines the process for users to install and upgrade apps. If an app + running on the M Preview supports the new permissions model, the user does not have to + grant any permissions when they install or upgrade the app. Instead, the app + requests permissions as it needs them, and the system shows a dialog to the + user asking for the permission. </p> <p> @@ -18,70 +56,122 @@ page.title=Android M Preview Runtime Permissions model on those devices. </p> -<h2> +<h2 id="overview"> Overview </h2> <p> - If an app's target SDK version is the M developer preview, that indicates - that the app uses the new permissions model: + With the M Developer Preview, the platform introduces a new app permissions + model. Here's a summary of the key components of this new model: </p> <ul> - <li>Permissions are divided into <em>permission groups</em>, based on their - functionality. For example, all permissions relating to the camera and photo - roll are grouped in the Camera permission group, - [link]android.permission-group.CAMERA[/link]. + <li> + <strong>Declaring Permissions:</strong> The app declares all the + permissions it needs in the manifest, as in earlier Android platforms. </li> - <li>The app declares all the permissions it needs in the manifest, as in - earlier Android platforms. + <li> + <strong>Permission Groups:</strong> Permissions are divided into + <em>permission groups</em>, based on their functionality. For example, the + <code>CONTACTS</code> permission group contains permissions to read and + write the user's contacts and profile information. </li> - <li>When the user installs or updates the app, the app is granted just those - permissions it requests that fall under <a href= - "https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_NORMAL"> - <code>PROTECTION_NORMAL</code></a>, as well as signature and system permissions, as - described below. The user is <em>not</em> prompted to grant any permissions - at this time. + <li> + <p><strong>Limited Permissions Granted at Install Time:</strong> When the + user installs or updates the app, the system grants the app all + permissions that the app requests that fall under {@link + android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}. + For example, alarm clock and internet permissions fall under {@link + android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}, so + they are automatically granted at install time. + </p> + + <p>The system may also grant the app signature and system permissions, as + described in <a href="#system-apps">System apps and signature + permissions</a>. The user is <em>not</em> prompted to grant any permissions + at install time.</p> </li> - <li>When the app needs to perform any action that requires a permission, it - first checks whether it has that permission already. If it does not, it - requests to be granted that permission. + <li> + <strong>User Grants Permissions at Run-Time:</strong> When the app requests + a permission, the system shows a dialog to the user, then calls the app's + callback function to notify it whether the permission was granted. If a + user grants a permission, the app is given all permissions in that + permission's functional area that were declared in the app manifest. </li> - <li>When the app requests a permission, the system shows a dialog box to the - user, then calls the app's callback function to notify it whether the - permission was granted. If a user grants a permission, the app is given all - permissions in that permission's functional area that were declared in the - app manifest. +</ul> + +<p> + This permission model changes the way your app behaves for features that + require permissions. Here's a summary of the development practices you should + follow to adjust to this model: +</p> + +<ul> + + <li> + <strong>Always Check for Permissions:</strong> When the app needs to + perform any action that requires a permission, it should first check + whether it has that permission already. If it does not, it requests to be + granted that permission. </li> - <li>If the app is not granted an appropriate permission, it should handle the - failure cleanly. For example, if the permission is just needed for an added - feature, the app can disable that feature. If the permission is essential for - the app to function, the app might disable all its functionality and inform - the user that they need to grant that permission. + <li> + <strong>Handle Lack of Permissions Gracefully:</strong> If the app is not + granted an appropriate permission, it should handle the failure cleanly. + For example, if the permission is just needed for an added feature, the app + can disable that feature. If the permission is essential for the app to + function, the app might disable all its functionality and inform the user + that they need to grant that permission. </li> - <li>Users can always go to the app's <b>Settings</b> screen and turn on or - off any of the app's permissions. - <!-- insert screenshot of settings screen--> - If a user turns off an app's permissions, the app is - <em>not</em> notified. + <div class="figure" style="width:220px"> + <img src="images/app-permissions-screen.png" srcset= + "images/app-permissions-screen@2x.png 2x" alt="" width="220" height= + "375"> + <p class="img-caption"> + <strong>Figure 2.</strong> Permission screen in the app's Settings. + </p> + </div> + + <li> + <strong>Permissions are Revocable:</strong> Users can revoke an app's + permissions at any time. If a user turns off an app's permissions, the app + is <em>not</em> notified. Once again, your app should verify that it has + needed permissions before performing any restricted actions. </li> </ul> -<h3> - System Apps and Signature Permissions +<p class="note"> + <strong>Note:</strong> If an app targets the M Developer Preview, it + <em>must</em> use the new permissions model. +</p> + +<p> + As of the launch of the M Developer Preview, not all Google apps fully + implement the new permissions model. Google is updating these apps over + the course of the M Developer Preview to properly respect Permissions toggle + settings. +</p> + +<p class="note"> + <strong>Note:</strong> If your app has its own API surface, do not proxy + permissions without first ensuring the caller has the requisite permissions + to access that data. +</p> + +<h3 id="system-apps"> + System apps and signature permissions </h3> <p> - Ordinarily, an app is just granted the <a href= - "https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_NORMAL"> - <code>PROTECTION_NORMAL</code></a> permissions when it is installed. However, - under some circumstances the app is granted more permissions: + Ordinarily, when the user installs an app, the system only grants the app the + {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL + PROTECTION_NORMAL}. However, under some circumstances the system grants the + app more permissions: </p> <ul> @@ -89,37 +179,130 @@ page.title=Android M Preview Runtime Permissions the permissions listed in its manifest. </li> - <li>Apps are granted all permissions listed in the manifest that fall under - <a href= - "https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_SIGNATURE"> - PROTECTION_SIGNATURE</a>, if the app's signature matches the signature of - the app that declares the permissions. + <li>If the app requests permissions in the manifest that fall under {@link + android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE}, + and the app is signed with the same certificate as the app that declared + those permissions, the system grants the requesting app those permissions on + installation. </li> </ul> <p> In both cases, the user can still revoke permissions at any time by going to - the app's <b>Settings</b> screen, so the app should continue to check for - permissions at run time and request them if necessary. + the system's <strong>Settings</strong> screen and choosing <strong>Apps + ></strong> <i>app_name</i> <strong>> Permissions</strong>. The app + should continue to check for permissions at run time and request them if + necessary. </p> -<h3> - Forwards and Backwards Compatibility +<h3 id="compatibility"> + Forwards and backwards compatibility </h3> <p> - If an app does not target the M developer preview, it continues to use the - old permissions model even on M devices. When the app is installed, the - system asks the user to grant all permissions listed in the app's manifest. + If an app does not target the M Developer Preview, the app continues to use + the old permissions model even on M Preview devices. When the user installs + the app, the system asks the user to grant all permissions listed in the + app's manifest. +</p> + +<p class="note"> + <strong>Note:</strong> On devices running the M Developer Preview, a user can + turn off permissions for any app (including legacy apps) from the app's + Settings screen. If a user turns off permissions for a legacy app, the system + silently disables the appropriate functionality. When the app attempts to + perform an operation that requires that permission, the operation will not + necessarily cause an exception. Instead, it might return an empty data set, + signal an error, or otherwise exhibit unexpected behavior. For example, if you + query a calendar without permission, the method returns an empty data set. +</p> + +<p> + If you install an app using the new permissions model on a device that is not + running the M Preview, + the system treats it the same as any other app: the system asks + the user to grant all declared permissions at install time. +</p> + +<p class="note"> + <strong>Note:</strong> For the preview release, you must set the minimum SDK + version to the M Preview SDK to compile with the preview SDK. This means you + will not be able to test such apps on older platforms during the developer + preview. +</p> + +<h3 id="perms-vs-intents">Permissions versus intents</h3> + +<p> + In many cases, you can choose between two ways for your app to perform a + task. You can have your app ask for permission to perform the operation + itself. Alternatively, you can have the app use an intent to have another app + perform the task. </p> <p> - If an app using the new permissions model is run on a pre-M device, the - system treats it the same as any other app. Once again, the system asks the - user to grant all declared permissions at install time. + For example, suppose your app needs to be able to take pictures with the + device camera. Your app can request the + <code>android.permission.CAMERA</code> permission, which allows your app to + access the camera directly. Your app would then use the camera APIs + to control the camera and take a picture. This approach gives your app full + control over the photography process, and lets you incorporate the camera UI + into your app. </p> -<h2 id="">Coding for Runtime Permissions</h2> +<p> + However, if you don't need such control, you can just use an {@link + android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} intent + to request an image. When you start the intent, the user is prompted to + choose a camera app (if there isn't already a default camera app), and that + app takes the picture. The camera app returns the picture to your app's {@link + android.app.Activity#onActivityResult onActivityResult()} method. +</p> + +<p> + Similarly, if you need to make a phone call, access the user's contacts, and + so on, you can do that by creating an appropriate intent, or you can request + the permission and access the appropriate objects directly. There are + advantages and disadvantages to each approach. +</p> + +<p> + If you use permissions: +</p> + +<ul> + <li>Your app has full control over the user experience when you perform the + operation. However, such broad control adds to the complexity of your task, + since you need to design an appropriate UI. + </li> + + <li>The user is prompted to give permission once, the first time you perform + the operation. After that, your app can perform the operation without + requiring additional interaction from the user. However, if the user doesn't + grant the permission (or revokes it later on), your app becomes unable to + perform the operation at all. + </li> +</ul> + +<p> + If you use an intent: +</p> + +<ul> + <li>You do not have to design the UI for the operation. The app that handles + the intent provides the UI. However, this means you have + no control over the user experience. The user could be interacting with an + app you've never seen. + </li> + + <li>If the user does not have a default app for the operation, the system + prompts the user to choose an app. If the user does not designate a default + handler, they may have to go + through an extra dialog every time they perform the operation. + </li> +</ul> + +<h2 id="coding">Coding for Runtime Permissions</h2> <p> If your app targets the new M Developer Preview, you must use the new @@ -129,44 +312,47 @@ page.title=Android M Preview Runtime Permissions have them. </p> -<h3> - Enabling the New Permissions Model +<h3 id="enabling"> + Enabling the new permissions model </h3> <p> To enable the new M Developer Preview permissions model, set the app's - <a href= - "http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"> - targetSdkVersion</a> attribute to "M". Doing this enables all the new - permissions features. + <code>targetSdkVersion</code> attribute to <code>"MNC"</code>, and + <code>compileSdkVersion</code> to <code>"android-MNC"</code>. Doing so + enables all the new permissions features. </p> -<!-- TODO: Insert manifest snippet --> +<p> + For the preview release, you must set <code>minSdkVersion</code> to + <code>"MNC"</code> to compile with the preview SDK. +</p> -<h3> - Designating a Permission for M Only +<h3 id="m-only-perm"> + Designating a permission for the M Preview only </h3> <p> - You can use the new <code><uses-permission-sdk-m></code> element in the - app manifest to indicate that a permission is only needed on the M platform. - If you declare a permission this way, then whenever the app is installed on - an older device, the user is not prompted to grant the permission and the - permission is not granted to the app. This allows you to add new permissions + You can use the new <code><uses-permission-sdk-m></code> element in the app manifest + to indicate that a permission is only needed on the M Developer Preview. If + you declare a permission this way, then whenever the app is installed on an + older device, the system does not prompt the user or grant the + permission to the app. By using the <code><uses-permission-sdk-m></code> + element, you can add new permissions to updated versions of your app without forcing users to grant permissions when they install the update. </p> <p> - If the app is running on a device with the M developer preview, + If the app is running on a device with the M Developer Preview, <code><uses-permission-sdk-m></code> behaves the same as - <code><uses-permission></code>. The user is not prompted to grant any - permissions when the app is installed, and the app requests permissions as - they are needed. + <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>. + The system does not prompt the user to grant any permissions when they install + the app, and the app requests permissions as they are needed. </p> <h3 id="prompting"> - Prompting for Permissions on the M Preview + Prompting for permissions </h3> <p> @@ -178,73 +364,348 @@ page.title=Android M Preview Runtime Permissions </p> <p> - An app should follow this workflow to request permissions on an Android M - device. The device can check what platform it's running on by checking the - value of {@link android.os.Build.VERSION#SDK_INT Build.VERSION.SDK_INT}. If - the device is running the M Developer Preview, {@link - android.os.Build.VERSION#SDK_INT SDK_INT} is 23. - <!-- TODO: Confirm this number --> + If your app runs on a device that has SDK 22 or lower, the app uses the old + permissions model. When the user installs the app, they are prompted to grant + all the permissions your app requests in its manifest, except for those + permissions which are labeled with <code><uses-permission-sdk-m></code>. </p> -<ol> - <li>When the user tries to do something that requires a permission, the app - checks to see if it currently has permission to perform this operation. To do - this, the app calls - <a href="https://android-preview.googleplex.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)"><code>Context.CheckSelfPermission(<em>permission_name</em>)</code></a> . The - app should do this even if it knows the user has already granted that - permission, since the user can revoke an app's permissions at any time. For - example, if a user wants to use an app to take a picture, the app calls - <a href="https://android-preview.googleplex.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)"><code>Context.CheckSelfPermission(Manifest.permission.CAMERA)</code></a>. - </li> -<!-- TODO: Full list of permissions (or link to that list), - and how they break down by functional area]--> +<h4 id="check-platform">Check what platform the app is running on</h4> - <li>If the permission is not already granted to the app, the app calls - <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a> to request the - appropriate permission or permissions. This method functions - asynchronously. - <!-- TODO: insert code snippet showing permission check and request --> - </li> +<p> + This permissions model is only supported on devices running the M Developer + Preview. Before calling any of these methods, the app should verify + what platform it's running on + by checking the value of {@link android.os.Build.VERSION#CODENAME + Build.VERSION.CODENAME}. If the device is running the M Developer Preview, + {@link android.os.Build.VERSION#CODENAME CODENAME} is <code>"MNC"</code>. +</p> - <li>The system presents a dialog box to the user. - <!-- TODO: insert screenshot of permissions dialog box --> - When the user responds, the system calls <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#onRequestPermissionsResult(int,%20java.lang.String[],%20int[])"> - <code>Activity.onRequestPermissionsResult()</code></a> with the - results; your app needs to override that method. The callback is passed the - same request code you passed to <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a>. - <!-- TODO: Insert code snippet of callback method --> - </li> +<h4 id="check-for-permission">Check if the app has the needed permission</h4> + +<p>When the user tries to do something that requires a permission, the app + checks to see if it currently has permission to perform this operation. To do + this, the app calls + <code>Context.checkSelfPermission(<i>permission_name</i>)</code>. The app + should perform this check even if it knows the user has already granted that + permission, + since the user can revoke an app's permissions at any time. For example, if a + user wants to use an app to take a picture, the app calls + <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.</p> + +<p class="table-caption" id="permission-groups"> + <strong>Table 1.</strong> Permissions and permission groups.</p> +<table> + <tr> + <th scope="col">Permission Group</th> + <th scope="col">Permissions</th> + </tr> + + <tr> + <td><code>android.permission-group.CALENDAR</code></td> + <td> + <ul> + <li> + <code>android.permission.READ_CALENDAR</code> + </li> + </ul> + <ul> + <li> + <code>android.permission.WRITE_CALENDAR</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.CAMERA</code></td> + <td> + <ul> + <li> + <code>android.permission.CAMERA</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.CONTACTS</code></td> + <td> + <ul> + <li> + <code>android.permission.READ_CONTACTS</code> + </li> + <li> + <code>android.permission.WRITE_CONTACTS</code> + </li> + <li> + <code>android.permission.READ_PROFILE</code> + </li> + <li> + <code>android.permission.WRITE_PROFILE</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.LOCATION</code></td> + <td> + <ul> + <li> + <code>android.permission.ACCESS_FINE_LOCATION</code> + </li> + <li> + <code>android.permission.ACCESS_COARSE_LOCATION</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.MICROPHONE</code></td> + <td> + <ul> + <li> + <code>android.permission.RECORD_AUDIO</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.PHONE</code></td> + <td> + <ul> + <li> + <code>android.permission.READ_PHONE_STATE</code> + </li> + <li> + <code>android.permission.CALL_PHONE</code> + </li> + <li> + <code>android.permission.READ_CALL_LOG</code> + </li> + <li> + <code>android.permission.WRITE_CALL_LOG</code> + </li> + <li> + <code>com.android.voicemail.permission.ADD_VOICEMAIL</code> + </li> + <li> + <code>android.permission.USE_SIP</code> + </li> + <li> + <code>android.permission.PROCESS_OUTGOING_CALLS</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.SENSORS</code></td> + <td> + <ul> + <li> + <code>android.permission.BODY_SENSORS</code> + </li> + </ul> + <ul> + <li> + <code>android.permission.USE_FINGERPRINT</code> + </li> + </ul> + </td> + </tr> + + <tr> + <td><code>android.permission-group.SMS</code></td> + <td> + <ul> + <li> + <code>android.permission.SEND_SMS</code> + </li> + <li> + <code>android.permission.RECEIVE_SMS</code> + </li> + <li> + <code>android.permission.READ_SMS</code> + </li> + <li> + <code>android.permission.RECEIVE_WAP_PUSH</code> + </li> + <li> + <code>android.permission.RECEIVE_MMS</code> + </li> + <li> + <code>android.permission.READ_CELL_BROADCASTS</code> + </li> + </ul> + </td> + </tr> + +</table> + +<h4 id="request-permissions">Request permissions if necessary</h4> + +<p>If the app doesn't already have the permission it needs, the app calls the + <code>Activity.requestPermissions(String[], int)</code> method to + request the appropriate permission or permissions. The app passes the + permission or permissions it wants, and also an integer "request code". + This method functions asynchronously: it returns right away, and after + the user responds to the dialog box, the system calls the app's callback + method with the results, passing the same "request code" that the app passed + to <code>requestPermissions()</code>.</p> + + <p>The following code code checks if the app has permission to read the + user's contacts, and requests the permission if necessary:</p> + +<pre> +if (checkSelfPermission(Manifest.permission.READ_CONTACTS) + != PackageManager.PERMISSION_GRANTED) { + requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, + MY_PERMISSIONS_REQUEST_READ_CONTACTS); + + // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an + // app-defined int constant + + return; +} +</pre> + +<h4 id="handle-response">Handle the permissions request response</h4> + +<p> + When an app requests permissions, the system presents a dialog box to the + user. When the user responds, the system invokes your app's + <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> + passing it the user response. Your app needs to override that method. The + callback is passed the same request code you passed to + <code>requestPermissions()</code>. For example, if an app requests + <code>READ_CONTACTS</code> access it might have the following callback + method: +</p> - <li>If the user grants a permission, the app is given all permissions - in that functional area that are listed in the app manifest. - If the request is denied, you should take appropriate action. For - example, you might disable any menu actions that depend on this permission. +<pre> +@Override +public void onRequestPermissionsResult(int requestCode, + String permissions[], int[] grantResults) { + switch (requestCode) { + case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + + // permission was granted, yay! do the + // calendar task you need to do. + + } else { + + // permission denied, boo! Disable the + // functionality that depends on this permission. + } + return; + } + + // other 'switch' lines to check for other + // permissions this app might request + } +} +</pre> + + <p>If the user grants a permission, the system gives the app all permissions + that the app manifest lists for that functional area. If the user denies the + request, you should take appropriate action. For example, you might disable + any menu actions that depend on this permission. </li> -</ul> +</p> <p> When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, - when an app asks for that permission with <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a>, the - system immediately denies the request. For this reason, your app cannot - assume that any direct interaction with the user has taken place. + when an app uses <code>requestPermissions()</code> to ask for that permission, + the system immediately denies the request. In this case, the system calls + your <code>onRequestPermissionsResult()</code> the same way it would if the + user had explicitly rejected your request again. For this reason, your app + cannot assume that any direct interaction with the user has taken place. </p> +<h2 id="testing">Testing Runtime Permissions</h2> + + <p> - If your app runs on a device that has SDK 22 or lower, the app uses the old - permissions model. When the user installs the app, they are prompted to grant - all the permissions your app requests in its manifest, except for those - permissions which are labeled with <code><uses-permission-sdk-m></code>. + If your app targets the M Developer Preview, you must test that it + handles permissions properly. You cannot assume that your app has any + particular permissions when it runs. When the app is first launched, it is + likely to have no permissions, and the user can revoke or restore permissions + at any time. +</p> + +<p> + You should test your app to make sure it behaves properly under all + permission situations. With the M Preview SDK, we have provided new + <a href="{@docRoot}tools/help/adb.html">Android + Debug Bridge (adb)</a> commands to enable you to test your app with whatever + permissions settings you need to try. +</p> + +<h3> + New adb commands and options +</h3> + +<p> + The M Preview SDK Platform-tools provides several new commands to let you test + how your app handles permissions. +</p> + +<h4> + Install with permissions +</h4> + +<p> + You can use the <a href="{@docRoot}tools/help/adb.html#move"><code>adb + install</code></a> command's new <code>-g</code> option, which installs the + app and grants all permissions listed in its manifest: </p> -<h2 id="">Best Practices</h2> +<pre class="no-pretty-print"> +$ adb install -g <path_to_apk> +</pre> + +<h4> + Grant and revoke permissions +</h4> + +<p> + You can use new ADB <a href="{@docRoot}tools/help/adb.html#pm">package manager + (pm)</a> commands to grant and revoke permissions to an installed app. + This functionality can be useful for automated testing. +</p> + +<p> + To grant a permission, use the package manager's <code>grant</code> command: +</p> + +<pre class="no-pretty-print"> +$ adb pm grant <package_name> <permission_name> +</pre> + +<p> + For example, to grant the com.example.myapp package permission to record + audio, use this command: +</p> + +<pre class="no-pretty-print"> +$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO +</pre> + +<p> + To revoke a permission, use the package manager's <code>revoke</code> command: +</p> + +<pre class="no-pretty-print"> +$ adb pm revoke <package_name> <permission_name> +</pre> + +<h2 id="best-practices">Best Practices</h2> <p> The new permissions model gives users a smoother experience, and makes it @@ -253,12 +714,32 @@ page.title=Android M Preview Runtime Permissions the new model. </p> -<h3> - Don't Overwhelm the User + +<h3 id="bp-what-you-need">Only ask for permissions you need</h3> + +<p> + Every time you ask for a permission, you force the user to make a decision. + If the user turns down the request, that reduces your app's functionality. + You should minimize the number of times you make these requests. +</p> + +<p> + For example, quite often your app can get needed functionality by using an + <a href="{@docRoot}guide/components/intents-filters.html">intent</a> instead + of asking for permissions. If your app needs to take pictures with the + phone's camera, your app can use a {@link + android.provider.MediaStore#ACTION_IMAGE_CAPTURE + MediaStore.ACTION_IMAGE_CAPTURE} intent. When your app executes the intent, the + system prompts the user to choose an already-installed camera app to take the + picture. +</p> + +<h3 id="bp-dont-overwhelm"> + Don't overwhelm the user </h3> <p> - If you confront the user with a lot of permissions requests at once, you may + If you confront the user with a lot of requests for permissions at once, you may overwhelm the user and cause them to quit your app. Instead, you should ask for permissions as you need them. </p> @@ -266,35 +747,30 @@ page.title=Android M Preview Runtime Permissions <p> In some cases, one or more permissions might be absolutely essential to your app. In that case, it might make sense to ask for all the permissions as soon - as the app launches. - <!-- TODO: insert screenshot of dialog box asking for several permissions --> - For example, if you make a photography app, the app would - need access to the device camera. When the user launches the app for the - first time, they won't be surprised to be asked to give permission to use the - camera. But if the same app also had a feature to share photos with the + as the app launches. For example, if you make a photography app, the app + would need access to the device camera. When the user launches the app for + the first time, they won't be surprised to be asked for permission to use + the camera. But if the same app also had a feature to share photos with the user's contacts, you probably should <em>not</em> ask for that permission at first launch. Instead, wait until the user tries to use the "sharing" feature and ask for the permission then. </p> <p> - If your app provides a tutorial, it may make sense to request app's essential + If your app provides a tutorial, it may make sense to request the app's essential permissions at the end of the tutorial sequence. </p> -<h3> - Explain Why You Need Permissions +<h3 id="bp-explain"> + Explain why you need permissions </h3> <p> - The permissions screen shown by the system when you call <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a> says what permission your app wants, - but doesn't say why you want it. In some cases, the user may find that - puzzling. It's a good idea to explain to the user why your app wants the - permissions before you call <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a>. + The permissions dialog shown by the system when you call + <code>requestPermissions()</code> says what permission your app wants, but + doesn't say why. In some cases, the user may find that puzzling. + It's a good idea to explain to the user why your app wants the permissions + before calling <code>requestPermissions()</code>. </p> <p> @@ -303,50 +779,17 @@ page.title=Android M Preview Runtime Permissions contain location information, and would be puzzled why their photography app wanted to know the location. So in this case, it's a good idea for the app to tell the user about this feature <em>before</em> calling - <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a>. + <code>requestPermissions()</code>. </p> <p> - As noted, one way to do this is to incorporate these requests into an app - tutorial. The tutorial can show each of the app's features in turn, and as it - does this, it can explain what permissions are needed. For example, the - photography app's tutorial demonstrate its "share photos with your contacts" - feature, then tell the user that they'll need to give permission for the app - to see the user's contacts, and <em>then</em> call <a href= - "https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)"> - <code>requestPermissions()</code></a> - to get that access. Of course, some users will want to skip the tutorial, so - you'll still need to check for and request permissions during the app's - normal operation. -</p> - -<h3> - Opt Out If Necessary -</h3> - -<p> - Until you are ready to use the new permissions model, you can opt out simply - by setting your app's <a href= - "http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"> - targetSdkVersion</a> to 22 or less. If you do this, the system will use the - old permissions model. When the user downloads the app, they will be prompted - to grant all the permissions listed in the manifest. -</p> - -<p> - With the M Developer Preview, users can turn off permissions for <em>any</em> - app from the app's Settings page, regardless of what SDK version the app - targets. For this reason, it's a good idea to follow the steps described in - <a href="#prompting">"Prompting for Permissions on the M Preview"</a> even if - your app doesn't fully support the new permissions model. -</p> - -<p class="note"> - <strong>Note:</strong> If a user turns off permissions for a legacy app, the system - silently disables the appropriate functionality. When the app attempts to - perform an operation that requires that permission, the operation will not - necessarily cause an exception. Instead, it might return an empty data set or - otherwise signal an error. + One way to do this is to incorporate these requests into an app tutorial. The + tutorial can show each of the app's features in turn, and as it does this, it + can explain what permissions are needed. For example, the photography app's + tutorial can demonstrate its "share photos with your contacts" feature, then + tell the user that they need to give permission for the app to see the user's + contacts. The app can then call <code>requestPermissions()</code> to ask the + user for that access. Of course, not every user is going to follow the + tutorial, so you still need to check for and request permissions during the + app's normal operation. </p> diff --git a/docs/html/preview/images/m-preview-timeline-crop.png b/docs/html/preview/images/m-preview-timeline-crop.png Binary files differnew file mode 100644 index 0000000..724a6af --- /dev/null +++ b/docs/html/preview/images/m-preview-timeline-crop.png diff --git a/docs/html/preview/images/perf-test-frame-latency.png b/docs/html/preview/images/perf-test-frame-latency.png Binary files differnew file mode 100644 index 0000000..87d1cfc --- /dev/null +++ b/docs/html/preview/images/perf-test-frame-latency.png diff --git a/docs/html/preview/images/perf-test-framestats.png b/docs/html/preview/images/perf-test-framestats.png Binary files differnew file mode 100644 index 0000000..589a923 --- /dev/null +++ b/docs/html/preview/images/perf-test-framestats.png diff --git a/docs/html/preview/images/work-profile-screen.png b/docs/html/preview/images/work-profile-screen.png Binary files differnew file mode 100644 index 0000000..c3e4e44 --- /dev/null +++ b/docs/html/preview/images/work-profile-screen.png diff --git a/docs/html/preview/images/work-profile-screen_2x.png b/docs/html/preview/images/work-profile-screen_2x.png Binary files differnew file mode 100644 index 0000000..5dcf610 --- /dev/null +++ b/docs/html/preview/images/work-profile-screen_2x.png diff --git a/docs/html/preview/index.jd b/docs/html/preview/index.jd index d9af7e0..c5644cc 100644 --- a/docs/html/preview/index.jd +++ b/docs/html/preview/index.jd @@ -8,28 +8,35 @@ footer.hide=1 @jd:body <section class="dac-expand dac-hero dac-light" > - <div class="wrap" style="max-width:1100px"> + <div class="wrap"> <div class="cols dac-hero-content"> <div class="col-9of16 col-push-7of16 dac-hero-figure"> - <img class="dac-hero-image" src="/images/home/devices-hero_620px_2x.png"> + <img class="dac-hero-image" src="{@docRoot}images/home/devices-hero_620px_2x.png" + srcset="{@docRoot}images/home/devices-hero_620px.png 1x, + {@docRoot}images/home/devices-hero_620px_2x.png 2x"> </div> - <div class="col-6of16 col-pull-8of16"> + <div class="col-7of16 col-pull-9of16"> <h1 class="dac-hero-title">Android M Developer Preview</h1> <p class="dac-hero-description"> Get ready for the next version of Android. Test your apps on Nexus 5, 6, 9, and Player. Explore what's new — a <strong>runtime permissions</strong> model, - power-saving <strong>Volta features</strong>, new <strong>assist technology</strong>, - and more. + power-saving <strong>Doze</strong> and <strong>Standby Mode</strong>, new + <strong>assist technology</strong>, and more. </p> - <a class="dac-hero-cta" href="/preview/overview.html"> + <a class="dac-hero-cta" href="{@docRoot}preview/overview.html"> <span class="dac-sprite dac-auto-chevron"></span> Get Started! </a><br> </div> </div> - - + <div class="dac-section dac-small"> + <div class="resource-widget resource-flow-layout col-16" + data-query="collection:preview/landing/resources" + data-cardSizes="6x2" + data-maxResults="6"></div> + </div> + </div> </section> @@ -40,34 +47,24 @@ footer.hide=1 </div> <section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> - <h2 class="norule">Resources</h2> -<div class="dac-section dac-small"> - <div class="resource-widget resource-flow-layout col-16" - data-query="collection:preview/landing/resources" - data-cardSizes="6x2" - data-maxResults="6"></div> - </div> - </div></section> - - - -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> - <h1 class="dac-section-title">Get your apps ready</h1> - <div class="dac-section-subtitle"> - Resources to help you learn about Android M and get your app ready. - </div> + <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" - data-query="collection:preview/landing/resources" + data-query="type:blog+tag:androidm,type:youtube+tag:androidm" data-cardSizes="6x6" - data-maxResults="6"></div> + data-maxResults="6" + data-initial-results="3"</div> </div></section> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> - <h2 class="norule">Latest</h2> +<section class="dac-section dac-light"><div class="wrap"> + <h1 class="dac-section-title">Resources</h1> + <div class="dac-section-subtitle"> + Essential information to help you get your apps ready for Android M. + </div> <div class="resource-widget resource-flow-layout col-16" - data-query="type:blog+tag:androidm,type:youtube+tag:androidm" + data-query="tag:previewresources" data-cardSizes="6x6" - data-maxResults="6" - data-initial-results="3"</div> + data-initial-results="6" + data-maxResults="16"></div> </div></section> + diff --git a/docs/html/preview/overview.jd b/docs/html/preview/overview.jd index e235d68..4c13fbc 100644 --- a/docs/html/preview/overview.jd +++ b/docs/html/preview/overview.jd @@ -1,39 +1,345 @@ -page.title=Preview Program Overview +page.title=Program Overview +page.metaDescription=Welcome to the Android M Developer Preview, a program that gives you everything you need to test and optimize your apps for the next version of Android. page.image=images/cards/card-preview_16-9_2x.png +page.tags="preview", "developer", "android" @jd:body <p> - The Android M platform is still under development, but we’re offering developers an early look - through the Android M Developer Preview program. This program is an opportunity for you to test - the compatibility of your apps with the next platform release, try out early versions of new API - features, and provide feedback to the Android team. Developers can try out the M Preview system - on with the Android SDK emulator or on Nexus 5, Nexus 6, Nexus 9, and Nexus Player devices. The - program includes update releases during course of the program to allow you to follow the progress - of feature development and fixes, leading up to the official release of the platform. + Welcome to the <strong>Android M Developer Preview</strong>, a program that gives you + everything you need to test and optimize your apps for the next version of + Android. It's free, and you can get started right away just by downloading + the M Developer Preview tools. </p> -<img src="{@docRoot}preview/images/m-preview-timeline.png" - alt="Preview program timeline" id="figure1" style="margin-top: 15px;"> -<p class="img-caption"> - Timeline for the M Developer Preview program. +<div style="background-color:#eceff1;padding:1em;"> +<div class="wrap"> + <div class="cols"> + <div class="col-4of12"> + <h5> + Hardware and emulator system images + </h5> + + <p> + Run and test your apps on Nexus 5, 6, 9, and Player (for TV), as well + as emulator. + </p> + </div> + + <div class="col-4of12"> + <h5> + Latest platform code + </h5> + + <p> + We’ll provide multiple updates during the Preview, so you’ll be testing + against the latest platform changes. + </p> + </div> + + <div class="col-4of12"> + <h5> + Updates delivered by OTA + </h5> + + <p> + You can get updates over the air, once you’ve flashed a + device to the initial preview. + </p> + </div> + </div> + + <div class="cols"> + +<!--<div class="col-4of12"> +<h5>Early access to new APIs</h5> +<p>Explore the new capabilities and APIs offered in the new platform and give us +feedback. Note that APIs and capabilities may change during the Preview +program.</p> +</div>--> + + <div class="col-4of12"> + <h5> + New behaviors and capabilities + </h5> + + <p> + Start work early to support new platform behaviors such as + the new runtime permissions model and power-saving features. + </p> + </div> + + <div class="col-4of12"> + <h5> + Priority window for developer-reported issues + </h5> + + <p> + During the first several weeks we’ll give priority to developer-reported + issues, so test and give feedback as soon as possible. + </p> + </div> + + <div class="col-4of12"> + <h5> + Feedback and support channels + </h5> + + <p> + Report issues and give us feedback using our <a href= + "https://code.google.com/p/android-developer-preview/">issue tracker</a>. + Connect with other developers in the <a + href="http://g.co/dev/AndroidMDevPreview">M Developer Community</a>. + </p> + </div> + </div> +</div> +</div> + +<!-- +<p> + With the M Developer Preview, you'll get an early start on testing your apps, + with enough time to make adjustments before the public platform release later + in the year. We'll provide several updates to the Preview tools in the weeks + ahead, so you can keep in sync with the latest changes as the platform moves + toward launch. </p> +<img src="{@docRoot}preview/images/m-preview-timeline.png" alt= +"Preview program timeline" id="timeline"> +<p> + You can help us improve the platform by <a href= + "https://code.google.com/p/android-developer-preview/">reporting issues</a> + through our feedback channels. This is especially + critical in the first month of the preview, when we’ll be giving priority to + developer-reported issues and feedback. +</p> --> + +<h2 id="timeline"> + Timeline and updates +</h2> +<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt= +"Preview program timeline" id="timeline"> <p> - We strongly encourage you to provide feedback for the M Preview releases through our <a href= - "https://code.google.com/p/android-developer-preview/">issue tracker</a>. Issues reported early - in the program have a better chance of being addressed before the official release, so reports - provided by June 30, 2015 receive priority processing by the Android team. + The M Developer Preview runs from May 27 until the final Android M SDK, which + we’ll release shortly before the public release during Q3 + 2015. </p> <p> - To get started testing your app: + At key development milestones, we’ll deliver updates for your test devices. + The tentative milestones are +</p> + +<ul> + <li> + <strong>Preview 1</strong> (initial Preview release, late May), + </li> + + <li> + <strong>Preview 2</strong> (late June/early July), and + </li> + + <li> + <strong>Preview 3</strong> (near final, late July) + </li> +</ul> + +<p> + These updates culminate in the <strong>final SDK</strong> (later in Q3), + which delivers the official APIs for the new version of Android, as well + as the final system behaviors and features. +</p> + +<p> + As you test and develop on Android M, we strongly recommend <strong>keeping + your development environment up-to-date</strong> as Preview updates are released. + To make the process easier, we'll deliver <strong>updates over the air + (OTA)</strong> to devices already flashed to a Preview build, as well as + providing system images that you can download and flash manually. +</p> +<p class="note"> + <strong>Note:</strong> The final SDK and system images can not be delivered + by OTA, but will instead need to be <strong>flashed manually</strong> to + your test devices.</strong> +</p> + +<p> + We’ll notify you when Preview updates are available via the <a href= + "http://android-developers.blogspot.com/">Android Developers Blog</a>, as + well as this site and the + <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a>. +</p> + +<h2 id="preview_tools"> + What’s in the Preview? +</h2> + +<p> + The M Developer Preview includes everything you need to test your existing + apps on a variety of screen sizes, network technologies, CPU/GPU chipsets, + and hardware architectures. +</p> + +<h4> + SDK tools +</h4> + +<p> + You can download these components through the SDK Manager in <a href= + "{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>: +</p> + +<ul> + <li>M Developer Preview <strong>SDK tools</strong> + </li> + + <li>M Developer Preview <strong>emulator system image</strong> (32-bit & + 64-bit) + </li> + + <li>M Developer Preview <strong>emulator system Image for Android TV</strong> + (32-bit) + </li> +</ul> + +<h4> + Hardware system images +</h4> + +<p> + You can download these hardware system images for Nexus devices from the + <a href="downloads.html">Downloads page</a>: </p> <ul> - <li>Review the <a href="{@docRoot}preview/api-overview.html"> API Overview</a> and - <a href="{@docRoot}preview/api-changes.html">Behavior Changes</a> to - get an idea of what's new and how it affects your app. + <li> + <strong>Nexus 5</strong> (GSM/LTE) “hammerhead” device system image + </li> + + <li> + <strong>Nexus 6</strong> “shamu” device system image + </li> + + <li> + <strong>Nexus 9</strong> (Wi-Fi) “volantis” device system image + </li> + + <li> + <strong>Nexus Player</strong> (Android TV) “fugu” device system image + </li> +</ul> + +<h4> + Documentation and sample code +</h4> + +<p> + These documentation resources help you learn about the Preview: +</p> + +<ul> + <li> + <a href="setup-sdk.html">Set Up the SDK</a> has step-by-step instructions + for getting started. + </li> + + <li> + <a href="testing.html">Testing Guide</a> and <a href= + "api-changes.html">Behavior Changes</a> point you to key areas to test. + </li> + + <li>Documentation of new APIs, including an <a href="api-overview.html">API Overview</a>, + downloadable <a href="">API Reference</a>, and detailed developer guides on + key features such as <a href="">permissions</a>, <a href="">app backup</a>, + and others. + </li> + + <li> + <a href="">Sample code</a> that demonstrates how support + permissions and other new features. + </li> + + <li> + <a href="">Release notes</a> for the current version of the M Developer + Preview, including change notes and diff reports. + </li> +</ul> + +<h4> + Support resources +</h4> + +<p> + Use these support resources as you test and develop on the M + Developer Preview: +</p> + +<ul> + <li><a href="https://code.google.com/p/android-developer-preview/">M + Developer Preview Issue Tracker</a> is your <strong>primary feedback + channel.</strong> You can report bugs, performance issues, and general + feedback through the issue tracker. You can also check for known issues + and find workaround steps, if available. + </li> + + <li>The <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer + Community</a> is a Google+ community where you can <strong>connect with + other developers</strong> working with Android M. You can share + observations or ideas or find answers to questions about Android M. + </li> +</ul> + + +<h2 id="preview_apis_and_publishing"> + Targeting, preview APIs, and publishing +</h2> + +<p> + The Android M Developer Preview is a development-only release and + <strong>does not have a standard API level</strong>. If you want to opt out + of compatibility behaviors to test your app (which is strongly recommended), + you can target the M Developer Preview by setting your app's <code><a href= + "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> + to <code>“MNC”</code>. +</p> + +<p> + The Android M Developer Preview delivers <strong>preview APIs</strong> + — the APIs will not be official until the final SDK is released, + currently planned for the third quarter of 2015. This means that you can + <strong>expect minor API changes</strong> over time, especially during + initial weeks of the program. We’ll provide a summary of changes to you with + each update of the Android M Developer Preview. +</p> + +<p class="note"> + Note that although preview APIs may change, underlying system behaviors such + as runtime permissions and power-saving features are stable and ready for + testing right away. +</p> + +<p> + In terms of publishing, Google Play <strong>prevents publishing of apps + targeting the M Developer Preview</strong>. When the Android M final SDK is + available, you’ll be able to target the official Android M API level and + publish your app to Google Play. Meanwhile, if you want to distribute an app + targeting Android M to testers, you can do so via email or by direct download + from your site. +</p> + +<h2 id="get_started"> + How to get started? +</h2> + +<p> + To get started testing your app: +</p> + +<ol> + <li>Review the <a href="{@docRoot}preview/api-overview.html">API Overview</a> + and <a href="{@docRoot}preview/behavior.html">Behavior Changes</a> to get an + idea of what's new and how it affects your apps. </li> <li>Setup for testing and development by following the instructions for @@ -41,23 +347,24 @@ page.image=images/cards/card-preview_16-9_2x.png and configuring test devices. </li> - <li>You can <a href="{@docRoot}preview/download.html">download</a> the latest M Developer - Preview system image for compatible Nexus devices and install it for testing. Once you have - flashed a development device, it is upgraded automatically with the next preview release - through over-the-air (OTA) updates. + <li>Follow the <a href="https://developers.google.com/android/nexus/images"> + flashing instructions</a> to flash the latest M developer preview system image + for Nexus 5, 6, 9, and Player. Once you've flashed your development device, + Preview updates will be delivered through over-the-air (OTA) updates.</a> </li> - <li>Review the M Preview <a href="{@docRoot}preview/reference.html">API Reference</a> and - <a href="{@docRoot}preview/samples.html">samples</a> to - gain more insight into new API features and how to use them in your app. + <li>Download the <a href="{@docRoot}preview/reference.html">M Preview API + Reference</a> and <a href="{@docRoot}preview/samples.html">M Preview + samples</a> to gain more insight into new API features and how to use them in + your app. </li> - <li>Join the M Preview <a href="http://g.co/dev/AndroidMDevPreview">Google+ developer - community</a> to get the latest developer updates and connect with other - developers working with the preview. + <li>Join the <a href="http://g.co/dev/AndroidMDevPreview">Android M + Developer Community</a> to get the latest news and connect with other + developers working with the new platform. </li> -</ul> +</ol> <p> - Thanks in advance for your participation in the developer preview program! -</p> + Thank you for your participation in the Android M Developer Preview program! +</p>
\ No newline at end of file diff --git a/docs/html/preview/preview_toc.cs b/docs/html/preview/preview_toc.cs index 7e9f292..76dfef5 100644 --- a/docs/html/preview/preview_toc.cs +++ b/docs/html/preview/preview_toc.cs @@ -7,7 +7,7 @@ <li class="nav-section"> <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/download.html"> - Download</a></div> + Downloads</a></div> </li> <li class="nav-section"> @@ -38,10 +38,9 @@ </li> <li class="nav-section"> - <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/api-changes.html"> + <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/behavior-changes.html"> Behavior Changes</a></div> </li> - <li class="nav-section"> <div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/samples.html"> Samples</a></div> diff --git a/docs/html/preview/samples.jd b/docs/html/preview/samples.jd index 29b9e2a..21d4215 100644 --- a/docs/html/preview/samples.jd +++ b/docs/html/preview/samples.jd @@ -1,5 +1,5 @@ page.title=Samples -page.image=images/cards/card-samples_16-9_2x.png +page.image=images/cards/samples-new_2x.png @jd:body <p> diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd index b31b104..f0def9b 100644 --- a/docs/html/preview/setup-sdk.jd +++ b/docs/html/preview/setup-sdk.jd @@ -72,8 +72,8 @@ App</a> training lesson first.</a></p> <ul> <li><code>compileSdkVersion</code> is set to <code>'android-MNC'</code></li> - <li><code>minSdkVersion</code> is set to <code>'android-MNC'</code></li> - <li><code>targetSdkVersion</code> is set to <code>'android-MNC'</code></li> + <li><code>minSdkVersion</code> is set to <code>'MNC'</code></li> + <li><code>targetSdkVersion</code> is set to <code>'MNC'</code></li> </ul> diff --git a/docs/html/preview/testing/guide.jd b/docs/html/preview/testing/guide.jd new file mode 100644 index 0000000..1879268 --- /dev/null +++ b/docs/html/preview/testing/guide.jd @@ -0,0 +1,176 @@ +page.title=Testing Guide +page.image=images/cards/card-set-up_16-9_2x.png + +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#runtime-permissions">Testing Runtime Permissions</a></li> + <li><a href="#doze-standby">Testing Doze and App Standby</a></li> + </ol> + </div> +</div> + +<p> + The Android M Developer Preview gives you an opportunity to ensure your apps work with the next + version of the platform. This preview includes a number of APIs and behavior changes that can + impact your app, as described in the <a href="{@docRoot}preview/api-overview.html">API + Overview</a> and <a href="{@docRoot}preview/api-changes.html">Behavior Changes</a>. In testing + your app with the preview, there are some specific system changes that you should focus on to + ensure that users have a good experience. +</p> + +<p> + This guide describes the what and how to test preview features with your app. You should + prioritize testing of these specific preview features, due to their high potential impact on your + app's behavior: +</p> + +<ul> + <li><a href="#runtime-permissions">Runtime Permissions</a> + </li> + <li><a href="#doze-mode">Doze and App Standby</a> + </li> +</ul> + +<p> + For more information about how to set up devices or virtual devices with a preview system image + for testing, see <a href="{@docRoot}preview/setup-sdk.html">Set up the Preview SDK</a>. +</p> + + +<h2 id="runtime-permissions">Testing Runtime Permissions</h2> + +<p> + The <a href="{@docRoot}preview/features/runtime-permissions.html">Runtime Permissions</a> feature + changes the way that permissions are allocated to your app by the user. Instead of granting all + permissions during the install procedure, your app must ask the user for individual permissions + at runtime. For users this behavior provides more granular control over each app’s activities, as + well as better context for understanding why the app is requesting a specific permission. Users + can grant or revoke the permissions granted to an app individually at any time. This feature of + the preview is most likely to have an impact on your app's behavior and may prevent some of your + app features from working, or they may work in a degraded state. +</p> + +<p> + This change that affects all apps running on the new platform, even those not targeting the new + platform version. The platform provides a limited compatibility behavior for legacy apps, but you + should begin planning your app’s migration to the new permissions model now, with a goal of + publishing an updated version of your app at the official platform launch. +</p> + + +<h3 id="permission-test-tips">Test tips</h3> + +<p> + Use the following test tips to help you plan and execute testing of your app with the new + permissions behavior. +</p> + +<ul> + <li>Identify your app’s current permissions and the related code paths.</li> + <li>Test user flows across permission-protected services and data.</li> + <li>Test with various combinations of granted/revoked permission.</li> + <li>Use the {@code adb} tool to manage permssions from the command line: + <ul> + <li>List permissions and status by group: + <pre>adb shell pm list permissions -d -g</pre> + </li> + <li>Grant or revoke one or more permissions using the following syntax:<br> + <pre>adb shell pm [grant|revoke] <permission.name> ...</pre> + </li> + </ul> + </li> + <li>Analyze your app for services that use permissions.</li> +</ul> + +<h3 id="permission-test-strategy">Test strategy</h3> + +<p> + The Runtime Permissions change affects the structure and design of your app, as well as + the user experience and flows you provide to users. You should assess your app’s current + permissions use and start planning for the new flows you want to offer. The official release of + the platform provides compatibility behavior, but you should plan on updating your app and not + rely on these behaviors. +</p> + +<p> + Identify the permissions that your app actually needs and uses, and then find the various code + paths that use the permission-protected services. You can do this through a combination of + testing on the new platform and code analysis. In testing, you should focus on opting in to + runtime permissions by changing the app’s {@code targetSdkVersion} to the preview version. For + more information, see <a href="{@docRoot}preview/setup-sdk.html#">Set up the Preview SDK</a>. +</p> + +<p> + Test with various combinations of permissions revoked and added, to highlight the user flows that + depend on permissions. Where a dependency is not obvious or logical you should consider + refactoring or compartmentalizing that flow to eliminate the dependency or make it clear why the + permission is needed. +</p> + +<p> + For more information on the behavior of Runtime Permissions, testing, and best practices, see the + <a href="{@docRoot}preview/features/runtime-permissions.html">Runtime Permissions</a> developer + preview page. +</p> + + +<h2 id="doze-standby">Testing Doze and App Standby</h2> + +<p> + The power saving features of Doze and App Standby limits the amount of background processing that + your app can perform when a device is in an idle state or while your app is not in focus. The + restrictions the system may impose on apps include limited or no network access, + suspended background tasks, suspended Notifications, ignored wake requests, and alarms. To ensure + that your app behaves properly with these power saving optimizations, you should test your app by + simulating these low power states. +</p> + +<h4 id="doze">Testing your app with Doze</h4> + +<p>To test Doze with your app:</p> + +<ol> +<li>Configure a hardware device or virtual device with a M Preview system image.</li> +<li>Connect the device to your development machine and install your app.</li> +<li>Run your app and leave it active.</li> +<li>Simulate the device going into Doze mode by running the following commands: + +<pre> +$ adb shell dumpsys battery unplug +$ adb shell dumpsys deviceidle step +$ adb shell dumpsys deviceidle -h +</pre> + + </li> + <li>Observe the behavior of your app when the device is re-activated. Make sure it + recovers gracefully when the device exits Doze.</li> +</ol> + + +<h4 id="standby">Testing apps with App Standby</h4> + +<p>To test the App Standby mode with your app:</p> + +<ol> + <li>Configure a hardware device or virtual device with a M Preview system image.</li> + <li>Connect the device to your development machine and install your app.</li> + <li>Run your app and leave it active.</li> + <li>Simulate the app going into standby mode by running the following commands: + +<pre> +$ adb shell am broadcast -a android.os.action.DISCHARGING +$ adb shell am set-idle <packageName> true +</pre> + + </li> + <li>Simulate waking your app using the following command: + <pre>$ adb shell am set-idle <packageName> false</pre> + </li> + <li>Observe the behavior of your app when it is woken. Make sure it recovers gracefully + from standby mode. In particular, you should check if your app's Notifications and background + jobs continue to function as expected.</li> +</ol> diff --git a/docs/html/preview/testing/performance.jd b/docs/html/preview/testing/performance.jd new file mode 100644 index 0000000..a61091f --- /dev/null +++ b/docs/html/preview/testing/performance.jd @@ -0,0 +1,667 @@ +page.title=Testing Display Performance + +@jd:body + + +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#measure">Measuring UI Performance</a> + <ul> + <li><a href="#aggregate">Aggregate frame stats</a></li> + <li><a href="#timing-info">Precise frame timing info</a></li> + <li><a href="#timing-dump">Simple frame timing dump</a></li> + <li><a href="#collection-window">Controlling the window of stat collection</a></li> + <li><a href="#diagnose">Diagnosing performance regressions</a></li> + <li><a href="#resources">Additional resources</a></li> + </ul> + </li> + <li><a href="#automate">Automating UI Perfomance Tests</a> + <ul> + <li><a href="#ui-tests">Setting up UI tests</a></li> + <li><a href="#automated-tests">Setting up automated UI testing</a></li> + <li><a href="#triage">Triaging and fixing observed problems</a></li> + </ul> + </li> + </ol> + </div> +</div> + + +<p> + User interface (UI) performance testing ensures that your app not only meets its functional + requirements, but that user interactions with your app are buttery smooth, running at a + consistent 60 frames per second (<a href= + "https://www.youtube.com/watch?v=CaMTIgxCSqU&index=25&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">why + 60fps?</a>), without any dropped or delayed frames, or as we like to call it, <em>jank</em>. This + document explains tools available to measure UI performance, and lays out an approach to + integrate UI performance measurements into your testing practices. +</p> + + +<h2 id="measure">Measuring UI Performance</h2> + +<p> + In order to improve performance you first need the ability to measure the performance of + your system, and then diagnose and identify problems that may arrive from various parts of your + pipeline. +</p> + +<p> + <em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em> is an + Android tool that runs on the device and dumps interesting information about the status of system + services. Passing the <em>gfxinfo</em> command to dumpsys provides an output in logcat with + performance information relating to frames of animation that are occurring during the recording + phase. +</p> + +<pre> +> adb shell dumpsys gfxinfo <PACKAGE_NAME> +</pre> + +<p> + This command can produce multiple different variants of frame timing data. +</p> + +<h3 id="aggregate">Aggregate frame stats</h3> + +<p> + With the M Preview the command prints out aggregated analysis of frame data to logcat, collected + across the entire lifetime of the process. For example: +</p> + +<pre class="noprettyprint"> +Stats since: 752958278148ns +Total frames rendered: 82189 +Janky frames: 35335 (42.99%) +90th percentile: 34ms +95th percentile: 42ms +99th percentile: 69ms +Number Missed Vsync: 4706 +Number High input latency: 142 +Number Slow UI thread: 17270 +Number Slow bitmap uploads: 1542 +Number Slow draw: 23342 +</pre> + +<p> + These high level statistics convey at a high level the rendering performance of the app, as well + as its stability across many frames. +</p> + + +<h3 id="timing-info">Precise frame timing info</h3> + +<p> + With the M Preview comes a new command for gfxinfo, and that’s <em>framestats</em> which provides + extremely detailed frame timing information from recent frames, so that you can track down and + debug problems more accurately. +</p> + +<pre> +>adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats +</pre> + +<p> + This command prints out frame timing information, with nanosecond timestamps, from the last 120 + frames produced by the app. Below is example raw output from adb dumpsys gfxinfo + <PACKAGE_NAME> framestats: +</p> + +<pre class="noprettyprint"> +0,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954, +0,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120, +0,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527, +0,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683, +</pre> + +<p> + Each line of this output represents a frame produced by the app. Each line has a fixed number of + columns describing time spent in each stage of the frame-producing pipeline. The next section + describes this format in detail, including what each column represents. +</p> + + +<h4 id="fs-data-format">Framestats data format</h4> + +<p> + Since the block of data is output in CSV format, it's very straightforward to paste it to your + spreadsheet tool of choice, or collect and parse with a script. The following table explains the + format of the output data columns. All timestamps are in nanoseconds. +</p> + +<ul> + <li>FLAGS + <ul> + <li>Rows with a ‘0’ for the FLAGS column can have their total frame time computed by + subtracting the INTENDED_VSYNC column from the FRAME_COMPLETED column. + </li> + + <li>If this is non-zero the row should be ignored, as the frame has been determined as being + an outlier from normal performance, where it is expected that layout & draw take longer + than 16ms. Here are a few reasons this could occur: + <ul> + <li>The window layout changed (such as the first frame of the application or after a + rotation) + </li> + + <li>It is also possible the frame was skipped in which case some of the values will have + garbage timestamps. A frame can be skipped if for example it is out-running 60fps or if + nothing on-screen ended up being dirty, this is not necessarily a sign of a problem in + the app. + </li> + </ul> + </li> + </ul> + </li> + + <li>VSYNC + <ul> + <li>The time value that was used in all the vsync listeners and drawing for the frame + (Choreographer frame callbacks, animations, View.getDrawingTime(), etc…) + </li> + + <li>To understand more about VSYNC and how it influences your application, check out the + <a href= + "https://www.youtube.com/watch?v=1iaHxmfZGGc&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=23"> + Understanding VSYNC</a> video. + </li> + </ul> + </li> + + + <li>INTENDED_VSYNC + <ul> + <li>The intended start point for the frame. If this value is different from VSYNC, there + was work occurring on the UI thread that prevented it from responding to the vsync signal + in a timely fashion. + </li> + </ul> + </li> + + <li>OLDEST_INPUT_EVENT + <ul> + <li>The timestamp of the oldest input event in the input queue, or Long.MAX_VALUE if + there were no input events for the frame. + </li> + + <li>This value is primarily intended for platform work and has limited usefulness to app + developers. + </li> + </ul> + </li> + + <li>NEWEST_INPUT_EVENT + <ul> + <li>The timestamp of the newest input event in the input queue, or 0 if there were no + input events for the frame. + </li> + + <li>This value is primarily intended for platform work and has limited usefulness to app + developers. + </li> + + <li>However it’s possible to get a rough idea of how much latency the app is adding by + looking at (FRAME_COMPLETED - NEWEST_INPUT_EVENT). + </li> + </ul> + </li> + + <li>HANDLE_INPUT_START + <ul> + <li>The timestamp at which input events were dispatched to the application. + </li> + + <li>By looking at the time between this and ANIMATION_START it is possible to measure how + long the application spent handling input events. + </li> + + <li>If this number is high (>2ms), this indicates the app is spending an unusually + long time processing input events, such as View.onTouchEvent(), which may indicate this + work needs to be optimized, or offloaded to a different thread. Note that there are some + scenarios, such as click events that launch new activities or similar, where it is + expected and acceptable that this number is large. + </li> + </ul> + </li> + + <li>ANIMATION_START + <ul> + <li>The timestamp at which animations registered with Choreographer were run. + </li> + + <li>By looking at the time between this and PERFORM_TRANVERSALS_START it is possible to + determine how long it took to evaluate all the animators (ObjectAnimator, + ViewPropertyAnimator, and Transitions being the common ones) that are running. + </li> + + <li>If this number is high (>2ms), check to see if your app has written any custom + animators or what fields ObjectAnimators are animating and ensure they are appropriate + for an animation. + </li> + + <li>To learn more about Choreographer, check out the <a href= + "https://developers.google.com/events/io/sessions/325418001">For Butter or Worse</a> + video. + </li> + </ul> + </li> + + <li>PERFORM_TRAVERSALS_START + <ul> + <li>If you subtract out DRAW_START from this value, you can extract how long the layout + & measure phases took to complete. (note, during a scroll, or animation, you would + hope this should be close to zero..) + </li> + + <li>To learn more about the measure & layout phases of the rendering pipeline, check + out the <a href= + "https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27"> + Invalidations, Layouts and Performance</a> video + </li> + </ul> + </li> + + <li>DRAW_START + <ul> + <li>The time at which the draw phase of performTraversals started. This is the start + point of recording the display lists of any views that were invalidated. + </li> + + <li>The time between this and SYNC_START is how long it took to call View.draw() on all + the invalidated views in the tree. + </li> + + <li>For more information on the drawing model, see <a href= + "{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">Hardware Acceleration</a> + or the <a href= + "https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27"> + Invalidations, Layouts and Performance</a> video + </li> + </ul> + </li> + + <li>SYNC_START + <ul> + <li>The time at which the sync phase of the drawing started. + </li> + + <li>If the time between this and ISSUE_DRAW_COMMANDS_START is substantial (>0.4ms or + so), it typically indicates a lot of new Bitmaps were drawn which must be uploaded to the + GPU. + </li> + + <li>To understand more about the sync phase, check out the <a href= + "https://www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu"> + Profile GPU Rendering</a> video + </li> + </ul> + </li> + + <li>ISSUE_DRAW_COMMANDS_START + <ul> + <li>The time at which the hardware renderer started issuing drawing commands to the GPU. + </li> + + <li>The time between this and FRAME_COMPLETED gives a rough idea of how much GPU work the + app is producing. Problems like too much overdraw or inefficient rendering effects show + up here. + </li> + </ul> + </li> + + <li>SWAP_BUFFERS + <ul> + <li>The time at which eglSwapBuffers was called, relatively uninteresting outside of + platform work. + </li> + </ul> + </li> + + <li>FRAME_COMPLETED + <ul> + <li>All done! The total time spent working on this frame can be computed by doing + FRAME_COMPLETED - INTENDED_VSYNC. + </li> + </ul> + </li> + +</ul> + +<p> + You can use this data in different ways. One simple but useful visualization is a + histogram showing the distribution of frames times (FRAME_COMPLETED - INTENDED_VSYNC) in + different latency buckets, see figure below. This graph tells us at a glance that most + frames were very good - well below the 16ms deadline (depicted in red), but a few frames + were significantly over the deadline. We can look at changes in this histogram over time + to see wholesale shifts or new outliers being created. You can also graph input latency, + time spent in layout, or other similar interesting metrics based on the many timestamps + in the data. +</p> + +<img src="{@docRoot}preview/images/perf-test-framestats.png"> + + +<h3 id="timing-dump">Simple frame timing dump</h3> + +<p> + If <strong>Profile GPU rendering</strong> is set to <strong>In adb shell dumpsys gfxinfo</strong> + in Developer Options, the <code>adb shell dumpsys gfxinfo</code> command prints out timing + information for the most recent 120 frames, broken into a few different categories with + tab-separated-values. This data can be useful for indicating which parts of the drawing pipeline + may be slow at a high level. +</p> + +<p> + Similar to <a href="#fs-data-format">framestats</a> above, it's very + straightforward to paste it to your spreadsheet tool of choice, or collect and parse with + a script. The following graph shows a breakdown of where many frames produced by the app + were spending their time. +</p> + +<img src="{@docRoot}preview/images/perf-test-frame-latency.png"> + +<p> + The result of running gfxinfo, copying the output, pasting it into a spreadsheet + application, and graphing the data as stacked bars. +</p> + +<p> + Each vertical bar represents one frame of animation; its height represents the number of + milliseconds it took to compute that frame of animation. Each colored segment of the bar + represents a different stage of the rendering pipeline, so that you can see what parts of + your application may be creating a bottleneck. For more information on understanding the + rendering pipeline, and how to optimize for it, see the <a href= + "https://www.youtube.com/watch?v=we6poP0kw6E&index=27&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE"> + Invalidations Layouts and Performance</a> video. +</p> + + +<h3 id="collection-window">Controlling the window of stat collection</h3> + +<p> + Both the framestats and simple frame timings gather data over a very short window - about + two seconds worth of rendering. In order to precisely control this window of time - for + example, to constrain the data to a particular animation - you can reset all counters, + and aggregate statistics gathered. +</p> + +<pre> +>adb shell dumpsys gfxinfo <PACKAGE_NAME> reset +</pre> + +<p> + This can also be used in conjunction with the dumping commands themselves to collect and + reset at a regular cadence, capturing less-than-two-second windows of frames + continuously. +</p> + + +<h3 id="diagnose">Diagnosing performance regressions</h3> + +<p> + Identification of regressions is a good first step to tracking down problems, and + maintaining high application health. However, dumpsys just identifies the existence and + relative severity of problems. You still need to diagnose the particular cause of the + performance problems, and find appropriate ways to fix them. For that, it’s highly + recommended to use the <a href="{@docRoot}tools/help/systrace.html">systrace</a> tool. +</p> + + +<h3 id="resources">Additional resources</h3> + +<p> + For more information on how Android’s rendering pipeline works, common problems that you + can find there, and how to fix them, some of the following resources may be useful to + you: +</p> + +<ul> + <li>Rendering Performance 101 + </li> + <li>Why 60fps? + </li> + <li>Android UI and the GPU + </li> + <li>Invalidations Layouts and performance + </li> + <li>Analyzing UI Performance with Systrace + </li> +</ul> + + +<h2 id="automate">Automating UI Perfomance Tests</h2> + +<p> + One approach to UI Performance testing is to simply have a human tester perform a set of + user operations on the target app, and either visually look for jank, or spend an very + large amount of time using a tool-driven approach to find it. But this manual approach is + fraught with peril - human ability to perceive frame rate changes varies tremendously, + and this is also time consuming, tedious, and error prone. +</p> + +<p> + A more efficient approach is to log and analyze key performance metrics from automated UI + tests. The Android M developer preview includes new logging capabilities which make it + easy to determine the amount and severity of jank in your application’s animations, and + that can be used to build a rigorous process to determine your current performance and + track future performance objectives. +</p> + +<p> + This article walks you through a recommended approach to using that data to automate your + performance testing. +</p> + +<p> + This is mostly broken down into two key actions. Firstly, identifying what you're + testing, and how you’re testing it. and Secondly, setting up, and maintaining an + automated testing environment. +</p> + + +<h3 id="ui-tests">Setting up UI tests</h3> + +<p> + Before you can get started with automated testing, it’s important to determine a few high + level decisions, in order to properly understand your test space, and needs you may have. +</p> + +<h4> + Identify key animations / flows to test +</h4> + +<p> + Remember that bad performance is most visible to users when it interrupts a smooth + animation. As such, when identifying what types of UI actions to test for, it’s useful to + focus on the key animations that users see most, or are most important to their + experience. For example, here are some common scenarios that may be useful to identify: +</p> + +<ul> + <li>Scrolling a primary ListView or RecyclerView + </li> + + <li>Animations during async wait cycles + </li> + + <li>Any animation that may have bitmap loading / manipulation in it + </li> + + <li>Animations including Alpha Blending + </li> + + <li>Custom View drawing with Canvas + </li> +</ul> + +<p> + Work with engineers, designers, and product managers on your team to prioritize these key + product animations for test coverage. +</p> + +<h4> + Define your future objectives and track against them +</h4> + +<p> + From a high-level, it may be critical to identify your specific performance goals, and + focus on writing tests, and collecting data around them. For example: +</p> + +<ul> + <li>Do you just want to begin tracking UI performance for the first time to learn more? + </li> + + <li>Do you want to prevent regressions that might be introduced in the future? + </li> + + <li>Are you at 90% of smooth frames today and want to get to 98% this quarter? + </li> + + <li>Are you at 98% smooth frames and don’t want to regress? + </li> + + <li>Is your goal to improve performance on low end devices? + </li> +</ul> + +<p> + In all of these cases, you’ll want historical tracking which shows performance across + multiple versions of your application. +</p> + +<h4> + Identify devices to test on +</h4> + +<p> + Application performance varies depending on the device it's running on. Some devices may + contain less memory, less powerful GPUs, or slower CPU chips. This means that animations + which may perform well on one set of hardware, may not on others, and worse, may be a + result of a bottleneck in a different part of the pipeline. So, to account for this + variation in what a user might see, pick a range of devices to execute tests on, both + current high end devices, low end devices, tablets, etc. Look for variation in CPU + performance, RAM, screen density, size, and so on. Tests that pass on a high end device + may fail on a low end device. +</p> + +<h4> + Basic frameworks for UI Testing +</h4> + +<p> + Tool suites like <a href= + "https://developer.android.com/tools/testing-support-library/index.html">UIAutomator</a>, + and <a href="https://code.google.com/p/android-test-kit/">Espresso</a> are built to help + automate the action of a user moving through your application. These are simple + frameworks which mimic user interaction with your device. To use these frameworks, you + effectively create unique scripts, which run through a set of user-actions, and play them + out on the device itself. +</p> + +<p> + By combining these automated tests, alongside <code>dumpsys gfxinfo</code> you can quickly + create a reproducible system that allows you to execute a test, and measure the + performance information of that particular condition. +</p> + + +<h3 id="automated-tests">Setting up automated UI testing</h3> + +<p> + Once you have the ability to execute a UI test, and a pipeline to gather the data from a + single test, the next important step is to embrace a framework which can execute that + test multiple times, across multiple devices, and aggregate the resulting performance + data for further analysis by your development team. +</p> + +<h4> + A framework for test automation +</h4> + +<p> + It’s worth noting that UI testing frameworks (like <a href= + "https://developer.android.com/tools/testing-support-library/index.html">UIAutomator</a>) + run on the target device/emulator directly. While performance gathering information done + by <em>dumpsys gfxinfo</em> is driven by a host machine, sending commands over ADB. To + help bridge the automation of these separate entities, <a href= + "{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a> framework was + developed; A scripting system that runs on your host machine, which can issue commands to + a set of connected devices, as well as receive data from them. +</p> + +<p> + Building a set of scripts for proper Automation of UI Performance testing, at a minimum, + should be able to utilize monkeyRunner to accomplish the following tasks: +</p> + +<ul> + <li>Load & Launch a desired APK to a target device, devices, or emulator. + </li> + + <li>Launch a UIAutomator UI test, and allow it to be executed + </li> + + <li>Collect performance information through <em>dumpsys gfxinfo</em><em>.</em> + </li> + + <li>Aggregate information and display it back in a useful fashion to the developer. + </li> +</ul> + + +<h3 id="triage">Triaging and fixing observed problems</h3> + +<p> + Once problem patterns or regressions are identified, the next step is identifying and + applying the fix. If your automated test framework preserves precise timing breakdowns + for frames, it can help you scrutinize recent suspicious code/layout changes (in the case + of regression), or narrow down the part of the system you’re analyzing when you switch to + manual investigation. For manual investigation, <a href= + "{@docRoot}tools/help/systrace.html">systrace</a> is a great place to start, showing + precise timing information about every stage of the rendering pipeline, every thread and + core in the system, as well as any custom event markers you define. +</p> + +<h4> + Properly profiling temporal timings +</h4> + +<p> + It is important to note the difficulties in obtaining and measuring timings that come from + rendering performance. These numbers are, by nature, non deterministic, and often + fluctuate depending on the state of the system, amount of memory available, thermal + throttling, and the last time a sun flare hit your area of the earth. The point is that + you can run the same test, twice and get slightly different numbers that may be close to + each other, but not exact. +</p> + +<p> + Properly gathering and profiling data in this manner means running the same test, + multiple times, and accumulating the results as an average, or median value. (for the + sake of simplicity, let’s call this a ‘batch’) This gives you the rough approximation of + the performance of the test, while not needing exact timings. +</p> + +<p> + Batches can be used between code changes to see the relative impact of those changes on + performance. If the average frame rate for the pre-change Batch is larger than the + post-change batch, then you generally have an overall win wrt performance for that + particular change. +</p> + +<p> + This means that any Automated UI testing you do should take this concept into + consideration, and also account for any anomalies that might occur during a test. For + example, if your application performance suddenly dips, due to some device issue (that + isn’t caused by your application) then you may want to re-run the batch in order to get + less chaotic timings. +</p> + +<p> + So, how many times should you run a test, before the measurements become meaningful? 10 + times should be the minimum, with higher numbers like 50 or 100 yielding more accurate + results (of course, you’re now trading off time for accuracy) +</p> |
