summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java21
-rw-r--r--core/java/android/app/Notification.java3
-rw-r--r--core/java/android/view/ViewRootImpl.java1
-rw-r--r--core/java/android/widget/AbsListView.java4
-rw-r--r--core/res/AndroidManifest.xml167
-rw-r--r--core/res/res/values-de/strings.xml10
-rw-r--r--core/res/res/values-el/strings.xml2
-rw-r--r--core/res/res/values-pt/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--docs/html/_redirects.yaml15
-rw-r--r--docs/html/design/media/devices_displays_density.pngbin8236 -> 11719 bytes
-rw-r--r--docs/html/design/media/devices_displays_density@2x.pngbin0 -> 40816 bytes
-rw-r--r--docs/html/design/style/devices-displays.jd2
-rw-r--r--docs/html/design/style/iconography.jd190
-rw-r--r--docs/html/design/style/metrics-grids.jd24
-rw-r--r--docs/html/guide/topics/resources/localization.jd2
-rw-r--r--docs/html/sdk/installing/migrate.jd11
-rw-r--r--docs/html/sdk/installing/studio-tips.jd11
-rw-r--r--docs/html/tools/extras/support-library.jd7
-rw-r--r--docs/html/training/basics/data-storage/databases.jd66
-rw-r--r--docs/html/training/location/receive-location-updates.jd25
-rw-r--r--libs/hwui/DisplayList.cpp3
-rw-r--r--media/java/android/media/IRemoteControlDisplay.aidl27
-rw-r--r--media/java/android/media/MediaExtractor.java4
-rw-r--r--media/java/android/media/RemoteControlClient.java27
-rw-r--r--services/java/com/android/server/MountService.java19
-rw-r--r--services/java/com/android/server/NativeDaemonConnector.java76
-rw-r--r--services/java/com/android/server/NetworkManagementService.java6
-rw-r--r--services/java/com/android/server/NotificationManagerService.java21
-rw-r--r--services/java/com/android/server/content/SyncManager.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java27
33 files changed, 616 insertions, 166 deletions
diff --git a/api/current.txt b/api/current.txt
index 092fe168ad0d..02b95a0fc10b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -639,6 +639,7 @@ package android {
field public static final int layout = 16842994; // 0x10100f2
field public static final int layoutAnimation = 16842988; // 0x10100ec
field public static final int layoutDirection = 16843698; // 0x10103b2
+ field public static final int layoutMode = 16843738; // 0x10103da
field public static final int layout_above = 16843140; // 0x1010184
field public static final int layout_alignBaseline = 16843142; // 0x1010186
field public static final int layout_alignBottom = 16843146; // 0x101018a
@@ -11883,6 +11884,7 @@ package android.media {
ctor public MediaExtractor();
method public boolean advance();
method public long getCachedDuration();
+ method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
method public boolean getSampleCryptoInfo(android.media.MediaCodec.CryptoInfo);
method public int getSampleFlags();
method public long getSampleTime();
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index de58a3331519..059945fc66f4 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -58,6 +58,18 @@ import java.util.List;
* developer guide.</p>
* </div>
*
+ * @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes
+ * @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType
+ * @attr ref android.R.styleable#AccessibilityService_accessibilityFlags
+ * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
+ * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
+ * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
+ * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
+ * @attr ref android.R.styleable#AccessibilityService_description
+ * @attr ref android.R.styleable#AccessibilityService_notificationTimeout
+ * @attr ref android.R.styleable#AccessibilityService_packageNames
+ * @attr ref android.R.styleable#AccessibilityService_settingsActivity
+ *
* @see AccessibilityService
* @see android.view.accessibility.AccessibilityEvent
* @see android.view.accessibility.AccessibilityManager
@@ -68,23 +80,27 @@ public class AccessibilityServiceInfo implements Parcelable {
/**
* Capability: This accessibility service can retrieve the active window content.
+ * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
*/
public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001;
/**
* Capability: This accessibility service can request touch exploration mode in which
* touched items are spoken aloud and the UI can be explored via gestures.
+ * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
*/
public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
/**
* Capability: This accessibility service can request enhanced web accessibility
* enhancements. For example, installing scripts to make app content more accessible.
+ * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
*/
public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
/**
- * Capability: This accessibility service can request to filter the key event stream.
+ * Capability: This accessibility service can request to filter the key event stream.
+ * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
*/
public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008;
@@ -213,6 +229,7 @@ public class AccessibilityServiceInfo implements Parcelable {
* the first time they are run, if this flag is specified, a dialog is
* shown to the user to confirm enabling explore by touch.
* </p>
+ * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
*/
public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
@@ -232,6 +249,7 @@ public class AccessibilityServiceInfo implements Parcelable {
* true, otherwise this flag will be ignored. For how to declare the meta-data
* of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
* </p>
+ * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
*/
public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
@@ -260,6 +278,7 @@ public class AccessibilityServiceInfo implements Parcelable {
* otherwise this flag will be ignored. For how to declare the meta-data
* of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
* </p>
+ * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
*/
public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fb28ae3d6e45..b66e95bbf1f4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1719,6 +1719,9 @@ public class Notification implements Parcelable
extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
extras.putBoolean(EXTRA_SHOW_CHRONOMETER, mUseChronometer);
extras.putBoolean(EXTRA_SHOW_WHEN, mShowWhen);
+ if (mLargeIcon != null) {
+ extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
+ }
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bbf5ae933153..6b2ed912d9d4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2829,6 +2829,7 @@ public final class ViewRootImpl implements ViewParent,
setAccessibilityFocus(null, null);
+ mView.assignParent(null);
mView = null;
mAttachInfo.mRootView = null;
mAttachInfo.mSurface = null;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index bf662924b7f3..219891c4627b 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6390,7 +6390,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
int viewType = lp.viewType;
final boolean scrapHasTransientState = scrap.hasTransientState();
if (!shouldRecycleViewType(viewType) || scrapHasTransientState) {
- if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) {
+ if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER && scrapHasTransientState) {
if (mSkippedScrap == null) {
mSkippedScrap = new ArrayList<View>();
}
@@ -6464,7 +6464,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final boolean scrapHasTransientState = victim.hasTransientState();
if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) {
// Do not move views that should be ignored
- if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER ||
+ if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER &&
scrapHasTransientState) {
removeDetachedView(victim, false);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 619a10b9ef75..86e0a2c9af9d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -216,7 +216,8 @@
android:description="@string/permdesc_sendSms" />
<!-- Allows an application (Phone) to send a request to other applications
- to handle the respond-via-message action during incoming calls. -->
+ to handle the respond-via-message action during incoming calls.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:permissionGroup="android.permission-group.MESSAGES"
android:protectionLevel="signature|system"
@@ -240,7 +241,8 @@
android:description="@string/permdesc_receiveMms" />
<!-- Allows an application to receive emergency cell broadcast messages,
- to record or display them to the user. Reserved for system apps.
+ to record or display them to the user.
+ <p>Not for use by third-party applications.
@hide Pending API council approval -->
<permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
android:permissionGroup="android.permission-group.MESSAGES"
@@ -319,7 +321,8 @@
android:description="@string/permdesc_writeContacts" />
<!-- Allows an application to execute contacts directory search.
- This should only be used by ContactsProvider. -->
+ This should only be used by ContactsProvider.
+ <p>Not for use by third-party applications. -->
<!-- @hide -->
<permission android:name="android.permission.BIND_DIRECTORY_SEARCH"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
@@ -598,15 +601,16 @@
android:label="@string/permlab_accessLocationExtraCommands"
android:description="@string/permdesc_accessLocationExtraCommands" />
- <!-- Allows an application to install a location provider into the Location Manager -->
+ <!-- Allows an application to install a location provider into the Location Manager.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
android:protectionLevel="signature|system"
android:label="@string/permlab_installLocationProvider"
android:description="@string/permdesc_installLocationProvider" />
<!-- Allows an application to use location features in hardware,
- such as the geofencing api
- Protected by signature|system protection level -->
+ such as the geofencing api.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.LOCATION_HARDWARE"
android:permissionGroup="android.permission-group.LOCATION"
android:protectionLevel="signature|system" />
@@ -769,8 +773,8 @@
android:label="@string/permlab_manageAccounts"
android:description="@string/permdesc_manageAccounts" />
- <!-- Allows applications to call into AccountAuthenticators. Only
- the system can get this permission. -->
+ <!-- Allows applications to call into AccountAuthenticators.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCOUNT_MANAGER"
android:permissionGroup="android.permission-group.ACCOUNTS"
android:protectionLevel="signature"
@@ -870,7 +874,8 @@
android:label="@string/permlab_accessMtp"
android:description="@string/permdesc_accessMtp" />
- <!-- Allows access to hardware peripherals. Intended only for hardware testing -->
+ <!-- Allows access to hardware peripherals. Intended only for hardware testing.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.HARDWARE_TEST"
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
android:protectionLevel="signature"
@@ -971,7 +976,8 @@
android:description="@string/permdesc_processOutgoingCalls" />
<!-- Allows modification of the telephony state - power on, mmi, etc.
- Does not include placing calls. -->
+ Does not include placing calls.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.MODIFY_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:protectionLevel="signature|system"
@@ -1257,7 +1263,8 @@
android:description="@string/permgroupdesc_systemClock"
android:priority="140" />
- <!-- Allows applications to set the system time -->
+ <!-- Allows applications to set the system time.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signature|system"
android:label="@string/permlab_setTime"
@@ -1370,7 +1377,8 @@
android:label="@string/permlab_writeSettings"
android:description="@string/permdesc_writeSettings" />
- <!-- Allows an application to modify the Google service map. -->
+ <!-- Allows an application to modify the Google service map.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.WRITE_GSERVICES"
android:protectionLevel="signature|system"
android:label="@string/permlab_writeGservices"
@@ -1393,7 +1401,8 @@
android:label="@string/permlab_retrieve_window_content"
android:description="@string/permdesc_retrieve_window_content" />
- <!-- Modify the global animation scaling factor. -->
+ <!-- Modify the global animation scaling factor.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ANIMATION_SCALE"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature|system|development"
@@ -1451,14 +1460,16 @@
android:label="@string/permlab_broadcastSticky"
android:description="@string/permdesc_broadcastSticky" />
- <!-- Allows mounting and unmounting file systems for removable storage. -->
+ <!-- Allows mounting and unmounting file systems for removable storage.
+ <p>Not for use by third-party applications.-->
<permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="system|signature"
android:label="@string/permlab_mount_unmount_filesystems"
android:description="@string/permdesc_mount_unmount_filesystems" />
- <!-- Allows formatting file systems for removable storage. -->
+ <!-- Allows formatting file systems for removable storage.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="system|signature"
@@ -1505,7 +1516,8 @@
android:label="@string/permlab_asec_rename"
android:description="@string/permdesc_asec_rename" />
- <!-- Allows applications to write the apn settings -->
+ <!-- Allows applications to write the apn settings.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.WRITE_APN_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature|system"
@@ -1553,7 +1565,7 @@
<eat-comment />
<!-- Group of permissions that are related to development features. These
- are not permissions that should appear in normal applications; they
+ are not permissions that should appear in third-party applications; they
protect APIs that are intended only to be used for development
purposes. -->
<permission-group android:name="android.permission-group.DEVELOPMENT_TOOLS"
@@ -1561,15 +1573,16 @@
android:description="@string/permgroupdesc_developmentTools"
android:priority="310" />
- <!-- Allows an application to read or write the secure system settings. -->
+ <!-- Allows an application to read or write the secure system settings.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.WRITE_SECURE_SETTINGS"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
android:label="@string/permlab_writeSecureSettings"
android:description="@string/permdesc_writeSecureSettings" />
- <!-- Allows an application to retrieve state dump information from system
- services. -->
+ <!-- Allows an application to retrieve state dump information from system services.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.DUMP"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
@@ -1577,15 +1590,16 @@
android:description="@string/permdesc_dump" />
<!-- Allows an application to read the low-level system log files.
- Log entries can contain the user's private information,
- which is why this permission is not available to normal apps. -->
+ <p>Not for use by third-party applications, because
+ Log entries can contain the user's private information. -->
<permission android:name="android.permission.READ_LOGS"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
android:label="@string/permlab_readLogs"
android:description="@string/permdesc_readLogs" />
- <!-- Configure an application for debugging. -->
+ <!-- Configure an application for debugging.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_DEBUG_APP"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
@@ -1593,7 +1607,8 @@
android:description="@string/permdesc_setDebugApp" />
<!-- Allows an application to set the maximum number of (not needed)
- application processes that can be running. -->
+ application processes that can be running.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_PROCESS_LIMIT"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
@@ -1601,14 +1616,16 @@
android:description="@string/permdesc_setProcessLimit" />
<!-- Allows an application to control whether activities are immediately
- finished when put in the background. -->
+ finished when put in the background.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ALWAYS_FINISH"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
android:label="@string/permlab_setAlwaysFinish"
android:description="@string/permdesc_setAlwaysFinish" />
- <!-- Allow an application to request that a signal be sent to all persistent processes -->
+ <!-- Allow an application to request that a signal be sent to all persistent processes.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
android:protectionLevel="signature|system|development"
@@ -1620,7 +1637,8 @@
<!-- ==================================== -->
<eat-comment />
- <!-- Allows applications to RW to diagnostic resources. -->
+ <!-- Allows applications to RW to diagnostic resources.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.DIAGNOSTIC"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature"
@@ -1628,7 +1646,8 @@
android:label="@string/permlab_diagnostic" />
<!-- Allows an application to open, close, or disable the status bar
- and its icons. -->
+ and its icons.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.STATUS_BAR"
android:label="@string/permlab_statusBar"
android:description="@string/permdesc_statusBar"
@@ -1642,14 +1661,15 @@
android:protectionLevel="signature" />
<!-- Allows an application to force a BACK operation on whatever is the
- top activity. -->
+ top activity.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.FORCE_BACK"
android:label="@string/permlab_forceBack"
android:description="@string/permdesc_forceBack"
android:protectionLevel="signature" />
- <!-- Allows an application to update device statistics. Not for
- use by third party apps. -->
+ <!-- Allows an application to update device statistics.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.UPDATE_DEVICE_STATS"
android:label="@string/permlab_updateBatteryStats"
android:description="@string/permdesc_updateBatteryStats"
@@ -1670,15 +1690,16 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to open windows that are for use by parts
- of the system user interface. Not for use by third party apps. -->
+ of the system user interface.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
android:label="@string/permlab_internalSystemWindow"
android:description="@string/permdesc_internalSystemWindow"
android:protectionLevel="signature" />
<!-- Allows an application to manage (create, destroy,
- Z-order) application tokens in the window manager. This is only
- for use by the system. -->
+ Z-order) application tokens in the window manager.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.MANAGE_APP_TOKENS"
android:label="@string/permlab_manageAppTokens"
android:description="@string/permdesc_manageAppTokens"
@@ -1694,7 +1715,7 @@
<!-- Allows an application to inject user events (keys, touch, trackball)
into the event stream and deliver them to ANY window. Without this
permission, you can only deliver events to windows in your own process.
- Very few applications should need to use this permission. -->
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.INJECT_EVENTS"
android:label="@string/permlab_injectEvents"
android:description="@string/permdesc_injectEvents"
@@ -1727,7 +1748,8 @@
<!-- Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
- (usually the monkey command). -->
+ (usually the monkey command).
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:label="@string/permlab_runSetActivityWatcher"
android:description="@string/permdesc_runSetActivityWatcher"
@@ -1752,14 +1774,16 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to retrieve private information about
- the current top activity, such as any assist context it can provide. -->
+ the current top activity, such as any assist context it can provide.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
android:label="@string/permlab_getTopActivityInfo"
android:description="@string/permdesc_getTopActivityInfo"
android:protectionLevel="signature" />
<!-- Allows an application to retrieve the current state of keys and
- switches. This is only for use by the system.
+ switches.
+ <p>Not for use by third-party applications.
@deprecated The API that used this permission has been removed. -->
<permission android:name="android.permission.READ_INPUT_STATE"
android:label="@string/permlab_readInputState"
@@ -1809,46 +1833,51 @@
android:protectionLevel="signature" />
<!-- Allows low-level access to setting the orientation (actually
- rotation) of the screen. Not for use by normal applications. -->
+ rotation) of the screen.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ORIENTATION"
android:label="@string/permlab_setOrientation"
android:description="@string/permdesc_setOrientation"
android:protectionLevel="signature" />
<!-- Allows low-level access to setting the pointer speed.
- Not for use by normal applications. -->
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_POINTER_SPEED"
android:label="@string/permlab_setPointerSpeed"
android:description="@string/permdesc_setPointerSpeed"
android:protectionLevel="signature" />
<!-- Allows low-level access to setting the keyboard layout.
- Not for use by normal applications.
+ <p>Not for use by third-party applications.
@hide -->
<permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
android:label="@string/permlab_setKeyboardLayout"
android:description="@string/permdesc_setKeyboardLayout"
android:protectionLevel="signature" />
- <!-- Allows an application to install packages. -->
+ <!-- Allows an application to install packages.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.INSTALL_PACKAGES"
android:label="@string/permlab_installPackages"
android:description="@string/permdesc_installPackages"
android:protectionLevel="signature|system" />
- <!-- Allows an application to clear user data -->
+ <!-- Allows an application to clear user data.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.CLEAR_APP_USER_DATA"
android:label="@string/permlab_clearAppUserData"
android:description="@string/permdesc_clearAppUserData"
android:protectionLevel="signature" />
- <!-- Allows an application to delete cache files. -->
+ <!-- Allows an application to delete cache files.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.DELETE_CACHE_FILES"
android:label="@string/permlab_deleteCacheFiles"
android:description="@string/permdesc_deleteCacheFiles"
android:protectionLevel="signature|system" />
- <!-- Allows an application to delete packages. -->
+ <!-- Allows an application to delete packages.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.DELETE_PACKAGES"
android:label="@string/permlab_deletePackages"
android:description="@string/permdesc_deletePackages"
@@ -1862,7 +1891,8 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to change whether an application component (other than its own) is
- enabled or not. -->
+ enabled or not.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
android:label="@string/permlab_changeComponentState"
android:description="@string/permdesc_changeComponentState"
@@ -1874,14 +1904,16 @@
android:description="@string/permdesc_grantRevokePermissions"
android:protectionLevel="signature" />
- <!-- Allows an application to use SurfaceFlinger's low level features -->
+ <!-- Allows an application to use SurfaceFlinger's low level features.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
android:label="@string/permlab_accessSurfaceFlinger"
android:description="@string/permdesc_accessSurfaceFlinger"
android:protectionLevel="signature" />
<!-- Allows an application to take screen shots and more generally
- get access to the frame buffer data -->
+ get access to the frame buffer data.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.READ_FRAME_BUFFER"
android:label="@string/permlab_readFrameBuffer"
android:description="@string/permdesc_readFrameBuffer"
@@ -1903,19 +1935,22 @@
android:description="@string/permdesc_controlWifiDisplay"
android:protectionLevel="signature" />
- <!-- Required to be able to disable the device (very dangerous!). -->
+ <!-- Required to be able to disable the device (very dangerous!).
+ <p>Not for use by third-party applications.. -->
<permission android:name="android.permission.BRICK"
android:label="@string/permlab_brick"
android:description="@string/permdesc_brick"
android:protectionLevel="signature" />
- <!-- Required to be able to reboot the device. -->
+ <!-- Required to be able to reboot the device.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.REBOOT"
android:label="@string/permlab_reboot"
android:description="@string/permdesc_reboot"
android:protectionLevel="signature|system" />
- <!-- Allows low-level access to power management -->
+ <!-- Allows low-level access to power management.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.DEVICE_POWER"
android:label="@string/permlab_devicePower"
android:description="@string/permdesc_devicePower"
@@ -1927,34 +1962,39 @@
android:protectionLevel="signature" />
<!-- Run as a manufacturer test application, running as the root user.
- Only available when the device is running in manufacturer test mode. -->
+ Only available when the device is running in manufacturer test mode.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.FACTORY_TEST"
android:label="@string/permlab_factoryTest"
android:description="@string/permdesc_factoryTest"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast a notification that an application
- package has been removed. -->
+ package has been removed.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:label="@string/permlab_broadcastPackageRemoved"
android:description="@string/permdesc_broadcastPackageRemoved"
android:protectionLevel="signature" />
- <!-- Allows an application to broadcast an SMS receipt notification -->
+ <!-- Allows an application to broadcast an SMS receipt notification.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.BROADCAST_SMS"
android:permissionGroup="android.permission-group.MESSAGES"
android:label="@string/permlab_broadcastSmsReceived"
android:description="@string/permdesc_broadcastSmsReceived"
android:protectionLevel="signature" />
- <!-- Allows an application to broadcast a WAP PUSH receipt notification -->
+ <!-- Allows an application to broadcast a WAP PUSH receipt notification.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.BROADCAST_WAP_PUSH"
android:permissionGroup="android.permission-group.MESSAGES"
android:label="@string/permlab_broadcastWapPush"
android:description="@string/permdesc_broadcastWapPush"
android:protectionLevel="signature" />
+ <!-- Not for use by third-party applications. -->
<permission android:name="android.permission.MASTER_CLEAR"
android:label="@string/permlab_masterClear"
android:description="@string/permdesc_masterClear"
@@ -1962,7 +2002,8 @@
<!-- Allows an application to call any phone number, including emergency
numbers, without going through the Dialer user interface for the user
- to confirm the call being placed. Not for use by third party apps. -->
+ to confirm the call being placed.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.CALL_PRIVILEGED"
android:label="@string/permlab_callPrivileged"
android:description="@string/permdesc_callPrivileged"
@@ -1975,14 +2016,16 @@
android:protectionLevel="signature|system" />
<!-- Allows enabling/disabling location update notifications from
- the radio. Not for use by normal applications. -->
+ the radio.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
android:label="@string/permlab_locationUpdates"
android:description="@string/permdesc_locationUpdates"
android:protectionLevel="signature|system" />
<!-- Allows read/write access to the "properties" table in the checkin
- database, to change values that get uploaded. -->
+ database, to change values that get uploaded.
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
android:label="@string/permlab_checkinProperties"
android:description="@string/permdesc_checkinProperties"
@@ -2002,7 +2045,8 @@
android:description="@string/permdesc_batteryStats"
android:protectionLevel="dangerous" />
- <!-- Allows an application to control the backup and restore process
+ <!-- Allows an application to control the backup and restore process.
+ <p>Not for use by third-party applications.
@hide pending API council -->
<permission android:name="android.permission.BACKUP"
android:label="@string/permlab_backup"
@@ -2029,7 +2073,7 @@
picks an AppWidget to go into a particular host, thereby giving that
host application access to the private data from the AppWidget app.
An application that has this permission should honor that contract.
- Very few applications should need to use this permission. -->
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.BIND_APPWIDGET"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:label="@string/permlab_bindGadget"
@@ -2050,7 +2094,8 @@
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature|system" />
- <!-- Allows applications to change the background data setting
+ <!-- Allows applications to change the background data setting.
+ <p>Not for use by third-party applications.
@hide pending API council -->
<permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8443d7f88e98..f09914cc083a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -942,11 +942,11 @@
<item quantity="other" msgid="3903706804349556379">"vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item>
</plurals>
<plurals name="num_minutes_ago">
- <item quantity="one" msgid="3306787433088810191">"Vor 1 Minute"</item>
+ <item quantity="one" msgid="3306787433088810191">"vor 1 Minute"</item>
<item quantity="other" msgid="2176942008915455116">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
</plurals>
<plurals name="num_hours_ago">
- <item quantity="one" msgid="9150797944610821849">"Vor 1 Stunde"</item>
+ <item quantity="one" msgid="9150797944610821849">"vor 1 Stunde"</item>
<item quantity="other" msgid="2467273239587587569">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
</plurals>
<plurals name="last_num_days">
@@ -955,7 +955,7 @@
<string name="last_month" msgid="3959346739979055432">"Letzter Monat"</string>
<string name="older" msgid="5211975022815554840">"Älter"</string>
<plurals name="num_days_ago">
- <item quantity="one" msgid="861358534398115820">"Gestern"</item>
+ <item quantity="one" msgid="861358534398115820">"gestern"</item>
<item quantity="other" msgid="2479586466153314633">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
</plurals>
<plurals name="in_num_seconds">
@@ -983,11 +983,11 @@
<item quantity="other" msgid="851164968597150710">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
</plurals>
<plurals name="abbrev_num_hours_ago">
- <item quantity="one" msgid="4796212039724722116">"Vor 1 Stunde"</item>
+ <item quantity="one" msgid="4796212039724722116">"vor 1 Stunde"</item>
<item quantity="other" msgid="6889970745748538901">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
</plurals>
<plurals name="abbrev_num_days_ago">
- <item quantity="one" msgid="8463161711492680309">"Gestern"</item>
+ <item quantity="one" msgid="8463161711492680309">"gestern"</item>
<item quantity="other" msgid="3453342639616481191">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
</plurals>
<plurals name="abbrev_in_num_seconds">
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 3d275684825b..800da21cbe27 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -607,7 +607,7 @@
<string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"δοκιμή πρόσβασης σε προστατευμένο χώρο αποθήκευσης"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Επιτρέπει USB για άλλες συσκ."</string>
<string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Επιτρέπει στην εφαρμογή τη δοκιμή μια άδειας για την κάρτα SD που θα διατίθεται σε μελλοντικές συσκευές."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. περιεχ. αποθ. χώρ. USB"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. του USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"τροποποίηση ή διαγραφή των περιεχομένων της κάρτας SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Επιτρέπει στην εφαρμογή την εγγραφή στον αποθηκευτικό χώρο USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fb9154f2c418..2cd31a847b70 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -607,7 +607,7 @@
<string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"testar o acesso ao armazenamento protegido"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Permite que o aplicativo teste uma permissão para o armazenamento USB que estará disponível em dispositivos futuros."</string>
<string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Permite que o aplicativo teste uma permissão para o cartão SD que estará disponível em dispositivos futuros."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modif ou excl cont. armaz USB"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modificar ou excluir conteúdo do armazenamento USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modificar ou excluir o conteúdo do cartão SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite gravar no armaz. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o aplicativo grave em seu cartão SD."</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6c3991a4f96d..8b908d7263ab 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -619,7 +619,7 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允許應用程式讀取及寫入快取檔案系統。"</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"撥打/接聽網路電話"</string>
<string name="permdesc_use_sip" msgid="4717632000062674294">"允許應用程式使用 SIP 服務撥打/接聽網路電話。"</string>
- <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"讀取網路用量記錄"</string>
+ <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"讀取網路用量紀錄"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"允許應用程式讀取特定網路和應用程式的網路使用記錄。"</string>
<string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"管理網路政策"</string>
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允許應用程式管理網路政策並定義應用程式專用規則。"</string>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2d9713813d78..22ef31b8f047 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2046,6 +2046,7 @@
<public type="attr" name="canRequestTouchExplorationMode" id="0x010103d7" />
<public type="attr" name="canRequestEnhancedWebAccessibility" id="0x010103d8" />
<public type="attr" name="canRequestFilterKeyEvents" id="0x010103d9" />
+ <public type="attr" name="layoutMode" id="0x010103da" />
<public type="style" name="Theme.Holo.NoActionBar.Overscan" id="0x010301dd" />
<public type="style" name="Theme.Holo.Light.NoActionBar.Overscan" id="0x010301de" />
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index a1473508be79..27cedcb82ea7 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -219,6 +219,21 @@ redirects:
- from: /guide/tutorials/...
to: /resources/tutorials/...
+# move ui docs to design
+
+- from: /guide/practices/ui_guidelines/index.html
+ to: /design/index.html
+
+- from: /guide/practices/ui_guidelines/icon_design.*
+ to: /design/style/iconography.html
+
+- from: /guide/practices/ui_guidelines/activity_task_design.html
+ to: /design/patterns/app-structure.html
+
+- from: /guide/practices/ui_guidelines/menu_design.html
+ to: /design/patterns/actionbar.html
+
+
# ------------------- RESOURCES -------------------
- from: /resources/dashboard/...
diff --git a/docs/html/design/media/devices_displays_density.png b/docs/html/design/media/devices_displays_density.png
index 7ddad31efdad..4e3cbf66201d 100644
--- a/docs/html/design/media/devices_displays_density.png
+++ b/docs/html/design/media/devices_displays_density.png
Binary files differ
diff --git a/docs/html/design/media/devices_displays_density@2x.png b/docs/html/design/media/devices_displays_density@2x.png
new file mode 100644
index 000000000000..79a46b08c9d1
--- /dev/null
+++ b/docs/html/design/media/devices_displays_density@2x.png
Binary files differ
diff --git a/docs/html/design/style/devices-displays.jd b/docs/html/design/style/devices-displays.jd
index 18550d9ff0b6..a8f9d6f4e9bd 100644
--- a/docs/html/design/style/devices-displays.jd
+++ b/docs/html/design/style/devices-displays.jd
@@ -32,7 +32,7 @@ ensure that your app looks great on any device.</p>
</div>
</div>
- <img src="{@docRoot}design/media/devices_displays_density.png">
+ <img src="{@docRoot}design/media/devices_displays_density@2x.png" alt="" height="160" />
<h4>Strategies</h4>
<p>So where do you begin when designing for multiple screens? One approach is to work in the base
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 1475e5cee771..0d2cdbb57926 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -4,9 +4,37 @@ page.tags="icons"
<img src="{@docRoot}design/media/iconography_overview.png">
+
<p>An icon is a graphic that takes up a small portion of screen real estate and provides a quick,
intuitive representation of an action, a status, or an app.</p>
+<p>When you design icons for your app, it's important to keep in mind that your
+app may be installed on a variety of devices that offer a range of
+pixel densities, as mentioned in
+<a href="{@docRoot}design/style/devices-displays.html">Devices
+and Displays</a>. But you can make your icons look great on all devices
+by providing each icon in multiple sizes. When your app runs, Android checks the characteristics of
+the device screen and loads the appropriate density-specific assets for your app. </p>
+
+<p>Because you will deliver each icon in multiple sizes to support different densities,
+the design guidelines below
+refer to the icon dimensions in <acronym title="density-independent pixels">dp</acronym>
+units, which are based on the pixel dimensions of a medium-density (MDPI) screen.</p>
+
+<img src="{@docRoot}design/media/devices_displays_density@2x.png" alt="" height="160" />
+
+<p>So, to create an icon for different densities, you should follow the <strong>2:3:4:6 scaling
+ratio</strong> between the four primary densities (medium, high, x-high, and xx-high,
+respectively). For example, consider that the size for a launcher icon is specified to be
+48x48 dp. This means the baseline (MDPI) asset is 48x48 px, and the
+high density (HDPI) asset should be 1.5x the baseline at 72x72 px, and the x-high
+density (XHDPI) asset should be 2x the baseline at 96x96 px, and so on.</p>
+
+<p class="note"><strong>Note:</strong> Android also supports low-density (LDPI) screens,
+but you normally don't need to create custom assets at this size because Android
+effectively down-scales your HDPI assets by 1/2 to match the expected size.</p>
+
+
<h2 id="launcher">Launcher</h2>
@@ -338,3 +366,165 @@ whenever a new notification is available.</p>
</div>
<!-- 2 free columns -->
</div>
+
+
+
+
+
+
+
+
+
+
+<h2 id="DesignTips">Design Tips</h2>
+
+<p>Here are some tips you might find useful as you create icons or other
+drawable assets for your application. These tips assume you are using
+Adobe&reg; Photoshop&reg; or a similar raster and vector image-editing program.</p>
+
+
+
+
+<h3>Use vector shapes where possible</h3>
+
+<p>Many image-editing programs such as Adobe&reg; Photoshop&reg; allow you to use a
+combination of vector shapes and raster layers and effects. When possible,
+use vector shapes so that if the need arises, assets can be scaled up without
+loss of detail and edge crispness.</p>
+
+<p>Using vectors also makes it easy to align edges and corners to pixel
+boundaries at smaller resolutions.</li>
+
+
+
+<h3>Start with large artboards</h3>
+
+<p>Because you will need to create assets for different screen densities,
+it is best to start your icon
+designs on large artboards with dimensions that are multiples of the target icon
+sizes. For example, launcher icons are 48, 72, 96, or 144 pixels wide,
+depending on screen density (mdpi, hdpi, xhdpi, and xxhdpi, respectively). If you
+initially draw launcher icons on an 864x864 artboard, it will be easier and
+cleaner to adjust the icons when you scale the artboard down to the target
+sizes for final asset creation.</p>
+
+
+
+<h3>When scaling, redraw bitmap layers as needed</h3>
+
+<p>If you scaled an image up from a bitmap layer, rather than from a vector
+layer, those layers will need to be redrawn manually to appear crisp at higher
+densities. For example if a 60x60 circle was painted as a bitmap for
+mdpi it will need to be repainted as a 90x90 circle for hdpi.</p>
+
+
+
+<h3>Use common naming conventions for icon assets</h3>
+
+<p>Try to name files so that related assets will group together inside a
+directory when they are sorted alphabetically. In particular, it helps to use a
+common prefix for each icon type. For example:</p>
+
+<table>
+<tr>
+<th>Asset Type</th>
+<th>Prefix</th>
+<th>Example</th>
+</tr>
+<tr>
+<td>Icons</td>
+<td><code>ic_</code></td>
+<td><code>ic_star.png</code></td>
+</tr>
+<tr>
+<td>Launcher icons</td>
+<td><code>ic_launcher</code></td>
+<td><code>ic_launcher_calendar.png</code></td>
+</tr>
+<tr>
+<td>Menu icons and Action Bar icons</td>
+<td><code>ic_menu</code></td>
+<td><code>ic_menu_archive.png</code></td>
+</tr>
+<tr>
+<td>Status bar icons</td>
+<td><code>ic_stat_notify</code></td>
+<td><code>ic_stat_notify_msg.png</code></td>
+</tr>
+<tr>
+<td>Tab icons</td>
+<td><code>ic_tab</code></td>
+<td><code>ic_tab_recent.png</code></td>
+</tr>
+<tr>
+<td>Dialog icons</td>
+<td><code>ic_dialog</code></td>
+<td><code>ic_dialog_info.png</code></td>
+</tr>
+</table>
+
+<p>Note that you are not required to use a shared prefix of any
+type&mdash;doing so is for your convenience only.</p>
+
+
+<h3>Set up a working space that organizes files by density</h3>
+
+<p>Supporting multiple screen densities means you must create multiple versions
+of the same icon. To help keep the multiple copies of files safe and easier to
+find, we recommend creating a directory structure in your working space that
+organizes asset files based on the target density. For example:</p>
+
+<pre>
+art/...
+ mdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png
+ hdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png
+ xhdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png</pre>
+ xxhdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png</pre>
+
+<p>Because the structure in your working space is similar to that of the application, you
+can quickly determine which assets should be copied to each
+resources directory. Separating assets by density also helps you detect any
+variances in filenames across densities, which is important because
+corresponding assets for different densities must share the same filename.</p>
+
+<p>For comparison, here's the resources directory structure of a typical
+application: </p>
+
+<pre>res/...
+ drawable-ldpi/...
+ <em>finished_asset</em>.png
+ drawable-mdpi/...
+ <em>finished_asset</em>.png
+ drawable-hdpi/...
+ <em>finished_asset</em>.png
+ drawable-xhdpi/...
+ <em>finished_asset</em>.png
+</pre>
+
+<p>For more information about how to save resources in the application project,
+see <a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.
+</p>
+
+
+<h3>Remove unnecessary metadata from final assets</h3>
+
+<p>Although the Android SDK tools will automatically compress PNGs when packaging
+application resources into the application binary, a good practice is to remove
+unnecessary headers and metadata from your PNG assets. Tools such as <a
+href="http://optipng.sourceforge.net/">OptiPNG</a> or <a
+href="http://pmt.sourceforge.net/pngcrush/">Pngcrush</a> can ensure that this
+metadata is removed and that your image asset file sizes are optimized.</p>
+
+
diff --git a/docs/html/design/style/metrics-grids.jd b/docs/html/design/style/metrics-grids.jd
index 3116ff6d3cca..0a99a2f5d2ca 100644
--- a/docs/html/design/style/metrics-grids.jd
+++ b/docs/html/design/style/metrics-grids.jd
@@ -4,15 +4,28 @@ page.tags="layout","screens"
<p>Devices vary not only in physical size, but also in screen density (<acronym title="Dots per
inch">DPI</acronym>). To simplify the way you design for multiple screens, think of each device as
-falling into a particular size bucket and density bucket. The size buckets are <em>handset</em> (smaller than
-600<acronym title="Density-independent pixels. One dp is one pixel on a 160 dpi
-screen.">dp</acronym>) and <em>tablet</em> (larger than or equal 600dp). The density buckets are <acronym
+falling into a particular size bucket and density bucket:</p>
+<ul>
+ <li>The size buckets are <em>handset</em> (smaller than
+600<acronym title="Density-independent pixels: One dp is one pixel on a 160 dpi (mdpi)
+screen.">dp</acronym>) and <em>tablet</em> (larger than or equal 600dp).</li>
+ <li>The density buckets are <acronym
title="Low density (120 dpi)">LDPI</acronym>, <acronym title="Medium density (160
-dpi)">MDPI</acronym>, <acronym title="High density (240 dpi)">HDPI</acronym>, and <acronym title
-="Extra-high density (320 dpi)">XHDPI</acronym>. Optimize your application's UI by designing
+dpi)">MDPI</acronym>, <acronym title="High density (240 dpi)">HDPI</acronym>, <acronym title
+="Extra-high density (320 dpi)">XHDPI</acronym>, and <acronym title
+="Extra-extra!-high density (480 dpi)">XXHDPI</acronym>.</li>
+</ul>
+
+<p>Optimize your application's UI by designing
alternative layouts for some of the different size buckets, and provide alternative bitmap images
for different density buckets.</p>
+<p>Because it's important that you design and implement your layouts for multiple densities,
+the guidelines below and throught the documentation
+refer to layout dimensions with <acronym title="Density-independent pixels: One dp is one pixel
+on a 160 dpi (mdpi) screen.">dp</acronym> measurements instead of pixels.</p>
+
+
<div class="layout-content-row">
<div class="layout-content-col span-8">
@@ -30,6 +43,7 @@ Screen Sizes and Densities Device Dashboard</a>.</p>
</div>
</div>
+
<h2 id="48dp-rhythm">48dp Rhythm</h2>
<p>Touchable UI components are generally laid out along 48dp units.</p>
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 480fe650830c..55c8dc4234ca 100644
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -480,4 +480,4 @@ the new locale. </p>
<h2 id="checklist">Localization Checklist</h2>
-<p>For an overview of the process of localizing an Android application, see the <a href="{@docRoot}distribute/googleplay/publish/localization.html">Localization Checklist</a>.</p>
+<p>For an overview of the process of localizing an Android application, see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a>.</p>
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index 20a698b2fb13..db1b5dd8e151 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -2,6 +2,17 @@ page.title=Migrating from Eclipse
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<h2>See also</h2>
+<ul>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
+ >Eclipse Compatibility Mode</a></li>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
+ >FAQ on Migrating</a></li>
+</ul>
+</div>
+</div>
<p>If you've previously developed for Android using Eclipse and would like to migrate
to Android Studio, you should export your projects from Eclipse in order to generate
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd
index 259087bd4901..a686efdfad24 100644
--- a/docs/html/sdk/installing/studio-tips.jd
+++ b/docs/html/sdk/installing/studio-tips.jd
@@ -2,6 +2,17 @@ page.title=Android Studio Tips and Tricks
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<h2>See also</h2>
+<ul>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
+ >Eclipse Compatibility Mode</a></li>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
+ >FAQ on Migrating</a></li>
+</ul>
+</div>
+</div>
<p>If you're unfamiliar with the IntelliJ IDEA interface, you might be wondering
how to accomplish some common tasks in Android Studio. This page provides some tips
diff --git a/docs/html/tools/extras/support-library.jd b/docs/html/tools/extras/support-library.jd
index 60168f46a201..a82a98ae4eba 100644
--- a/docs/html/tools/extras/support-library.jd
+++ b/docs/html/tools/extras/support-library.jd
@@ -18,8 +18,7 @@ page.title=Support Library
<h2>See also</h2>
<ol>
<li><a
-href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing Apps for Android 3.0</a></li>
- <li><a href="http://code.google.com/p/iosched/">Google I/O App source code</a></li>
+href="{@docRoot}training/basics/fragments/support-lib.html">Using the Support Library</a></li>
</ol>
</div>
@@ -708,8 +707,8 @@ each activity when running on Android 3.0 and higher.</p>
</div>
<p>For more information about how you can optimize your application for the latest
-Android-powered devices, read <a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing
-Apps for Android 3.0</a>.</p>
+Android-powered devices, read <a href="{@docRoot}guide/practices/tablets-and-handsets.html"
+>Supporting Tablets and Handsets</a>.</p>
<h2 id="Docs">Reference Docs</h2>
diff --git a/docs/html/training/basics/data-storage/databases.jd b/docs/html/training/basics/data-storage/databases.jd
index 61fb7583f2e8..6ea2140d6c0b 100644
--- a/docs/html/training/basics/data-storage/databases.jd
+++ b/docs/html/training/basics/data-storage/databases.jd
@@ -73,25 +73,23 @@ single table:</p>
<pre>
-public static abstract class FeedEntry implements BaseColumns {
- public static final String TABLE_NAME = &quot;entry&quot;;
- public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
- public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
- public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
- ...
+public final class FeedReaderContract {
+ // To prevent someone from accidentally instantiating the contract class,
+ // give it an empty constructor.
+ public FeedReaderContract() {}
+
+ /* Inner class that defines the table contents */
+ public static abstract class FeedEntry implements BaseColumns {
+ public static final String TABLE_NAME = &quot;entry&quot;;
+ public static final String COLUMN_NAME_ENTRY_ID = &quot;entryid&quot;;
+ public static final String COLUMN_NAME_TITLE = &quot;title&quot;;
+ public static final String COLUMN_NAME_SUBTITLE = &quot;subtitle&quot;;
+ ...
+ }
}
</pre>
-<p>To prevent someone from accidentally instantiating the contract class, give
-it an empty constructor. </p>
-
-<pre>
-// Prevents the FeedReaderContract class from being instantiated.
-private FeedReaderContract() {}
-</pre>
-
-
<h2 id="DbHelper">Create a Database Using a SQL Helper</h2>
@@ -103,15 +101,15 @@ statements that create and delete a table:</P>
private static final String TEXT_TYPE = &quot; TEXT&quot;;
private static final String COMMA_SEP = &quot;,&quot;;
private static final String SQL_CREATE_ENTRIES =
- &quot;CREATE TABLE &quot; + FeedReaderContract.FeedEntry.TABLE_NAME + &quot; (&quot; +
- FeedReaderContract.FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
- FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
- FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
+ &quot;CREATE TABLE &quot; + FeedEntry.TABLE_NAME + &quot; (&quot; +
+ FeedEntry._ID + &quot; INTEGER PRIMARY KEY,&quot; +
+ FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
+ FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
... // Any other options for the CREATE command
&quot; )&quot;;
private static final String SQL_DELETE_ENTRIES =
- &quot;DROP TABLE IF EXISTS &quot; + TABLE_NAME_ENTRIES;
+ &quot;DROP TABLE IF EXISTS &quot; + FeedEntry.TABLE_NAME;
</pre>
<p>Just like files that you save on the device's <a
@@ -191,15 +189,15 @@ SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
-values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID, id);
-values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);
-values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_CONTENT, content);
+values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
// Insert the new row, returning the primary key value of the new row
long newRowId;
newRowId = db.insert(
- FeedReaderContract.FeedEntry.TABLE_NAME,
- FeedReaderContract.FeedEntry.COLUMN_NAME_NULLABLE,
+ FeedEntry.TABLE_NAME,
+ FeedEntry.COLUMN_NAME_NULLABLE,
values);
</pre>
@@ -227,18 +225,18 @@ SQLiteDatabase db = mDbHelper.getReadableDatabase();
// Define a <em>projection</em> that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
- FeedReaderContract.FeedEntry._ID,
- FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE,
- FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED,
+ FeedEntry._ID,
+ FeedEntry.COLUMN_NAME_TITLE,
+ FeedEntry.COLUMN_NAME_UPDATED,
...
};
// How you want the results sorted in the resulting Cursor
String sortOrder =
- FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED + " DESC";
+ FeedEntry.COLUMN_NAME_UPDATED + " DESC";
Cursor c = db.query(
- FeedReaderContract.FeedEntry.TABLE_NAME, // The table to query
+ FeedEntry.TABLE_NAME, // The table to query
projection, // The columns to return
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
@@ -262,7 +260,7 @@ For example:</p>
<pre>
cursor.moveToFirst();
long itemId = cursor.getLong(
- cursor.getColumnIndexOrThrow(FeedReaderContract.FeedEntry._ID)
+ cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
</pre>
@@ -282,7 +280,7 @@ immune to SQL injection.</p>
<pre>
// Define 'where' part of query.
-String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
@@ -305,10 +303,10 @@ SQLiteDatabase db = mDbHelper.getReadableDatabase();
// New value for one column
ContentValues values = new ContentValues();
-values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);
+values.put(FeedEntry.COLUMN_NAME_TITLE, title);
// Which row to update, based on the ID
-String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
+String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + &quot; LIKE ?&quot;;
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update(
diff --git a/docs/html/training/location/receive-location-updates.jd b/docs/html/training/location/receive-location-updates.jd
index c33f07547d24..e6e8c51a5078 100644
--- a/docs/html/training/location/receive-location-updates.jd
+++ b/docs/html/training/location/receive-location-updates.jd
@@ -417,7 +417,7 @@ public class MainActivity extends FragmentActivity implements
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL =
- MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN SECONDS;
+ MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
// A fast frequency ceiling in milliseconds
@@ -425,7 +425,7 @@ public class MainActivity extends FragmentActivity implements
MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
...
// Define an object that holds accuracy and frequency parameters
- LocationResult mLocationRequest;
+ LocationRequest mLocationRequest;
...
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
@@ -458,9 +458,11 @@ public class MainActivity extends FragmentActivity implements
the request by calling
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#requestLocationUpdates(com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">requestLocationUpdates()</a></code>.
Since your client must be connected for your app to receive updates, you should
- connect the client and make the request in
+ connect the client in
{@link android.support.v4.app.FragmentActivity#onStart onStart()}. This ensures that you always
- have a valid, connected client while your app is visible.
+ have a valid, connected client while your app is visible. Since you need a connection before you
+ can request updates, make the update request in
+<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">ConnectionCallbacks.onConnected()</a></code>
</p>
<p>
Remember that the user may want to turn off location updates for various reasons. You should
@@ -536,6 +538,21 @@ public class MainActivity extends FragmentActivity implements
}
}
...
+ /*
+ * Called by Location Services when the request to connect the
+ * client finishes successfully. At this point, you can
+ * request the current location or start periodic updates
+ */
+ &#64;Override
+ public void onConnected(Bundle dataBundle) {
+ // Display the connection status
+ Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
+ // If already requested, start periodic updates
+ if (mUpdatesRequested) {
+ mLocationClient.requestLocationUpdates(mLocationRequest, this);
+ }
+ }
+ ...
}
</pre>
<p>
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 648da9cb378d..1cbd53196861 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -63,6 +63,7 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
void DisplayList::clearResources() {
mDisplayListData = NULL;
+ mSize = 0; // TODO: shouldn't be needed, WAR possible use after delete
mClipRectOp = NULL;
mSaveLayerOp = NULL;
@@ -479,7 +480,7 @@ void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) {
*/
template <class T>
void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
- if (mSize == 0 || mAlpha <= 0) {
+ if (mSize == 0 || mAlpha <= 0 || CC_UNLIKELY(!mSaveOp)) { // TODO: shouldn't need mSaveOp check
DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
return;
}
diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl
index c70889c9237c..583f436690c6 100644
--- a/media/java/android/media/IRemoteControlDisplay.aidl
+++ b/media/java/android/media/IRemoteControlDisplay.aidl
@@ -40,6 +40,33 @@ oneway interface IRemoteControlDisplay
void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent,
boolean clearing);
+ /**
+ * Sets the playback information (state, position and speed) of a client.
+ * @param generationId the current generation ID as known by this client
+ * @param state the current playback state, one of the following values:
+ * {@link RemoteControlClient#PLAYSTATE_STOPPED},
+ * {@link RemoteControlClient#PLAYSTATE_PAUSED},
+ * {@link RemoteControlClient#PLAYSTATE_PLAYING},
+ * {@link RemoteControlClient#PLAYSTATE_FAST_FORWARDING},
+ * {@link RemoteControlClient#PLAYSTATE_REWINDING},
+ * {@link RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS},
+ * {@link RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS},
+ * {@link RemoteControlClient#PLAYSTATE_BUFFERING},
+ * {@link RemoteControlClient#PLAYSTATE_ERROR}.
+ * @param stateChangeTimeMs the time at which the client reported the playback information
+ * @param currentPosMs a 0 or positive value for the current media position expressed in ms
+ * Strictly negative values imply that position is not known:
+ * a value of {@link RemoteControlClient#PLAYBACK_POSITION_INVALID} is intended to express
+ * that an application doesn't know the position (e.g. listening to a live stream of a radio)
+ * or that the position information is not applicable (e.g. when state
+ * is {@link RemoteControlClient#PLAYSTATE_BUFFERING} and nothing had played yet);
+ * a value of {@link RemoteControlClient#PLAYBACK_POSITION_ALWAYS_UNKNOWN} implies that the
+ * application uses {@link RemoteControlClient#setPlaybackState(int)} (legacy API) and will
+ * never pass a playback position.
+ * @param speed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
+ * 2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
+ * playing (e.g. when state is {@link RemoteControlClient#PLAYSTATE_ERROR}).
+ */
void setPlaybackState(int generationId, int state, long stateChangeTimeMs, long currentPosMs,
float speed);
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index cf159f0ed1db..e558c07d3c87 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -199,9 +199,9 @@ final public class MediaExtractor {
public native final int getTrackCount();
/**
- * Get the PSSH info if present. This returns a map of uuid-to-bytes, with the uuid specifying
+ * Get the PSSH info if present.
+ * @return a map of uuid-to-bytes, with the uuid specifying
* the crypto scheme, and the bytes being the data specific to that scheme.
- * {@hide}
*/
public Map<UUID, byte[]> getPsshInfo() {
Map<UUID, byte[]> psshMap = null;
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index c6ae9aade2c0..7379438360ab 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -180,6 +180,12 @@ public class RemoteControlClient
public final static long PLAYBACK_POSITION_INVALID = -1;
/**
* @hide
+ * An invalid playback position value associated with the use of {@link #setPlaybackState(int)}
+ * used to indicate that playback position will remain unknown.
+ */
+ public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L;
+ /**
+ * @hide
* The default playback speed, 1x.
*/
public final static float PLAYBACK_SPEED_1X = 1.0f;
@@ -602,7 +608,8 @@ public class RemoteControlClient
* {@link #PLAYSTATE_ERROR}.
*/
public void setPlaybackState(int state) {
- setPlaybackState(state, PLAYBACK_POSITION_INVALID, PLAYBACK_SPEED_1X);
+ setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X,
+ false /* legacy API, converting to method with position and speed */);
}
/**
@@ -629,12 +636,28 @@ public class RemoteControlClient
* playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
*/
public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
+ setPlaybackStateInt(state, timeInMs, playbackSpeed, true);
+ }
+
+ private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed,
+ boolean hasPosition) {
synchronized(mCacheLock) {
if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
|| (mPlaybackSpeed != playbackSpeed)) {
// store locally
mPlaybackState = state;
- mPlaybackPositionMs = timeInMs;
+ // distinguish between an application not knowing the current playback position
+ // at the moment and an application using the API where only the playback state
+ // is passed, not the playback position.
+ if (hasPosition) {
+ if (timeInMs < 0) {
+ mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
+ } else {
+ mPlaybackPositionMs = timeInMs;
+ }
+ } else {
+ mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN;
+ }
mPlaybackSpeed = playbackSpeed;
// keep track of when the state change occurred
mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d7adbf7b2eff..f402f4bd3dcc 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -64,6 +64,7 @@ import com.android.internal.app.IMediaContainerService;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.NativeDaemonConnector.Command;
+import com.android.server.NativeDaemonConnector.SensitiveArg;
import com.android.server.am.ActivityManagerService;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerService;
@@ -1642,8 +1643,8 @@ class MountService extends IMountService.Stub
int rc = StorageResultCode.OperationSucceeded;
try {
- mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid,
- external ? "1" : "0");
+ mConnector.execute("asec", "create", id, sizeMb, fstype, new SensitiveArg(key),
+ ownerUid, external ? "1" : "0");
} catch (NativeDaemonConnectorException e) {
rc = StorageResultCode.OperationFailedInternalError;
}
@@ -1743,7 +1744,7 @@ class MountService extends IMountService.Stub
int rc = StorageResultCode.OperationSucceeded;
try {
- mConnector.execute("asec", "mount", id, key, ownerUid);
+ mConnector.execute("asec", "mount", id, new SensitiveArg(key), ownerUid);
} catch (NativeDaemonConnectorException e) {
int code = e.getCode();
if (code != VoldResponseCode.OpFailedStorageBusy) {
@@ -2019,7 +2020,7 @@ class MountService extends IMountService.Stub
final NativeDaemonEvent event;
try {
- event = mConnector.execute("cryptfs", "checkpw", password);
+ event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password));
final int code = Integer.parseInt(event.getMessage());
if (code == 0) {
@@ -2058,7 +2059,7 @@ class MountService extends IMountService.Stub
}
try {
- mConnector.execute("cryptfs", "enablecrypto", "inplace", password);
+ mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password));
} catch (NativeDaemonConnectorException e) {
// Encryption failed
return e.getCode();
@@ -2083,7 +2084,7 @@ class MountService extends IMountService.Stub
final NativeDaemonEvent event;
try {
- event = mConnector.execute("cryptfs", "changepw", password);
+ event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password));
return Integer.parseInt(event.getMessage());
} catch (NativeDaemonConnectorException e) {
// Encryption failed
@@ -2116,7 +2117,7 @@ class MountService extends IMountService.Stub
final NativeDaemonEvent event;
try {
- event = mConnector.execute("cryptfs", "verifypw", password);
+ event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password));
Slog.i(TAG, "cryptfs verifypw => " + event.getMessage());
return Integer.parseInt(event.getMessage());
} catch (NativeDaemonConnectorException e) {
@@ -2482,8 +2483,8 @@ class MountService extends IMountService.Stub
int rc = StorageResultCode.OperationSucceeded;
try {
- mConnector.execute(
- "obb", "mount", mObbState.voldPath, hashedKey, mObbState.ownerGid);
+ mConnector.execute("obb", "mount", mObbState.voldPath, new SensitiveArg(hashedKey),
+ mObbState.ownerGid);
} catch (NativeDaemonConnectorException e) {
int code = e.getCode();
if (code != VoldResponseCode.OpFailedStorageBusy) {
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index c3f2afa04bf7..47840e0882ca 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -204,9 +204,28 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
}
/**
+ * Wrapper around argument that indicates it's sensitive and shouldn't be
+ * logged.
+ */
+ public static class SensitiveArg {
+ private final Object mArg;
+
+ public SensitiveArg(Object arg) {
+ mArg = arg;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(mArg);
+ }
+ }
+
+ /**
* Make command for daemon, escaping arguments as needed.
*/
- private void makeCommand(StringBuilder builder, String cmd, Object... args) {
+ @VisibleForTesting
+ static void makeCommand(StringBuilder rawBuilder, StringBuilder logBuilder, int sequenceNumber,
+ String cmd, Object... args) {
if (cmd.indexOf('\0') >= 0) {
throw new IllegalArgumentException("Unexpected command: " + cmd);
}
@@ -214,16 +233,26 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
throw new IllegalArgumentException("Arguments must be separate from command");
}
- builder.append(cmd);
+ rawBuilder.append(sequenceNumber).append(' ').append(cmd);
+ logBuilder.append(sequenceNumber).append(' ').append(cmd);
for (Object arg : args) {
final String argString = String.valueOf(arg);
if (argString.indexOf('\0') >= 0) {
throw new IllegalArgumentException("Unexpected argument: " + arg);
}
- builder.append(' ');
- appendEscaped(builder, argString);
+ rawBuilder.append(' ');
+ logBuilder.append(' ');
+
+ appendEscaped(rawBuilder, argString);
+ if (arg instanceof SensitiveArg) {
+ logBuilder.append("[scrubbed]");
+ } else {
+ appendEscaped(logBuilder, argString);
+ }
}
+
+ rawBuilder.append('\0');
}
/**
@@ -303,27 +332,27 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
*/
public NativeDaemonEvent[] execute(int timeout, String cmd, Object... args)
throws NativeDaemonConnectorException {
+ final long startTime = SystemClock.elapsedRealtime();
+
final ArrayList<NativeDaemonEvent> events = Lists.newArrayList();
+ final StringBuilder rawBuilder = new StringBuilder();
+ final StringBuilder logBuilder = new StringBuilder();
final int sequenceNumber = mSequenceNumber.incrementAndGet();
- final StringBuilder cmdBuilder =
- new StringBuilder(Integer.toString(sequenceNumber)).append(' ');
- final long startTime = SystemClock.elapsedRealtime();
- makeCommand(cmdBuilder, cmd, args);
+ makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);
- final String logCmd = cmdBuilder.toString(); /* includes cmdNum, cmd, args */
- log("SND -> {" + logCmd + "}");
+ final String rawCmd = rawBuilder.toString();
+ final String logCmd = logBuilder.toString();
- cmdBuilder.append('\0');
- final String sentCmd = cmdBuilder.toString(); /* logCmd + \0 */
+ log("SND -> {" + logCmd + "}");
synchronized (mDaemonLock) {
if (mOutputStream == null) {
throw new NativeDaemonConnectorException("missing output stream");
} else {
try {
- mOutputStream.write(sentCmd.getBytes(Charsets.UTF_8));
+ mOutputStream.write(rawCmd.getBytes(Charsets.UTF_8));
} catch (IOException e) {
throw new NativeDaemonConnectorException("problem sending command", e);
}
@@ -332,7 +361,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
NativeDaemonEvent event = null;
do {
- event = mResponseQueue.remove(sequenceNumber, timeout, sentCmd);
+ event = mResponseQueue.remove(sequenceNumber, timeout, logCmd);
if (event == null) {
loge("timed-out waiting for response to " + logCmd);
throw new NativeDaemonFailureException(logCmd, event);
@@ -447,10 +476,11 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
private static class ResponseQueue {
private static class PendingCmd {
- public int cmdNum;
+ public final int cmdNum;
+ public final String logCmd;
+
public BlockingQueue<NativeDaemonEvent> responses =
new ArrayBlockingQueue<NativeDaemonEvent>(10);
- public String request;
// The availableResponseCount member is used to track when we can remove this
// instance from the ResponseQueue.
@@ -468,7 +498,11 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
// hold references to this instance already so it can be removed from
// mPendingCmds queue.
public int availableResponseCount;
- public PendingCmd(int c, String r) {cmdNum = c; request = r;}
+
+ public PendingCmd(int cmdNum, String logCmd) {
+ this.cmdNum = cmdNum;
+ this.logCmd = logCmd;
+ }
}
private final LinkedList<PendingCmd> mPendingCmds;
@@ -497,7 +531,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
// let any waiter timeout waiting for this
PendingCmd pendingCmd = mPendingCmds.remove();
Slog.e("NativeDaemonConnector.ResponseQueue",
- "Removing request: " + pendingCmd.request + " (" +
+ "Removing request: " + pendingCmd.logCmd + " (" +
pendingCmd.cmdNum + ")");
}
found = new PendingCmd(cmdNum, null);
@@ -515,7 +549,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
// note that the timeout does not count time in deep sleep. If you don't want
// the device to sleep, hold a wakelock
- public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String origCmd) {
+ public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String logCmd) {
PendingCmd found = null;
synchronized (mPendingCmds) {
for (PendingCmd pendingCmd : mPendingCmds) {
@@ -525,7 +559,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
}
}
if (found == null) {
- found = new PendingCmd(cmdNum, origCmd);
+ found = new PendingCmd(cmdNum, logCmd);
mPendingCmds.add(found);
}
found.availableResponseCount--;
@@ -547,7 +581,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
pw.println("Pending requests:");
synchronized (mPendingCmds) {
for (PendingCmd pendingCmd : mPendingCmds) {
- pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.request);
+ pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.logCmd);
}
}
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index d2acb404ada9..3b84c7323043 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -34,7 +34,6 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.Tethe
import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
-import android.bluetooth.BluetoothTetheringDataTracker;
import android.content.Context;
import android.net.INetworkManagementEventObserver;
import android.net.InterfaceConfiguration;
@@ -59,6 +58,7 @@ import android.util.SparseBooleanArray;
import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.Preconditions;
import com.android.server.NativeDaemonConnector.Command;
+import com.android.server.NativeDaemonConnector.SensitiveArg;
import com.android.server.net.LockdownVpnTracker;
import com.google.android.collect.Maps;
@@ -990,7 +990,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mConnector.execute("softap", "set", wlanIface);
} else {
mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
- getSecurityType(wifiConfig), wifiConfig.preSharedKey);
+ getSecurityType(wifiConfig), new SensitiveArg(wifiConfig.preSharedKey));
}
mConnector.execute("softap", "startap");
} catch (NativeDaemonConnectorException e) {
@@ -1039,7 +1039,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mConnector.execute("softap", "set", wlanIface);
} else {
mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
- getSecurityType(wifiConfig), wifiConfig.preSharedKey);
+ getSecurityType(wifiConfig), new SensitiveArg(wifiConfig.preSharedKey));
}
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 04773db67d13..5dc8e0c5cb74 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1390,7 +1390,7 @@ public class NotificationManagerService extends INotificationManager.Stub
return ;
}
- final boolean isSystemToast = ("android".equals(pkg));
+ final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) {
if (!isSystemToast) {
@@ -1606,7 +1606,7 @@ public class NotificationManagerService extends INotificationManager.Stub
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
- final boolean isSystemNotification = ("android".equals(pkg));
+ final boolean isSystemNotification = isCallerSystem() || ("android".equals(pkg));
userId = ActivityManager.handleIncomingUser(callingPid,
callingUid, userId, true, false, "enqueueNotification", pkg);
@@ -2082,19 +2082,26 @@ public class NotificationManagerService extends INotificationManager.Stub
cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
}
+ // Return true if the caller is a system or phone UID and therefore should not have
+ // any notifications or toasts blocked.
+ boolean isCallerSystem() {
+ final int uid = Binder.getCallingUid();
+ final int appid = UserHandle.getAppId(uid);
+ return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
+ }
+
void checkCallerIsSystem() {
- int uid = Binder.getCallingUid();
- if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
+ if (isCallerSystem()) {
return;
}
- throw new SecurityException("Disallowed call for uid " + uid);
+ throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
}
void checkCallerIsSystemOrSameApp(String pkg) {
- int uid = Binder.getCallingUid();
- if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
+ if (isCallerSystem()) {
return;
}
+ final int uid = Binder.getCallingUid();
try {
ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
pkg, 0, UserHandle.getCallingUserId());
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index 1c883ec8ce25..ff1281e5c546 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -1971,6 +1971,10 @@ public class SyncManager {
for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) {
final Bundle extras = info.periodicSyncs.get(i).first;
final Long periodInMillis = info.periodicSyncs.get(i).second * 1000;
+ // Skip if the period is invalid
+ if (periodInMillis <= 0) {
+ continue;
+ }
// find when this periodic sync was last scheduled to run
final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i);
diff --git a/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java
index 275d80764533..e2253a2151b0 100644
--- a/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java
@@ -17,10 +17,13 @@
package com.android.server;
import static com.android.server.NativeDaemonConnector.appendEscaped;
+import static com.android.server.NativeDaemonConnector.makeCommand;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import com.android.server.NativeDaemonConnector.SensitiveArg;
+
/**
* Tests for {@link NativeDaemonConnector}.
*/
@@ -67,4 +70,28 @@ public class NativeDaemonConnectorTest extends AndroidTestCase {
appendEscaped(builder, "caf\u00E9 c\u00F6ffee");
assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString());
}
+
+ public void testSensitiveArgs() throws Exception {
+ final StringBuilder rawBuilder = new StringBuilder();
+ final StringBuilder logBuilder = new StringBuilder();
+
+ rawBuilder.setLength(0);
+ logBuilder.setLength(0);
+ makeCommand(rawBuilder, logBuilder, 1, "foo", "bar", "baz");
+ assertEquals("1 foo bar baz\0", rawBuilder.toString());
+ assertEquals("1 foo bar baz", logBuilder.toString());
+
+ rawBuilder.setLength(0);
+ logBuilder.setLength(0);
+ makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("bar"), "baz");
+ assertEquals("1 foo bar baz\0", rawBuilder.toString());
+ assertEquals("1 foo [scrubbed] baz", logBuilder.toString());
+
+ rawBuilder.setLength(0);
+ logBuilder.setLength(0);
+ makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("foo bar"), "baz baz",
+ new SensitiveArg("wat"));
+ assertEquals("1 foo \"foo bar\" \"baz baz\" wat\0", rawBuilder.toString());
+ assertEquals("1 foo [scrubbed] \"baz baz\" [scrubbed]", logBuilder.toString());
+ }
}