summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--CleanSpec.mk2
-rw-r--r--api/current.txt26
-rw-r--r--core/java/android/app/AlarmManager.java10
-rw-r--r--core/java/android/content/AbstractThreadedSyncAdapter.java9
-rw-r--r--core/java/android/content/res/Configuration.java11
-rw-r--r--core/java/android/provider/DocumentsContract.java138
-rw-r--r--core/java/android/webkit/WebView.java1
-rw-r--r--core/java/android/webkit/WebViewFactory.java2
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodUtils.java17
-rw-r--r--docs/html/_redirects.yaml3
-rw-r--r--docs/html/about/versions/jelly-bean.jd9
-rw-r--r--docs/html/channels/io2013.jd10
-rw-r--r--docs/html/design/downloads/index.jd8
-rw-r--r--docs/html/design/index.jd8
-rw-r--r--docs/html/develop/index.jd10
-rw-r--r--docs/html/distribute/distribute_toc.cs1
-rw-r--r--docs/html/distribute/googleplay/promote/badges.jd8
-rw-r--r--docs/html/distribute/googleplay/promote/brand.jd9
-rw-r--r--docs/html/distribute/googleplay/promote/index.jd8
-rw-r--r--docs/html/distribute/googleplay/promote/linking.jd8
-rw-r--r--docs/html/distribute/googleplay/publish/preparing.jd8
-rw-r--r--docs/html/distribute/googleplay/quality/core.jd8
-rw-r--r--docs/html/distribute/googleplay/quality/index.jd8
-rw-r--r--docs/html/distribute/googleplay/quality/tablet.jd10
-rw-r--r--docs/html/distribute/googleplay/spotlight/games.jd245
-rw-r--r--docs/html/distribute/googleplay/spotlight/index.jd9
-rw-r--r--docs/html/distribute/index.jd8
-rw-r--r--docs/html/distribute/promote/device-art.jd96
-rw-r--r--docs/html/google/index.jd8
-rw-r--r--docs/html/google/play-services/auth.jd2
-rw-r--r--docs/html/google/play/billing/gp-purchase-status-api.jd15
-rw-r--r--docs/html/google/play/billing/index.jd8
-rw-r--r--docs/html/guide/components/index.jd8
-rw-r--r--docs/html/guide/guide_toc.cs3
-rw-r--r--docs/html/guide/topics/ui/declaring-layout.jd17
-rw-r--r--docs/html/guide/topics/ui/layout/tabs.jd219
-rw-r--r--docs/html/images/distribute/concrete-pbc-gpgames.jpgbin0 -> 222819 bytes
-rw-r--r--docs/html/images/distribute/glu-ew-gpgames.jpgbin0 -> 263114 bytes
-rw-r--r--docs/html/images/distribute/vector-unit-rt-gpgames.jpgbin0 -> 175179 bytes
-rw-r--r--docs/html/index.jd8
-rw-r--r--docs/html/sdk/index.jd54
-rw-r--r--docs/html/sdk/installing/installing-adt.jd8
-rw-r--r--docs/html/tools/extras/oem-usb.jd2
-rw-r--r--docs/html/tools/index.jd9
-rw-r--r--docs/html/tools/sdk/eclipse-adt.jd226
-rw-r--r--docs/html/tools/sdk/ndk/index.jd2
-rw-r--r--docs/html/tools/sdk/tools-notes.jd92
-rw-r--r--docs/html/tools/support-library/features.jd49
-rw-r--r--docs/html/tools/support-library/index.jd24
-rw-r--r--docs/html/training/basics/intents/sending.jd23
-rw-r--r--docs/html/training/displaying-bitmaps/cache-bitmap.jd6
-rw-r--r--docs/html/training/index.jd9
-rw-r--r--graphics/java/android/graphics/drawable/InsetDrawable.java7
-rw-r--r--media/java/android/media/FocusRequester.java246
-rw-r--r--media/java/android/media/MediaFocusControl.java215
-rw-r--r--packages/DocumentsUI/res/layout/dialog_create_dir.xml27
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/BackendFragment.java82
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java100
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java2
-rw-r--r--packages/ExternalStorageProvider/res/values/strings.xml1
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java246
-rw-r--r--preloaded-classes26
-rw-r--r--services/java/com/android/server/AlarmManagerService.java38
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java21
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java10
-rw-r--r--tools/aapt/AaptAssets.cpp3
67 files changed, 1575 insertions, 933 deletions
diff --git a/Android.mk b/Android.mk
index 74cf8244223e..9adf4341912a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -623,7 +623,7 @@ sample_dir := development/samples
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=4.2
+framework_docs_SDK_VERSION:=4.3
# release version (ie "Release x") (full releases only)
framework_docs_SDK_REL_ID:=1
diff --git a/CleanSpec.mk b/CleanSpec.mk
index c696aa1db290..73e8fa4bc171 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -165,6 +165,8 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libandroidfw_intermediates/import_includes)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index b9f9804caaa8..8daa59216d17 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7446,6 +7446,7 @@ package android.content.res {
field public static final int KEYBOARD_NOKEYS = 1; // 0x1
field public static final int KEYBOARD_QWERTY = 2; // 0x2
field public static final int KEYBOARD_UNDEFINED = 0; // 0x0
+ field public static final int MNC_ZERO = 65535; // 0xffff
field public static final int NAVIGATIONHIDDEN_NO = 1; // 0x1
field public static final int NAVIGATIONHIDDEN_UNDEFINED = 0; // 0x0
field public static final int NAVIGATIONHIDDEN_YES = 2; // 0x2
@@ -10076,6 +10077,7 @@ package android.graphics.drawable {
ctor public InsetDrawable(android.graphics.drawable.Drawable, int);
ctor public InsetDrawable(android.graphics.drawable.Drawable, int, int, int, int);
method public void draw(android.graphics.Canvas);
+ method public android.graphics.drawable.Drawable getDrawable();
method public int getOpacity();
method public void invalidateDrawable(android.graphics.drawable.Drawable);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -20257,15 +20259,25 @@ package android.provider {
ctor public DocumentsContract();
method public static android.net.Uri buildContentsUri(android.net.Uri);
method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
- method public static android.net.Uri buildSearchUri(java.lang.String, java.lang.String);
+ method public static android.net.Uri buildRootsUri(java.lang.String);
+ method public static android.net.Uri buildSearchUri(android.net.Uri, java.lang.String);
method public static android.graphics.Bitmap getThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point);
method public static boolean renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
+ field public static final java.lang.String EXTRA_HAS_MORE = "has_more";
+ field public static final java.lang.String EXTRA_REQUEST_MORE = "request_more";
field public static final java.lang.String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
field public static final int FLAG_SUPPORTS_RENAME = 2; // 0x2
- field public static final int FLAG_SUPPORTS_THUMBNAIL = 4; // 0x4
+ field public static final int FLAG_SUPPORTS_SEARCH = 16; // 0x10
+ field public static final int FLAG_SUPPORTS_THUMBNAIL = 8; // 0x8
field public static final java.lang.String MIME_TYPE_DIRECTORY = "vnd.android.cursor.dir/doc";
+ field public static final java.lang.String PARAM_QUERY = "query";
field public static final java.lang.String ROOT_GUID = "0";
+ field public static final int ROOT_TYPE_DEVICE = 3; // 0x3
+ field public static final int ROOT_TYPE_DEVICE_ADVANCED = 4; // 0x4
+ field public static final int ROOT_TYPE_SERVICE = 1; // 0x1
+ field public static final int ROOT_TYPE_SHORTCUT = 2; // 0x2
}
public static abstract interface DocumentsContract.DocumentColumns implements android.provider.OpenableColumns {
@@ -20275,6 +20287,15 @@ package android.provider {
field public static final java.lang.String MIME_TYPE = "mime_type";
}
+ public static abstract interface DocumentsContract.RootColumns {
+ field public static final java.lang.String AVAILABLE_BYTES = "available_bytes";
+ field public static final java.lang.String GUID = "guid";
+ field public static final java.lang.String ICON = "icon";
+ field public static final java.lang.String ROOT_TYPE = "root_type";
+ field public static final java.lang.String SUMMARY = "summary";
+ field public static final java.lang.String TITLE = "title";
+ }
+
public final deprecated class LiveFolders implements android.provider.BaseColumns {
field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
field public static final java.lang.String DESCRIPTION = "description";
@@ -29533,6 +29554,7 @@ package android.webkit {
method public android.webkit.WebBackForwardList copyBackForwardList();
method public void destroy();
method public void documentHasImages(android.os.Message);
+ method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
method public static java.lang.String findAddress(java.lang.String);
method public deprecated int findAll(java.lang.String);
method public void findAllAsync(java.lang.String);
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index d9c377545499..b73fbfffb453 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -257,6 +257,16 @@ public class AlarmManager
private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
PendingIntent operation) {
+ if (triggerAtMillis < 0) {
+ /* NOTYET
+ if (mAlwaysExact) {
+ // Fatal error for KLP+ apps to use negative trigger times
+ throw new IllegalArgumentException("Invalid alarm trigger time "
+ + triggerAtMillis);
+ }
+ */
+ triggerAtMillis = 0;
+ }
try {
mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation);
} catch (RemoteException ex) {
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 613450b690c9..809f900222c5 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -161,10 +161,13 @@ public abstract class AbstractThreadedSyncAdapter {
if (mAutoInitialize
&& extras != null
&& extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
- if (ContentResolver.getIsSyncable(account, authority) < 0) {
- ContentResolver.setIsSyncable(account, authority, 1);
+ try {
+ if (ContentResolver.getIsSyncable(account, authority) < 0) {
+ ContentResolver.setIsSyncable(account, authority, 1);
+ }
+ } finally {
+ syncContextClient.onFinished(new SyncResult());
}
- syncContextClient.onFinished(new SyncResult());
return;
}
SyncThread syncThread = new SyncThread(
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 68db33a2e630..6318e3893767 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -54,10 +54,17 @@ public final class Configuration implements Parcelable, Comparable<Configuration
/**
* IMSI MNC (Mobile Network Code), corresponding to
* <a href="{@docRoot}guide/topics/resources/providing-resources.html#MccQualifier">mnc</a>
- * resource qualifier. 0 if undefined.
+ * resource qualifier. 0 if undefined. Note that the actual MNC may be 0; in order to check
+ * for this use the {@link #MNC_ZERO} symbol.
*/
public int mnc;
-
+
+ /**
+ * Constant used to to represent MNC (Mobile Network Code) zero.
+ * 0 cannot be used, since it is used to represent an undefined MNC.
+ */
+ public static final int MNC_ZERO = 0xffff;
+
/**
* Current user preference for the locale, corresponding to
* <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index c26f6d47c914..979a5a3bd648 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -16,10 +16,13 @@
package android.provider;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
+import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
@@ -39,9 +42,10 @@ import java.io.InputStream;
public final class DocumentsContract {
private static final String TAG = "Documents";
+ // content://com.example/roots/
// content://com.example/docs/0/
// content://com.example/docs/0/contents/
- // content://com.example/search/?query=pony
+ // content://com.example/docs/0/search/?query=pony
/**
* MIME type of a document which is a directory that may contain additional
@@ -78,25 +82,69 @@ public final class DocumentsContract {
public static final int FLAG_SUPPORTS_RENAME = 1 << 1;
/**
+ * Flag indicating that a document is deletable.
+ *
+ * @see DocumentColumns#FLAGS
+ */
+ public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
+
+ /**
* Flag indicating that a document can be represented as a thumbnail.
*
* @see DocumentColumns#FLAGS
* @see #getThumbnail(ContentResolver, Uri, Point)
*/
- public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 2;
+ public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 3;
+
+ /**
+ * Flag indicating that a document is a directory that supports search.
+ *
+ * @see DocumentColumns#FLAGS
+ */
+ public static final int FLAG_SUPPORTS_SEARCH = 1 << 4;
/**
* Optimal dimensions for a document thumbnail request, stored as a
* {@link Point} object. This is only a hint, and the returned thumbnail may
* have different dimensions.
+ *
+ * @see ContentProvider#openTypedAssetFile(Uri, String, Bundle)
*/
public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
+ /**
+ * Extra boolean flag included in a directory {@link Cursor#getExtras()}
+ * indicating that the backend can provide additional data if requested,
+ * such as additional search results.
+ */
+ public static final String EXTRA_HAS_MORE = "has_more";
+
+ /**
+ * Extra boolean flag included in a {@link Cursor#respond(Bundle)} call to a
+ * directory to request that additional data should be fetched. When
+ * requested data is ready, the provider should send a change notification
+ * to cause a requery.
+ *
+ * @see Cursor#respond(Bundle)
+ * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver,
+ * boolean)
+ */
+ public static final String EXTRA_REQUEST_MORE = "request_more";
+
+ private static final String PATH_ROOTS = "roots";
private static final String PATH_DOCS = "docs";
private static final String PATH_CONTENTS = "contents";
private static final String PATH_SEARCH = "search";
- private static final String PARAM_QUERY = "query";
+ public static final String PARAM_QUERY = "query";
+
+ /**
+ * Build URI representing the custom roots in a storage backend.
+ */
+ public static Uri buildRootsUri(String authority) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_ROOTS).build();
+ }
/**
* Build URI representing the given {@link DocumentColumns#GUID} in a
@@ -108,11 +156,14 @@ public final class DocumentsContract {
}
/**
- * Build URI representing a search for matching documents in a storage
- * backend.
+ * Build URI representing a search for matching documents under a directory
+ * in a storage backend.
+ *
+ * @param documentUri directory to search under, which must have
+ * {@link #FLAG_SUPPORTS_SEARCH}.
*/
- public static Uri buildSearchUri(String authority, String query) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+ public static Uri buildSearchUri(Uri documentUri, String query) {
+ return documentUri.buildUpon()
.appendPath(PATH_SEARCH).appendQueryParameter(PARAM_QUERY, query).build();
}
@@ -134,7 +185,8 @@ public final class DocumentsContract {
public interface DocumentColumns extends OpenableColumns {
/**
* The globally unique ID for a document within a storage backend.
- * Values <em>must</em> never change once returned.
+ * Values <em>must</em> never change once returned. This field is
+ * read-only to document clients.
* <p>
* Type: STRING
*
@@ -144,7 +196,9 @@ public final class DocumentsContract {
/**
* MIME type of a document, matching the value returned by
- * {@link ContentResolver#getType(android.net.Uri)}.
+ * {@link ContentResolver#getType(android.net.Uri)}. This field must be
+ * provided when a new document is created, but after that the field is
+ * read-only.
* <p>
* Type: STRING
*
@@ -154,7 +208,8 @@ public final class DocumentsContract {
/**
* Timestamp when a document was last modified, in milliseconds since
- * January 1, 1970 00:00:00.0 UTC.
+ * January 1, 1970 00:00:00.0 UTC. This field is read-only to document
+ * clients.
* <p>
* Type: INTEGER (long)
*
@@ -163,13 +218,74 @@ public final class DocumentsContract {
public static final String LAST_MODIFIED = "last_modified";
/**
- * Flags that apply to a specific document.
+ * Flags that apply to a specific document. This field is read-only to
+ * document clients.
* <p>
* Type: INTEGER (int)
*/
public static final String FLAGS = "flags";
}
+ public static final int ROOT_TYPE_SERVICE = 1;
+ public static final int ROOT_TYPE_SHORTCUT = 2;
+ public static final int ROOT_TYPE_DEVICE = 3;
+ public static final int ROOT_TYPE_DEVICE_ADVANCED = 4;
+
+ /**
+ * These are standard columns for the roots URI.
+ *
+ * @see DocumentsContract#buildRootsUri(String)
+ */
+ public interface RootColumns {
+ /**
+ * Storage root type, use for clustering.
+ * <p>
+ * Type: INTEGER (int)
+ *
+ * @see DocumentsContract#ROOT_TYPE_SERVICE
+ * @see DocumentsContract#ROOT_TYPE_DEVICE
+ */
+ public static final String ROOT_TYPE = "root_type";
+
+ /**
+ * GUID of directory entry for this storage root.
+ * <p>
+ * Type: STRING
+ */
+ public static final String GUID = "guid";
+
+ /**
+ * Icon resource ID for this storage root, or {@code 0} to use the
+ * default {@link ProviderInfo#icon}.
+ * <p>
+ * Type: INTEGER (int)
+ */
+ public static final String ICON = "icon";
+
+ /**
+ * Title for this storage root, or {@code null} to use the default
+ * {@link ProviderInfo#labelRes}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String TITLE = "title";
+
+ /**
+ * Summary for this storage root, or {@code null} to omit.
+ * <p>
+ * Type: STRING
+ */
+ public static final String SUMMARY = "summary";
+
+ /**
+ * Number of free bytes of available in this storage root, or -1 if
+ * unknown or unbounded.
+ * <p>
+ * Type: INTEGER (long)
+ */
+ public static final String AVAILABLE_BYTES = "available_bytes";
+ }
+
/**
* Return thumbnail representing the document at the given URI. Callers are
* responsible for their own caching. Given document must have
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4f501e7dbf3d..a6e68d0aba54 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -862,7 +862,6 @@ public class WebView extends AbsoluteLayout
* @param resultCallback A callback to be invoked when the script execution
* completes with the result of the execution (if any).
* May be null if no notificaion of the result is required.
- * @hide pending API council approval and CTS test coverage.
*/
public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
checkThread();
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 53abf196a699..d924447907fc 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -82,6 +82,8 @@ public final class WebViewFactory {
public static void setUseExperimentalWebView(boolean enable) {
SystemProperties.set(WebViewFactory.WEBVIEW_EXPERIMENTAL_PROPERTY,
enable ? "true" : "false");
+ Log.i(LOGTAG, "Use Experimental WebView changed: "
+ + SystemProperties.get(WebViewFactory.WEBVIEW_EXPERIMENTAL_PROPERTY, ""));
}
/** @hide */
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 345a39e8cbac..7b4352e66f3f 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -57,6 +57,23 @@ public class InputMethodUtils {
// This utility class is not publicly instantiable.
}
+ // ----------------------------------------------------------------------
+ // Utilities for debug
+ public static String getStackTrace() {
+ final StringBuilder sb = new StringBuilder();
+ try {
+ throw new RuntimeException();
+ } catch (RuntimeException e) {
+ final StackTraceElement[] frames = e.getStackTrace();
+ // Start at 1 because the first frame is here and we don't care about it
+ for (int j = 1; j < frames.length; ++j) {
+ sb.append(frames[j].toString() + "\n");
+ }
+ }
+ return sb.toString();
+ }
+ // ----------------------------------------------------------------------
+
public static boolean isSystemIme(InputMethodInfo inputMethod) {
return (inputMethod.getServiceInfo().applicationInfo.flags
& ApplicationInfo.FLAG_SYSTEM) != 0;
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 2169c8ed13be..c23ee101dfab 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -299,6 +299,9 @@ redirects:
# ------------------- TRAINING -------------------
+- from: /guide/topics/ui/layout/tabs.html
+ to: /training/implementing-navigation/lateral.html
+
- from: /training/cloudsync/aesync.html
to: /google/gcm/index.html
diff --git a/docs/html/about/versions/jelly-bean.jd b/docs/html/about/versions/jelly-bean.jd
index 985a26634b17..5deb1900106d 100644
--- a/docs/html/about/versions/jelly-bean.jd
+++ b/docs/html/about/versions/jelly-bean.jd
@@ -7,14 +7,7 @@ tab3=Android 4.1
tab3.link=#android-41
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
+
<style>
#android-41 {display:none;}
diff --git a/docs/html/channels/io2013.jd b/docs/html/channels/io2013.jd
index b2bde312aa4f..977eb2f2aed3 100644
--- a/docs/html/channels/io2013.jd
+++ b/docs/html/channels/io2013.jd
@@ -1,15 +1,7 @@
fullpage=true
page.title=Google I/O 13
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
-
+
<style>
#ioplayer-frame {
z-index:10;
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index ab6bb1b67636..00f44677d8dd 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -1,13 +1,5 @@
page.title=Downloads
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div class="layout-content-row">
<div class="layout-content-col span-9">
diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd
index d4ef07fd0c8f..1e6b40c5876b 100644
--- a/docs/html/design/index.jd
+++ b/docs/html/design/index.jd
@@ -2,14 +2,6 @@ page.title=Design
header.hide=1
footer.hide=1
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<style>
#landing-graphic-container {
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 7e2337c28f3c..1833f24e2e75 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -4,14 +4,6 @@ header.hide=1
carousel=1
tabbedList=1
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<style>
#noplayer-message {
@@ -140,7 +132,7 @@ more</a></p>
<li><a href="//android-developers.blogspot.com/2013/07/beautiful-design-collection-summer-2013.html">
<div class="feed-image" style="background:url('//1.bp.blogspot.com/-k8DZYu0daT4/UdRt1AzstvI/AAAAAAAAAFM/CvEkb2yh-i0/s965/beautifulapps_4.png') no-repeat 0 0"></div>
<h4>The Beautiful Design Summer 2013 Collection</h4>
- <p>See the apps chosen by the Android Design for their masterfully crafted design details...</p>
+ <p>See the apps chosen by the Android Design team for their masterfully crafted design details...</p>
</a></li>
<li><a href="//android-developers.blogspot.com/2013/06/google-play-developer-8-step-checkup.html">
<div class="feed-image" style="background:url('//4.bp.blogspot.com/-LeK74UYY1eM/UbD8L-2DpFI/AAAAAAAACZA/YMjwndr-ZgM/s400/DoctorDroidV2.png') no-repeat 0 0;background-size:130px;background-position:8px -4px;"></div>
diff --git a/docs/html/distribute/distribute_toc.cs b/docs/html/distribute/distribute_toc.cs
index 75cf9f93d13e..ecdf2a842301 100644
--- a/docs/html/distribute/distribute_toc.cs
+++ b/docs/html/distribute/distribute_toc.cs
@@ -80,6 +80,7 @@
<div class="nav-section-header"><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/index.html">Spotlight</a></div>
<ul>
<li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/tablets.html">Tablet Stories</a></li>
+ <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/games.html">Game Stories</a></li>
</ul>
</li>
diff --git a/docs/html/distribute/googleplay/promote/badges.jd b/docs/html/distribute/googleplay/promote/badges.jd
index 93092bfcb66e..9a32921e2cbf 100644
--- a/docs/html/distribute/googleplay/promote/badges.jd
+++ b/docs/html/distribute/googleplay/promote/badges.jd
@@ -1,13 +1,5 @@
page.title=Google Play Badges
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<p itemprop="description">Google Play badges allow you to promote your app with official branding
in your online ads, promotional materials, or anywhere else you want a link to your app.</p>
diff --git a/docs/html/distribute/googleplay/promote/brand.jd b/docs/html/distribute/googleplay/promote/brand.jd
index a047b1fa098a..265584f6fa83 100644
--- a/docs/html/distribute/googleplay/promote/brand.jd
+++ b/docs/html/distribute/googleplay/promote/brand.jd
@@ -1,13 +1,6 @@
page.title=Brand Guidelines
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
+
<p>We encourage you to use the Android and Google Play brands with your Android app
diff --git a/docs/html/distribute/googleplay/promote/index.jd b/docs/html/distribute/googleplay/promote/index.jd
index 14f37c4d1b5c..68829907fe22 100644
--- a/docs/html/distribute/googleplay/promote/index.jd
+++ b/docs/html/distribute/googleplay/promote/index.jd
@@ -3,14 +3,6 @@ page.metaDescription=Raise the visibility of your apps in Google Play through de
header.hide=0
footer.hide=0
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<!--
<style>
diff --git a/docs/html/distribute/googleplay/promote/linking.jd b/docs/html/distribute/googleplay/promote/linking.jd
index 014582a39e43..4fdc5dba1a9a 100644
--- a/docs/html/distribute/googleplay/promote/linking.jd
+++ b/docs/html/distribute/googleplay/promote/linking.jd
@@ -1,13 +1,5 @@
page.title=Linking to Your Products
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div class="sidebox-wrapper">
<div class="sidebox">
diff --git a/docs/html/distribute/googleplay/publish/preparing.jd b/docs/html/distribute/googleplay/publish/preparing.jd
index dd35b25aeb6a..5593f4f8efc9 100644
--- a/docs/html/distribute/googleplay/publish/preparing.jd
+++ b/docs/html/distribute/googleplay/publish/preparing.jd
@@ -1,14 +1,6 @@
page.title=Launch Checklist
page.tags="publishing","launch","Google Play", "Developer Console"
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div id="qv-wrapper"><div id="qv">
<h2>Checklist</h2>
diff --git a/docs/html/distribute/googleplay/quality/core.jd b/docs/html/distribute/googleplay/quality/core.jd
index 3fd221cddda4..9e23bcca28a5 100644
--- a/docs/html/distribute/googleplay/quality/core.jd
+++ b/docs/html/distribute/googleplay/quality/core.jd
@@ -1,13 +1,5 @@
page.title=Core App Quality Guidelines
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div id="qv-wrapper"><div id="qv">
<h2>Quality Criteria</h2>
diff --git a/docs/html/distribute/googleplay/quality/index.jd b/docs/html/distribute/googleplay/quality/index.jd
index def42e503950..ef537b14f8e7 100644
--- a/docs/html/distribute/googleplay/quality/index.jd
+++ b/docs/html/distribute/googleplay/quality/index.jd
@@ -1,13 +1,5 @@
page.title=App Quality
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<p>App quality directly influences the long-term success of your app&mdash;in
terms of installs, user rating and reviews, engagement, and user retention.
diff --git a/docs/html/distribute/googleplay/quality/tablet.jd b/docs/html/distribute/googleplay/quality/tablet.jd
index c80c3cc978ba..36e7345976bd 100644
--- a/docs/html/distribute/googleplay/quality/tablet.jd
+++ b/docs/html/distribute/googleplay/quality/tablet.jd
@@ -1,13 +1,5 @@
page.title=Tablet App Quality Checklist
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div id="qv-wrapper"><div id="qv">
<h2>Checklist</h2>
@@ -312,7 +304,7 @@ without blurring or other scaling artifacts.</p>
<td>144x144 px</td>
<td>96x96 px</td>
<td>48x48 px</td>
-<td>74x74 px</td>
+<td>72x72 px</td>
</tr>
</table>
diff --git a/docs/html/distribute/googleplay/spotlight/games.jd b/docs/html/distribute/googleplay/spotlight/games.jd
new file mode 100644
index 000000000000..4e356dbe7afa
--- /dev/null
+++ b/docs/html/distribute/googleplay/spotlight/games.jd
@@ -0,0 +1,245 @@
+page.title=Developer Stories: Google Play Game Services
+walkthru=0
+header.hide=0
+
+@jd:body
+
+<p>One of the goals of <a href="https://developers.google.com/games/">Google
+Play game services</a> is to allow developers to focus on what they’re good at
+as game developers &mdash; creating great gaming experiences for their users, by
+building on top of what Google is good at: mobile and cloud services. Integral
+to that is an easy integration process, one that provides a whole host of
+features with little engineering work required.</p>
+
+<p>The gaming studios below understood the opportunity that Google Play game
+services unlocked, and are starting to see real results following their
+successful integrations. </p>
+
+<div style="margin-bottom:2em;"><!-- START STORY -->
+
+<h3>Concrete Software &mdash; Straightforward, easy to implement</h3>
+
+<img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px height:78px;
+ width: 78px;
+ float: left;
+ margin: 12px 20px 9px 20px;"
+ src="//lh6.ggpht.com/_UOay5HBxf077suKYzmikU2IbnYOJub3X0inz-LoUsVh4TX758BEyArjoR7owXijkAA=w124">
+
+<div style="list-style: none;height:100%;
+ float: right;
+ border-top: 1px solid #9C0;
+ width: 220px;
+ margin: 4px 20px;padding: .5em;">
+
+ <h5>About the developer</h5>
+ <ul>
+ <li><a href="https://play.google.com/store/apps/developer?id=Concrete%20Software%2C%20Inc.">Concrete Software</a>,
+ makers of <a href="https://play.google.com/store/apps/details?id=com.concretesoftware.pbachallenge_androidmarket&hl=en">PBA
+ Bowling Challenge</a></li>
+ <li>Added support for multiplayer, leaderboards and achievements through Google Play game
+ services</li>
+ </ul>
+
+ <h5>Results</h5>
+ <ul>
+ <li>Session lengths have increased more than 15%</li>
+ </ul>
+
+ <div style="padding:.5em 0 0 1em;">
+ <a href="https://play.google.com/store/apps/details?id=com.concretesoftware.pbachallenge_androidmarket&hl=en">
+ <img alt="Android app on Google Play" src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+ </a>
+ </div>
+</div>
+
+<div style="line-height:1.4em;">
+<p style="margin-top:0;margin-bottom:12px;">Concrete Software added several
+features from Google Play game services into one of their top titles,
+<a href="https://play.google.com/store/apps/details?id=com.concretesoftware.pbachallenge_androidmarket">PBA
+Bowling Challenge</a>, including support for multiplayer, leaderboards, and
+achievements.</p>
+
+<p>So far, their users have loved the new additions: average session length
+is up more than 15%. Keith Pichelman, CEO of Concrete Software, explains: </p>
+
+<p>"The Google Play game services were straightforward and easy to implement. We
+had been researching options for multiplayer services, so when Google Play game
+services came out, it was an easy decision for us. Not only were they easy to
+integrate, but the features have worked flawlessly. </p>
+
+<p>"PBA Bowling Challenge now has real-time multiplayer which our users instantly
+were thrilled with; you can see in the reviews how people immediately raved about
+the new game experience. </p>
+
+<p>"We also included achievements, leaderboards, and most recently cloud
+synchronization from the Google Play game services as well. Using the game
+services in PBA Bowling Challenge was a huge success, enough so that we are now
+going back to our other titles, adding the features to them as well."</p>
+</div>
+
+<div style="clear:both;margin-top:40px;width:auto;">
+
+ <img src="{@docRoot}images/distribute/concrete-pbc-gpgames.jpg">
+
+ <div style="width:600px;margin-top:0px;padding:0 90px;">
+ <p class="image-caption"><span style="font-weight:500;">Session lengths up:</span>
+ After adding support for multiplayer with Google Play game services, Concrete
+ Software saw an increase in session lengths of more than 15% for PBA Bowling
+ Challenge.</p>
+ </div>
+</div>
+</div> <!-- END STORY -->
+
+<div style="margin:3em auto"><!-- START STORY -->
+
+<h3>Glu: It’s a must-have for all titles</h3>
+
+<img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px height:78px;
+ width: 78px;
+ float: left;
+ margin: 12px 20px 30px 20px;"
+ src="//lh5.ggpht.com/l20dR2HYLV8vECoC35q_0NdfaAGTe4lZIFy_wCJRDqZjeQqSgneLRpXi3qOnnCaLXA=w124">
+
+<div style="list-style: none;height:100%;
+ float: right;
+ border-top: 1px solid #9C0;
+ width: 220px;
+ margin: 4px 20px;padding: .5em;">
+
+ <h5>About the developer</h5>
+ <ul>
+ <li><a href="https://play.google.com/store/apps/developer?id=Glu+Mobile">Glu
+ Mobile</a>, creators of <a href="https://play.google.com/store/apps/details?id=com.glu.ewarriors2">Eternity
+ Warriors 2</a></li>
+ <li>Has already integrated 5 titles with Google Play game services</li>
+ </ul>
+
+ <h5>Results</h5>
+ <ul>
+ <li>In Eternity Warriors 2, 7-day user retention is up 40%</li>
+ <li>20% increase in play sessions per day as well</li>
+ </ul>
+
+ <div style="padding:.5em 0 0 1em;">
+ <a href="https://play.google.com/store/apps/details?id=com.glu.ewarriors2">
+ <img alt="Android app on Google Play" src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+ </a>
+ </div>
+</div>
+
+<div style="line-height:1.4em;">
+<p style="margin-top:0;margin-bottom:12px;">Glu was one of the first developers
+to integrate Google Play game services, with
+<a href="https://play.google.com/store/apps/details?id=com.glu.ewarriors2">Eternity
+Warriors 2</a>. Based on this first success, Glu has integrated game services
+into several more games, including Samurai vs. Zombies 2, Frontline Commando:
+D-Day, Contract Killer 2, and Zombies Ate My Friends.</p>
+
+<p>Already supported in Eternity Warriors 2, they’ve seen a 40% increase in 7-day
+user retention and a 20% increase in play sessions per day. Sourabh Ahuja, Glu's
+Vice President of Android Development, explains:</p>
+
+<p>“Multiplayer, leaderboards, achievements &mdash; these are all things that we
+had to build individually for our titles. The availability of these features in
+Google Play game services helps us make our games stickier, and it’s awesome that
+it comes directly from Google. </p>
+
+<p>"It’s flexible enough that we were able to make it interoperable with our
+in-house systems. We look forward to utilizing game services extensively across
+our portfolio."</p>
+</div>
+
+<div style="clear:both;margin-top:40px;width:auto;">
+
+ <img src="{@docRoot}images/distribute/glu-ew-gpgames.jpg"></a>
+
+ <div style="width:600px;margin-top:0px;padding:0 90px;">
+ <p class="image-caption"><span style="font-weight:500;">User retention up:</span>
+ Glu saw a 40% increase in 7-day user retention for Eternity Warriors 2 after
+ integrating with Google Play game services.</p>
+ </div>
+</div>
+</div> <!-- END STORY -->
+
+
+<div style="margin-bottom:2em;"><!-- START STORY -->
+
+<h3>Vector-Unit: An awesome multiplayer experience</h3>
+
+<img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px height:78px;
+ width: 78px;
+ float: left;
+ margin: 12px 20px 9px 20px;" src=
+ "https://lh3.ggpht.com/dTUrKLffqXHJtPuIlp8fjDhROuzrTcpidbNFprugR65hMrPLX7Omd8SGop0xMXXKzcw=w124">
+
+<div style="list-style: none;height:100%;
+ float: right;
+ border-top: 1px solid #9C0;
+ width: 220px;
+ margin: 4px 20px;padding: .5em;">
+
+ <h5>About the developer</h5>
+ <ul>
+ <li><a href="https://play.google.com/store/apps/developer?id=Vector+Unit">Vector
+ Unit</a>, creators of <a href="https://play.google.com/store/apps/details?id=com.vectorunit.red">Riptide
+ GP2</a></li>
+ <li>Added multiplayer to Riptide GP2 through Google Play game services </li>
+ </ul>
+
+ <h5>Results</h5>
+ <ul>
+ <li>With an easy multiplayer solution, they were able to focus on the
+ gameplay</li>
+ <li>Early reviews of Riptide GP2 called multiplayer “one of the sweetest
+ cherries on top!”</li>
+ </ul>
+
+ <div style="padding:.5em 0 0 1em;">
+ <a href="https://play.google.com/store/apps/details?id=com.vectorunit.red">
+ <img alt="Android app on Google Play" src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+ </a>
+ </div>
+</div>
+
+<div style="line-height:1.4em;">
+<p style="margin-top:0;margin-bottom:12px;">Vector Unit just launched their
+latest title, <a href="https://play.google.com/store/apps/details?id=com.vectorunit.red">Riptide
+GP2</a>, with Google Play game services integration, and it has one of the strongest
+integrations of multiplayer yet. Early reviews call multiplayer “one of the sweetest
+cherries on top!”.</p>
+
+<p>Ralf Knoesel, CTO of Vector Unit, tells more about how they've used Google Play game
+services:</p>
+
+<p>“We wanted to provide a really compelling multiplayer experience for our users, and
+Google Play game services allowed us to do just that. With multiplayer, you can show off
+your skills and your custom-tuned hydro jet in 4-way online battles with friends and
+players around the world. </p>
+
+<p>"By providing an easy way to power this multiplayer experience, we were able to focus
+on making the gameplay come alive &mdash; like the stunts, which are more daring and
+slicker than ever (with more of them to master), or the realistic detail of the water
+splashing against the camera lens.”</p>
+
+</div>
+
+<div style="clear:both;margin-top:40px;width:auto;">
+
+ <img src="{@docRoot}images/distribute/vector-unit-rt-gpgames.jpg"></a>
+
+ <div style="width:600px;margin-top:0px;padding:0 90px;">
+ <p class="image-caption"><span style="font-weight:500;">Multiplayer and more:</span>
+ Google Play game services helped Vector Unit pack an awesome multiplayer experience
+ into Riptide GP 2, so they could focus on building a great gaming experience.</p>
+ </div>
+</div>
+</div> <!-- END STORY -->
+
+
+
diff --git a/docs/html/distribute/googleplay/spotlight/index.jd b/docs/html/distribute/googleplay/spotlight/index.jd
index 7004b0a63cb4..c59962892cae 100644
--- a/docs/html/distribute/googleplay/spotlight/index.jd
+++ b/docs/html/distribute/googleplay/spotlight/index.jd
@@ -3,14 +3,7 @@ walkthru=0
header.hide=0
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
+
<p>Android developers, their apps, and their successes with Android and Google Play. </p>
diff --git a/docs/html/distribute/index.jd b/docs/html/distribute/index.jd
index 8e7c6e1b221b..54f93015e8d6 100644
--- a/docs/html/distribute/index.jd
+++ b/docs/html/distribute/index.jd
@@ -2,14 +2,6 @@ page.title=Distribute Apps
header.hide=1
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div class="marquee">
diff --git a/docs/html/distribute/promote/device-art.jd b/docs/html/distribute/promote/device-art.jd
index 09a39417fe46..89231b2bed28 100644
--- a/docs/html/distribute/promote/device-art.jd
+++ b/docs/html/distribute/promote/device-art.jd
@@ -1,13 +1,5 @@
page.title=Device Art Generator
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<p>The device art generator allows you to quickly wrap your app screenshots in real device artwork.
This provides better visual context for your app screenshots on your web site or in other
@@ -47,7 +39,9 @@ feature image or screenshots for your Google Play app listing.</p>
</p>
</div>
<div class="layout-content-col span-10">
- <div id="output">No input image.</div>
+ <!-- position:relative fixes an issue where dragging an image out of a inline-block container
+ produced no drag feedback image in Chrome 28. -->
+ <div id="output" style="position:relative">No input image.</div>
</div>
</div>
@@ -143,6 +137,8 @@ feature image or screenshots for your Google Play app listing.</p>
// Global variables
var g_currentImage;
var g_currentDevice;
+ var g_currentObjectURL;
+ var g_currentBlob;
// Global constants
var MSG_INVALID_INPUT_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
@@ -267,14 +263,15 @@ feature image or screenshots for your Google Play app listing.</p>
return;
}
+ polyfillCanvasToBlob();
setupUI();
// Set up Chrome drag-out
$.event.props.push("dataTransfer");
document.body.addEventListener('dragstart', function(e) {
- var a = e.target;
- if (a.classList.contains('dragout')) {
- e.dataTransfer.setData('DownloadURL', a.dataset.downloadurl);
+ var target = e.target;
+ if (target.classList.contains('dragout')) {
+ e.dataTransfer.setData('DownloadURL', target.dataset.downloadurl);
}
}, false);
});
@@ -419,7 +416,7 @@ feature image or screenshots for your Google Play app listing.</p>
ctx.translate(-h, 0);
ctx.drawImage(g_currentImage, 0, 0);
- loadImageFromUri(canvas.toDataURL(), function(img) {
+ loadImageFromUri(canvas.toDataURL('image/png'), function(img) {
g_currentImage = img;
createFrame();
});
@@ -459,10 +456,10 @@ feature image or screenshots for your Google Play app listing.</p>
var resourceImages = {};
loadImageResources(resList, function(r) {
resourceImages = r;
- continuation_();
+ continueWithResources_();
});
- function continuation_() {
+ function continueWithResources_() {
var width = resourceImages['back'].naturalWidth;
var height = resourceImages['back'].naturalHeight;
var offset = port ? g_currentDevice.portOffset : g_currentDevice.landOffset;
@@ -486,17 +483,46 @@ feature image or screenshots for your Google Play app listing.</p>
ctx.drawImage(resourceImages['fore'], 0, 0);
}
- var dataUrl = canvas.toDataURL();
+ window.URL = window.URL || window.webkitURL;
+ if (canvas.toBlob && window.URL.createObjectURL) {
+ if (g_currentObjectURL) {
+ window.URL.revokeObjectURL(g_currentObjectURL);
+ g_currentObjectURL = null;
+ }
+ if (g_currentBlob) {
+ if (g_currentBlob.close) {
+ g_currentBlob.close();
+ }
+ g_currentBlob = null;
+ }
+
+ canvas.toBlob(function(blob) {
+ if (!blob) {
+ continueWithFinalUrl_(canvas.toDataURL('image/png'));
+ return;
+ }
+ g_currentBlob = blob;
+ g_currentObjectURL = window.URL.createObjectURL(blob);
+ continueWithFinalUrl_(g_currentObjectURL);
+ }, 'image/png');
+ } else {
+ continueWithFinalUrl_(canvas.toDataURL('image/png'));
+ }
+ }
+
+ function continueWithFinalUrl_(imageUrl) {
var filename = g_currentFilename
- ? ('framed_' + g_currentFilename)
+ ? g_currentFilename.replace(/^(.+?)(\.\w+)?$/, '$1_framed.png')
: 'framed_screenshot.png';
var $link = $('<a>')
.attr('download', filename)
- .attr('href', dataUrl)
- .attr('draggable', true)
- .attr('data-downloadurl', ['image/png', filename, dataUrl].join(':'))
- .append($('<img>').attr('src', dataUrl))
+ .attr('href', imageUrl)
+ .append($('<img>')
+ .addClass('dragout')
+ .attr('src', imageUrl)
+ .attr('draggable', true)
+ .attr('data-downloadurl', ['image/png', filename, imageUrl].join(':')))
.appendTo($('#output').empty());
$('#frame-customizations').show();
@@ -566,14 +592,14 @@ feature image or screenshots for your Google Play app listing.</p>
var file = null;
for (var i = 0; i < fileList.length; i++) {
- if (fileList[i].type.toLowerCase().match(/^image\/png/)) {
+ if (fileList[i].type.toLowerCase().match(/^image\/(png|jpeg|jpg)/)) {
file = fileList[i];
break;
}
}
if (!file) {
- alert('Please use a valid screenshot file (PNG format).');
+ alert('Please use a valid screenshot file (PNG or JPEG format).');
callback(null);
return;
}
@@ -609,4 +635,28 @@ feature image or screenshots for your Google Play app listing.</p>
fileReader.readAsDataURL(file);
}
+
+ /**
+ * Adds a simple version of Canvas.toBlob if toBlob isn't available.
+ */
+ function polyfillCanvasToBlob() {
+ if (!HTMLCanvasElement.prototype.toBlob && window.Blob) {
+ HTMLCanvasElement.prototype.toBlob = function(callback, mimeType, quality) {
+ if (typeof callback != 'function') {
+ throw new TypeError('Function expected');
+ }
+ var dataURL = this.toDataURL(mimeType, quality);
+ mimeType = dataURL.split(';')[0].split(':')[1];
+ var bs = window.atob(dataURL.split(',')[1]);
+ if (dataURL == 'data:,' || !bs.length) {
+ callback(null);
+ return;
+ }
+ for (var ui8arr = new Uint8Array(bs.length), i = 0; i < bs.length; ++i) {
+ ui8arr[i] = bs.charCodeAt(i);
+ }
+ callback(new Blob([ui8arr.buffer /* req'd for Safari */ || ui8arr], {type: mimeType}));
+ };
+ }
+ }
</script>
diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd
index 095388e0dc6e..4020cf451274 100644
--- a/docs/html/google/index.jd
+++ b/docs/html/google/index.jd
@@ -1,14 +1,6 @@
page.title=Google Services
header.hide=1
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<style>
div.landing-cell,
diff --git a/docs/html/google/play-services/auth.jd b/docs/html/google/play-services/auth.jd
index 3ccc81a8240b..7acaf1cd6834 100644
--- a/docs/html/google/play-services/auth.jd
+++ b/docs/html/google/play-services/auth.jd
@@ -23,7 +23,7 @@ page.tags="AccountManager","oauth2"
</p>
<p>For implementation details, see the sample in <code>&lt;android-sdk&gt;/extras/google-play-services/samples/auth</code>,
-which shows you how to carry out these basic steps for obtaining an acesss token.</p>
+which shows you how to carry out these basic steps for obtaining an access token.</p>
<h2 id="choose">Choosing an Account</h2>
<p>
diff --git a/docs/html/google/play/billing/gp-purchase-status-api.jd b/docs/html/google/play/billing/gp-purchase-status-api.jd
index d6b251ea9d0a..c5b84616d0aa 100644
--- a/docs/html/google/play/billing/gp-purchase-status-api.jd
+++ b/docs/html/google/play/billing/gp-purchase-status-api.jd
@@ -118,13 +118,13 @@ Purchase Status API. For security reasons, the app should not normally attempt t
the purchase itself using the Purchase Status API.</p>
<p>If the backend server determines that the purchase is valid, it notifies the
-app and grant access to the content. For improved performance, the backend servers
-should store the purchase details and order status in a local database, updated a
+app and grants access to the content. For improved performance, the backend servers
+should store the purchase details and order status in a local database, updated at
intervals or as-needed.</p>
-<p>Keep in mind that users will want to be able to use your app at any time, including
+<p>Keep in mind that users will want the ability to use your app at any time, including
when there may be no network connection available. Make sure that your approach to
-purchase verification takes account of the offline use-case.</p>
+purchase verification accounts for the offline use-case.</p>
<h2 id="practices">Using the API Efficiently</h2>
@@ -154,7 +154,7 @@ minimize your access using the techniques below. </p>
query each day to check the status of expiring subscriptions, then update the database.
Note that:
<ul>
- <li>Your servers should not query all subscriptions every day</li>
+ <li>Your servers should not query all subscriptions every day.</li>
<li>Your servers should never query subscription status dynamically, based on
individual requests from your Android application.</li>
</ul>
@@ -162,5 +162,6 @@ minimize your access using the techniques below. </p>
</ul>
<p>By following those general guidelines, your implementation will offer the
-best possible performance for users and minimize use of the Google Play Android
-Developer API.</p>
+best possible performance for users and minimize use of the <a
+href="https://developers.google.com/android-publisher/v1_1/">Google Play Android
+Developer API</a>.</p>
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index 0818514fd532..481a79ce0143 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -1,13 +1,5 @@
page.title=Google Play In-app Billing
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<p>In-app Billing is a Google Play service that lets you sell digital content from inside
your applications. You can use the service to sell a wide range of content, including downloadable
diff --git a/docs/html/guide/components/index.jd b/docs/html/guide/components/index.jd
index 6ede87350fb9..87bae53bf22a 100644
--- a/docs/html/guide/components/index.jd
+++ b/docs/html/guide/components/index.jd
@@ -4,14 +4,6 @@ page.landing.intro=Android's application framework lets you create extremely ric
page.landing.image=images/develop/app_components.png
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div class="landing-docs">
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index db08c3e62645..2a313748744a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -146,9 +146,6 @@
<li><a href="<?cs var:toroot ?>guide/topics/ui/layout/grid.html">
<span class="en">Grid Layout</span>
</a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/ui/layout/tabs.html">
- <span class="en">Tab Layout</span>
- </a></li>
-->
<li><a href="<?cs var:toroot ?>guide/topics/ui/layout/listview.html">
<span class="en">List View</span>
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 6398646e70f1..6586c2f1a767 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -359,23 +359,6 @@ partially or totally obscuring them (unless the newer object is transparent).
<p>Enables you to specify the location of child objects relative to each other (child A to
the left of child B) or to the parent (aligned to the top of the parent).</p>
</div>
-
-<!--
-<div class="layout">
- <h4><a href="layout/tabs.html">Tabs</a></h4>
- <a href="layout/tabs.html"><img src="{@docRoot}images/ui/tabs-small.png" alt="" /></a>
- <p>Provides a tab selection list that monitors clicks and enables the application to change
-the screen whenever a tab is clicked.</p>
-</div>
-
-<div class="layout first">
- <h4><a href="layout/grid.html">Table Layout</a></h4>
- <a href="layout/table.html"><img src="{@docRoot}images/ui/gridlayout-small.png" alt="" /></a>
- <p>A tabular layout with an arbitrary number of rows and columns, each cell holding the
-widget of your choice. The rows resize to fit the largest column. The cell borders are not
-visible.</p>
-</div>
--->
<div class="layout">
<h4><a href="{@docRoot}guide/webapps/webview.html">Web View</a></h4>
diff --git a/docs/html/guide/topics/ui/layout/tabs.jd b/docs/html/guide/topics/ui/layout/tabs.jd
deleted file mode 100644
index 62663de8a84d..000000000000
--- a/docs/html/guide/topics/ui/layout/tabs.jd
+++ /dev/null
@@ -1,219 +0,0 @@
-page.title=Tabbed
-parent.title=Layouts
-parent.link=layout-objects.html
-@jd:body
-<div id="qv-wrapper">
-<div id="qv">
-<h2>In this document</h2>
- <ol>
- <li><a href="#example">Example</a></li>
- </ol>
- <h2>Key classes</h2>
- <ol>
-<li>{@link android.widget.TabWidget}</li>
-<li>{@link android.widget.TabHost}</li>
-<li>{@link android.widget.TabHost.TabSpec}</li>
-<li>{@link android.widget.FrameLayout}</li>
- </ol>
-</div>
-</div>
-<p>To create a tabbed UI, you need to use a {@link android.widget.TabHost} and a {@link
-android.widget.TabWidget}. The {@link android.widget.TabHost} must be the root node for the layout,
-which contains both the {@link android.widget.TabWidget} for displaying the tabs and a {@link
-android.widget.FrameLayout} for displaying the tab content.</p>
-
-<img src="{@docRoot}images/ui/tabs.png" alt="" />
-
-<p>You can implement your tab content in one of two ways: use the tabs to swap
-{@link android.view.View}s within the same {@link android.app.Activity}, or use the tabs to change
-between entirely separate activities. Which method you want for your application will depend on your
-demands, but if each tab provides a distinct user activity, then it probably makes sense to use
-a separate {@link android.app.Activity} for each tab, so that you can better manage the application
-in discrete groups, rather than one massive application and layout.</p>
-<h2 id="example">Example</h2>
-<p>In this tutorial, you'll create a tabbed UI that uses a separate {@link
-android.app.Activity} for each tab.</p>
-
-<ol>
- <li>Start a new project named <em>HelloTabWidget</em>.</li>
- <li>First, create three separate {@link android.app.Activity} classes in your project:
-<code>ArtistsActivity</code>, <code>AlbumsActivity</code>, and <code>SongsActivity</code>. These
-will each represent a separate tab. For now, make each one display a simple message using a {@link
-android.widget.TextView}. For example:
-<pre>
-public class ArtistsActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- TextView textview = new TextView(this);
- textview.setText("This is the Artists tab");
- setContentView(textview);
- }
-}
-</pre>
- <p>Notice that this doesn't use a layout file. Just create a {@link
-android.widget.TextView}, give it some text and set that as the content. Duplicate this for
-each of the three activities, and add the corresponding <code>&lt;activity/&gt;</code> tags to the Android Manifest file.</p>
-
- <li>You need an icon for each of your tabs. For each icon, you should create two versions: one
-for when the tab is selected and one for when it is unselected. The
-general design recommendation is for the selected icon to be a dark color (grey), and the
-unselected icon to be a light color (white). (See the <a
-href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#tabstructure">Icon Design
-Guidelines</a>.) For example:
- <p>
- <img src="images/ic_tab_artists_white.png" title="unselected tab icon" alt="" />
- <img src="images/ic_tab_artists_grey.png" title="selected tab icon" alt="" />
- </p>
- <p>For this tutorial, you can copy these images and use them for all three tabs. (When you
-create tabs in your own application, you should create customized tab icons.)</p>
- <p>Now create a <a
-href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a>
-that specifies which image to use for each tab state:</p>
- <ol>
- <li>Save the icon images in your project <code>res/drawable/</code> directory.</li>
- <li>Create a new XML file in <code>res/drawable/</code>
-named <code>ic_tab_artists.xml</code> and insert the following:
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
- &lt;!-- When selected, use grey -->
- &lt;item android:drawable="@drawable/ic_tab_artists_grey"
- android:state_selected="true" />
- &lt;!-- When not selected, use white-->
- &lt;item android:drawable="@drawable/ic_tab_artists_white" />
-&lt;/selector>
-</pre>
- <p>This is a <a
-href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a>,
-which you will apply as the tab image. When the tab state changes, the tab icon will
-automatically switch between the images defined here.</p>
- </li>
- </ol>
- </li>
-
- <li>Open the <code>res/layout/main.xml</code> file and insert the following:
- <pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;TabHost xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/tabhost"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- &lt;LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:padding="5dp">
- &lt;TabWidget
- android:id="@android:id/tabs"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- &lt;FrameLayout
- android:id="@android:id/tabcontent"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:padding="5dp" />
- &lt;/LinearLayout>
-&lt;/TabHost>
-</pre>
- <p>This is the layout that will display the tabs and provide navigation between each {@link
- android.app.Activity} created above.</p>
- <p>The {@link android.widget.TabHost} requires that a {@link android.widget.TabWidget} and a
-{@link android.widget.FrameLayout} both live somewhere within it. To position the {@link
-android.widget.TabWidget} and {@link android.widget.FrameLayout} vertically, a {@link
-android.widget.LinearLayout} is used. The {@link android.widget.FrameLayout} is where the content
-for each tab goes, which is empty now because the {@link android.widget.TabHost} will automatically
-embed each {@link android.app.Activity} within it.</p>
- <p>Notice that the {@link android.widget.TabWidget} and the {@link android.widget.FrameLayout}
- elements have the IDs {@code tabs} and {@code tabcontent}, respectively. These names
- must be used so that the {@link android.widget.TabHost} can retrieve references to each of
- them. It expects exactly these names.</p>
- </li>
-
- <li>Now open <code>HelloTabWidget.java</code> and make it extend {@link
- android.app.TabActivity}:</p>
-<pre>
-public class HelloTabWidget extends TabActivity {
-</pre>
- </li>
- <li>Use the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
- method:
-<pre>
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- Resources res = getResources(); // Resource object to get Drawables
- TabHost tabHost = getTabHost(); // The activity TabHost
- TabHost.TabSpec spec; // Resusable TabSpec for each tab
- Intent intent; // Reusable Intent for each tab
-
- // Create an Intent to launch an Activity for the tab (to be reused)
- intent = new Intent().setClass(this, ArtistsActivity.class);
-
- // Initialize a TabSpec for each tab and add it to the TabHost
- spec = tabHost.newTabSpec("artists").setIndicator("Artists",
- res.getDrawable(R.drawable.ic_tab_artists))
- .setContent(intent);
- tabHost.addTab(spec);
-
- // Do the same for the other tabs
- intent = new Intent().setClass(this, AlbumsActivity.class);
- spec = tabHost.newTabSpec("albums").setIndicator("Albums",
- res.getDrawable(R.drawable.ic_tab_albums))
- .setContent(intent);
- tabHost.addTab(spec);
-
- intent = new Intent().setClass(this, SongsActivity.class);
- spec = tabHost.newTabSpec("songs").setIndicator("Songs",
- res.getDrawable(R.drawable.ic_tab_songs))
- .setContent(intent);
- tabHost.addTab(spec);
-
- tabHost.setCurrentTab(2);
-}
-</pre>
- <p>This sets up each tab with their text and icon, and assigns each one an {@link
-android.app.Activity}.</p>
- <p>A reference to the {@link android.widget.TabHost} is first captured with {@link
-android.app.TabActivity#getTabHost()}. Then, for
-each tab, a {@link android.widget.TabHost.TabSpec} is created to define the tab properties. The
-{@link android.widget.TabHost#newTabSpec(String)} method creates a new {@link
-android.widget.TabHost.TabSpec} identified by the given string tag. For each
-{@link android.widget.TabHost.TabSpec}, {@link
-android.widget.TabHost.TabSpec#setIndicator(CharSequence,Drawable)} is called to set the text and
-icon for the tab, and {@link android.widget.TabHost.TabSpec#setContent(Intent)} is called to specify
-the {@link android.content.Intent} to open the appropriate {@link android.app.Activity}. Each
-{@link android.widget.TabHost.TabSpec} is then added to the {@link android.widget.TabHost} by
-calling {@link android.widget.TabHost#addTab(TabHost.TabSpec)}.</p>
-
- <p>At the very end, {@link
- android.widget.TabHost#setCurrentTab(int)} opens the tab to be displayed by default, specified
- by the index position of the tab.</p>
-
- <p>Notice that not once was the {@link android.widget.TabWidget} object referenced. This is
- because a {@link android.widget.TabWidget} must always be a child of a {@link
- android.widget.TabHost}, which is what you use for almost all interaction with the tabs. So when
- a tab is added to the {@link android.widget.TabHost}, it's automatically added to the child
- {@link android.widget.TabWidget}.</p>
- </li>
-
- <li>Now open the Android Manifest file and add the <code>NoTitleBar</code> theme to the
-<em>HelloTabWidget</em>'s
- <code>&lt;activity></code> tag. This will remove the default application title from the top
- of the layout, leaving more space for the tabs, which effectively operate as their own titles.
- The <code>&lt;activity></code> tag should look like this:
-<pre>
-&lt;activity android:name=".HelloTabWidget" android:label="@string/app_name"
- android:theme="&#64;android:style/Theme.NoTitleBar">
-</pre>
- </li>
-
- <li>Run the application.</li>
-</ol>
-
-
-<p>Your application should look like this (though your icons may be different):</p>
-<img src="images/hello-tabwidget.png" width="150px" />
-
-
diff --git a/docs/html/images/distribute/concrete-pbc-gpgames.jpg b/docs/html/images/distribute/concrete-pbc-gpgames.jpg
new file mode 100644
index 000000000000..c97ba8e74296
--- /dev/null
+++ b/docs/html/images/distribute/concrete-pbc-gpgames.jpg
Binary files differ
diff --git a/docs/html/images/distribute/glu-ew-gpgames.jpg b/docs/html/images/distribute/glu-ew-gpgames.jpg
new file mode 100644
index 000000000000..8d97f8de71c1
--- /dev/null
+++ b/docs/html/images/distribute/glu-ew-gpgames.jpg
Binary files differ
diff --git a/docs/html/images/distribute/vector-unit-rt-gpgames.jpg b/docs/html/images/distribute/vector-unit-rt-gpgames.jpg
new file mode 100644
index 000000000000..323f188aaa3c
--- /dev/null
+++ b/docs/html/images/distribute/vector-unit-rt-gpgames.jpg
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index a945f0a7a504..bbb6a16bc567 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -3,14 +3,6 @@ no_footer_links=true
carousel=true
page.metaDescription=The official site for Android developers. Provides the Android SDK and documentation for app developers and designers.
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
<div class="wrap">
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index aa3b2ec8761b..4ea375263d7d 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,43 +5,43 @@ header.hide=1
page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
-sdk.linux32_bundle_download=adt-bundle-linux-x86-20130717.zip
-sdk.linux32_bundle_bytes=440035305
-sdk.linux32_bundle_checksum=ecfacb91df1ee63cce1edd4f1a5cda5a
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20130729.zip
+sdk.linux32_bundle_bytes=457716139
+sdk.linux32_bundle_checksum=b3686d10dc1cbceba1074404d4386283
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130717.zip
-sdk.linux64_bundle_bytes=440322117
-sdk.linux64_bundle_checksum=ab177a06784340b8f1d136651e3dc62a
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130729.zip
+sdk.linux64_bundle_bytes=458006784
+sdk.linux64_bundle_checksum=1fabcc3f772ba8b2fc194d6e0449da17
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130717.zip
-sdk.mac64_bundle_bytes=411609229
-sdk.mac64_bundle_checksum=07c891212a49b5f8495ea9d8d47ba3fe
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130729.zip
+sdk.mac64_bundle_bytes=428792424
+sdk.mac64_bundle_checksum=6c42b9966abcfa8a75c0ee83d0d95882
-sdk.win32_bundle_download=adt-bundle-windows-x86-20130717.zip
-sdk.win32_bundle_bytes=446783216
-sdk.win32_bundle_checksum=0dd91095999d3539ca1ec4033d83d935
+sdk.win32_bundle_download=adt-bundle-windows-x86-20130729.zip
+sdk.win32_bundle_bytes=463931746
+sdk.win32_bundle_checksum=51faf4e5fdf9c5b4a176179a99ce3511
-sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130717.zip
-sdk.win64_bundle_bytes=446911629
-sdk.win64_bundle_checksum=61ec74995b39166db7f079017a028cec
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130729.zip
+sdk.win64_bundle_bytes=464064756
+sdk.win64_bundle_checksum=e8f05c1fddb8e609e880de23113c7426
-sdk.linux_download=android-sdk_r22.0.4-linux.tgz
-sdk.linux_bytes=105640988
-sdk.linux_checksum=4a5db98a58c68c24e66f04f07ac77da5
+sdk.linux_download=android-sdk_r22.0.5-linux.tgz
+sdk.linux_bytes=105641005
+sdk.linux_checksum=8201b10c21510f082c54f58a9bb082c8
-sdk.mac_download=android-sdk_r22.0.4-macosx.zip
-sdk.mac_bytes=77225662
-sdk.mac_checksum=384752505f4f2ba3627bd6aad0697f11
+sdk.mac_download=android-sdk_r22.0.5-macosx.zip
+sdk.mac_bytes=77225724
+sdk.mac_checksum=94f3cbe896c332b94ee0408ae610a4b8
-sdk.win_download=android-sdk_r22.0.4-windows.zip
-sdk.win_bytes=113507679
-sdk.win_checksum=320b11d1ed85fd3f5e937697c333d895
+sdk.win_download=android-sdk_r22.0.5-windows.zip
+sdk.win_bytes=113510621
+sdk.win_checksum=30695dffc41e0d7cf9ff948ab0c48920
-sdk.win_installer=installer_r22.0.4-windows.exe
-sdk.win_installer_bytes=93502726
-sdk.win_installer_checksum=96a8ae367d84ed219e1eb2cf473667d0
+sdk.win_installer=installer_r22.0.5-windows.exe
+sdk.win_installer_bytes=93505782
+sdk.win_installer_checksum=940849be19ac6151e3e35c8706c81d86
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 2a09636a256f..bdc07d02283d 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
page.title=Installing the Eclipse Plugin
-adt.zip.version=22.0.4
-adt.zip.download=ADT-22.0.4.zip
-adt.zip.bytes=16838756
-adt.zip.checksum=f0291f4bb9d78ec34a7751cd2402cc2a
+adt.zip.version=22.0.5
+adt.zip.download=ADT-22.0.5.zip
+adt.zip.bytes=16839757
+adt.zip.checksum=1097fccf32063e3638a9d27aa0f295ca
@jd:body
diff --git a/docs/html/tools/extras/oem-usb.jd b/docs/html/tools/extras/oem-usb.jd
index 5e0e893710b0..e0bbf335d89b 100644
--- a/docs/html/tools/extras/oem-usb.jd
+++ b/docs/html/tools/extras/oem-usb.jd
@@ -227,7 +227,7 @@ href="http://www.acer.com/worldwide/support/mobile.html">http://www.acer.com/wor
<tr>
<td style="font-variant:small-caps">alcatel one touch</td>
<td><a
-href="http://www.alcatel-mobilephones.com/global/Android-Downloads">http://www.alcatel-mobilephones.com/global/Android-Downloads</a></td>
+href="http://www.alcatelonetouch.com/global-en/support/faq/usbdriver.html">http://www.alcatelonetouch.com/global-en/support/faq/usbdriver.html</a></td>
</tr>
<tr>
<td>Asus</td>
diff --git a/docs/html/tools/index.jd b/docs/html/tools/index.jd
index e9094a79b820..f9d452c0c253 100644
--- a/docs/html/tools/index.jd
+++ b/docs/html/tools/index.jd
@@ -1,13 +1,6 @@
page.title=Developer Tools
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
+
<img src="{@docRoot}images/tools-home.png" style="float:right;" height="415" width="763" />
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 7b0b5a8f0eab..e9c514e064d3 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -57,6 +57,41 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>ADT 22.0.5</a> <em>(July 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.0.5</a>.
+ If you haven't already installed SDK Tools r22.0.5 into your SDK, use the
+ Android SDK Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed Renderscript compilation issue for Windows platforms.</li>
+ <li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> report generation
+ in the Monitor and DDMS perspectives.</li>
+ </ul>
+ </dd>
+
+</dl>
+</div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>ADT 22.0.4</a> <em>(July 2013)</em>
</p>
@@ -66,11 +101,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 22.0.4.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 22.0.4.</li>
- <li>ADT 22.0.4 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r22.0.4</a>. If you haven't already installed SDK Tools r22.0.4 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.0.4</a>.
+ If you haven't already installed SDK Tools r22.0.4 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -102,11 +138,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 22.0.1.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 22.0.1.</li>
- <li>ADT 22.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r22.0.1</a>. If you haven't already installed SDK Tools r22 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.0.1</a>.
+ If you haven't already installed SDK Tools r22.0.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -138,11 +175,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 22.0.0.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 22.0.0.</li>
- <li>ADT 22.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r22</a>. If you haven't already installed SDK Tools r22 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22</a>.
+ If you haven't already installed SDK Tools r22 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -181,11 +219,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 21.1.0.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 21.1.0.</li>
- <li>ADT 21.1.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r21.1</a>. If you haven't already installed SDK Tools r21.1 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r21.1</a>.
+ If you haven't already installed SDK Tools r21.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -238,11 +277,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 21.0.1.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 21.0.1.</li>
- <li>ADT 21.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r21.0.1</a>. If you haven't already installed SDK Tools r21.0.1 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r21.0.1</a>.
+ If you haven't already installed SDK Tools r21.0.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -357,11 +397,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 20.0.3.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 21.0.0.</li>
- <li>ADT 21.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r21</a>. If you haven't already installed SDK Tools r21.0.0 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r21</a>.
+ If you haven't already installed SDK Tools r21.0.0 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -478,11 +519,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 20.0.3.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 20.0.3.</li>
- <li>ADT 20.0.3 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r20.0.3</a>. If you haven't already installed SDK Tools r20.0.3 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r20.0.3</a>.
+ If you haven't already installed SDK Tools r20.0.3 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -512,11 +554,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 20.0.2.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 20.0.2.</li>
- <li>ADT 20.0.2 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r20.0.1</a>. If you haven't already installed SDK Tools r20.0.1 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r20.0.1</a>.
+ If you haven't already installed SDK Tools r20.0.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -547,11 +590,12 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 20.0.1.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 20.0.1.</li>
- <li>ADT 20.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK
- Tools r20.0.1</a>. If you haven't already installed SDK Tools r20.0.1 into your SDK, use the
- Android SDK Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r20.0.1</a>.
+ If you haven't already installed SDK Tools r20.0.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -588,11 +632,12 @@ unprotected receivers for default Android actions.</li>
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 20.0.0.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 20.0.0.</li>
- <li>ADT 20.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools
- r20</a>. If you haven't already installed SDK Tools r20 into your SDK, use the Android SDK
- Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r20</a>.
+ If you haven't already installed SDK Tools r20 into your SDK, use the Android SDK
+ Manager to do so.</li>
</ul>
</dd>
@@ -711,11 +756,12 @@ functions.</li>
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 18.0.0.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 18.0.0.</li>
- <li>ADT 18.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools
- r18</a>. If you haven't already installed SDK Tools r18 into your SDK, use the Android SDK
- Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r18</a>.
+ If you haven't already installed SDK Tools r18 into your SDK, use the Android SDK
+ Manager to do so.</li>
</ul>
</dd>
@@ -746,11 +792,12 @@ functions.</li>
<dd>
<ul>
- <li>Java 1.6 or higher is required for ADT 17.0.0.</li>
- <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 17.0.0.</li>
- <li>ADT 17.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools
- r17</a>. If you haven't already installed SDK Tools r17 into your SDK, use the Android SDK
- Manager to do so.</li>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r17</a>.
+ If you haven't already installed SDK Tools r17 into your SDK, use the Android SDK
+ Manager to do so.</li>
</ul>
</dd>
@@ -848,9 +895,10 @@ select. (<a href="http://code.google.com/p/android/issues/detail?id=20589">Issue
<dd>
<ul>
- <li>Eclipse Helios (Version 3.6) or higher is required for ADT 16.0.1.</li>
- <li>ADT 16.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools
- r16</a>. If you haven't already installed SDK Tools r16 into your SDK, use the Android SDK
+ <li>Eclipse Helios (Version 3.6) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r16</a>.
+ If you haven't already installed SDK Tools r16 into your SDK, use the Android SDK
Manager to do so.</li>
</ul>
</dd>
@@ -882,11 +930,11 @@ select. (<a href="http://code.google.com/p/android/issues/detail?id=20589">Issue
<dd>
<ul>
- <li>Eclipse Helios (Version 3.6) or higher is required for ADT
-16.0.0.</li>
- <li>ADT 16.0.0 is designed for use with <a
-href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r16</a>. If you haven't already installed SDK Tools
-r16 into your SDK, use the Android SDK Manager to do so.</li>
+ <li>Eclipse Helios (Version 3.6) or higher is required for ADT 16.0.0.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r16</a>.
+ If you haven't already installed SDK Tools r16 into your SDK, use
+ the Android SDK Manager to do so.</li>
</ul>
</dd>
@@ -913,9 +961,10 @@ href="http://tools.android.com/recent/lint">more info</a>)</li>
<dl>
<dt>Dependencies:</dt>
- <dd>ADT 15.0.1 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r15</a>.
- If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
- do so.</dd>
+ <dd>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r15</a>.
+ If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
+ do so.</dd>
<dt>Bug fixes:</dt>
<dd>
@@ -948,9 +997,10 @@ href="http://tools.android.com/recent/lint">more info</a>)</li>
<dt>Dependencies:</dt>
-<dd>ADT 15.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r15</a>.
-If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
-do so.</dd>
+<dd>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r15</a>.
+ If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
+ do so.</dd>
<dt>Bug fixes:</dt>
<dd>
@@ -980,9 +1030,10 @@ do so.</dd>
<dt>Dependencies:</dt>
-<dd>ADT 14.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r14</a>.
-If you haven't already installed SDK Tools r14 into your SDK, use the Android SDK Manager to
-do so.</dd>
+<dd>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r14</a>.
+ If you haven't already installed SDK Tools r14 into your SDK, use the Android SDK Manager to
+ do so.</dd>
<dt>Build system:</dt>
<dd>
@@ -1099,7 +1150,8 @@ Linux</a>.</dd>
<dt>Dependencies:</dt>
-<dd>ADT 12.0.0 is designed for use with <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r12</a>. If you haven't
+<dd>This version of ADT is designed for use with
+<a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r12</a>. If you haven't
already installed SDK Tools r12 into your SDK, use
the Android SDK Manager to do so.</dd>
@@ -1152,7 +1204,7 @@ the Android SDK Manager to do so.</dd>
<dt>Dependencies:</dt>
-<dd>ADT 11.0.0 is designed for use with SDK Tools r11. If you haven't
+<dd>This version of ADT is designed for use with SDK Tools r11. If you haven't
already installed SDK Tools r11 into your SDK, use the Android SDK Manager to do
so.</dd>
@@ -1289,7 +1341,7 @@ href="http://tools.android.com/recent">Android Tools Project Site</a>.</p>
<dt>Dependencies:</dt>
-<dd>ADT 10.0.1 is designed for use with SDK Tools r10. If you haven't
+<dd>This version of ADT is designed for use with SDK Tools r10. If you haven't
already installed SDK Tools r10 into your SDK, use the Android SDK Manager to do
so.</dd>
@@ -1319,7 +1371,7 @@ requires Eclipse 3.5 or higher (as of 10.0.0).</li>
<dt>Dependencies:</dt>
-<dd>ADT 10.0.0 is designed for use with SDK Tools r10. If you haven't
+<dd>This version of ADT is designed for use with SDK Tools r10. If you haven't
already installed SDK Tools r10 into your SDK, use the Android SDK Manager to do
so.</dd>
@@ -1369,7 +1421,7 @@ so.</dd>
<dt>Dependencies:</dt>
-<dd>ADT 9.0.0 is designed for use with SDK Tools r9. If you haven't
+<dd>This version of ADT is designed for use with SDK Tools r9. If you haven't
already installed SDK Tools r9 into your SDK, use the Android SDK Manager to do
so.</dd>
@@ -1478,7 +1530,7 @@ so.</dd>
<dt>Dependencies:</dt>
-<p><p>ADT 8.0.1 is designed for use with SDK Tools r8. If you haven't
+<p>This version of ADT is designed for use with SDK Tools r8. If you haven't
already installed SDK Tools r8 into your SDK, use the Android SDK Manager to do
so.</p></dd>
@@ -1507,7 +1559,7 @@ so.</p></dd>
<dt>Dependencies:</dt>
-<p><p>ADT 8.0.0 is designed for use with SDK Tools r8. If you haven't
+<p>This version of ADT is designed for use with SDK Tools r8. If you haven't
already installed SDK Tools r8 into your SDK, use the Android SDK Manager to do
so.</p></dd>
@@ -1656,7 +1708,7 @@ project support through the Ant build system.</p>
<dl>
<dt>Dependencies:</dt>
-<dd><p>ADT 0.9.6 is designed for use with SDK Tools r5 and later. Before
+<dd><p>This version of ADT is designed for use with SDK Tools r5 and later. Before
updating to ADT 0.9.6, we highly recommend that you use the Android SDK Manager to install SDK
Tools r5 into your SDK.</p></dd>
@@ -1725,7 +1777,7 @@ targets for application launches.</li>
<dl>
<dt>Dependencies:</dt>
-<dd><p>ADT 0.9.5 requires features provided in SDK Tools r4 or higher. If you install
+<dd><p>This version of ADT requires features provided in SDK Tools r4 or higher. If you install
ADT 0.9.5, which is highly recommended, you should use the Android SDK
Manager to download the latest SDK Tools into your SDK. For more information,
see <a href="{@docRoot}sdk/exploring.html">Exploring the SDK</a>.</p>
@@ -1755,7 +1807,7 @@ see <a href="{@docRoot}sdk/exploring.html">Exploring the SDK</a>.</p>
<dl>
<dt>Dependencies:</dt>
-<dd><p>ADT 0.9.4 requires features provided in SDK Tools r3 or higher. If you install
+<dd><p>This version of ADT requires features provided in SDK Tools r3 or higher. If you install
ADT 0.9.4, which is highly recommended, you should use the Android SDK
Manager to download the latest SDK Tools into your SDK. For more information,
see <a href="{@docRoot}sdk/exploring.html">Exploring the SDK</a>.</p>
diff --git a/docs/html/tools/sdk/ndk/index.jd b/docs/html/tools/sdk/ndk/index.jd
index 318764e2b4da..61a91a849389 100644
--- a/docs/html/tools/sdk/ndk/index.jd
+++ b/docs/html/tools/sdk/ndk/index.jd
@@ -63,7 +63,7 @@ page.title=Android NDK
<div id="tos" style="display:none;width:760px;height:0;margin:0 auto">
-<div class="ndk" style="
+<div id="download" class="ndk" style="
z-index: 99;
width: 720px;
position: absolute;
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index cd2d986dade4..4aef8a028505 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -26,9 +26,50 @@ Tools you are using, refer to the "Installed Packages" listing in the Android SD
href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
+
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>SDK Tools, Revision 22.0.5</a> <em>(July 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 16 or later.</li>
+ <li>If you are developing in Eclipse with the
+ <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a>, note that this version of
+ SDK Tools is designed for use with ADT 22.0.5 and later. If you haven't already, update
+ ADT to 22.0.5.</li>
+ <li>If you are using <a href="{@docRoot}sdk/installing/studio.html">Android Studio</a>,
+ note that this version of the SDK Tools is designed to work with Android Studio
+ 0.2.x and later.</li>
+ <li>If you are developing without an integrated development environment (IDE), you must have
+ <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed Renderscript compilation issue for Windows platforms with ant.</li>
+ <li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> to work with the
+ Android 4.3 platform image.</li>
+ <li>Fixed packaging of Renderscript compiler.</li>
+ <li>Build tools 18.0.0 is obsolete and 18.0.1 should be used instead.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>SDK Tools, Revision 22.0.4</a> <em>(July 2013)</em>
</p>
@@ -75,7 +116,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 16 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r22.0.1 is
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 22.0.1 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.0.1.</li>
<li>If you are developing outside Eclipse, you must have
@@ -116,7 +157,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 16 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r22 is
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 22.0.0 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -171,7 +212,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 16 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21.1 is
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 21.1.0 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.1.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -206,7 +247,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 16 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21.0.1 is
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 21.0.1 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.0.1.</li>
<li>If you are developing outside Eclipse, you must have
@@ -309,7 +350,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 16 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r21 is designed
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed
for use with ADT 21.0.0 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 21.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -395,7 +436,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 12 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r20.0.3 is designed
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed
for use with ADT 20.0.3 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 20.0.3.</li>
<li>If you are developing outside Eclipse, you must have
@@ -426,7 +467,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dd>
<ul>
<li>Android SDK Platform-tools revision 12 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r20.0.1 is designed
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed
for use with ADT 20.0.1 and later. If you haven't already, update your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 20.0.1.</li>
<li>If you are developing outside Eclipse, you must have
@@ -462,7 +503,7 @@ unprotected receivers for default Android actions.</li>
<dd>
<ul>
<li>Android SDK Platform-tools revision 12 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r20 is designed for
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for
use with ADT 20.0.0 and later. If you haven't already, we highly recommend updating your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 20.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -540,7 +581,7 @@ download and install this update.</p>
<dd>
<ul>
<li>Android SDK Platform-tools revision 9 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r19 is designed for
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for
use with ADT 18.0.0 and later. If you haven't already, we highly recommend updating your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 18.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -575,7 +616,7 @@ acceleration.</li>
<dd>
<ul>
<li>Android SDK Platform-tools revision 9 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r18 is designed for
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for
use with ADT 18.0.0 and later. If you haven't already, we highly recommend updating your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 18.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -617,7 +658,7 @@ in some cases.</li>
<dd>
<ul>
<li>Android SDK Platform-tools revision 9 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r17 is designed for
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for
use with ADT 17.0.0 and later. If you haven't already, we highly recommend updating your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 17.0.0.</li>
<li>If you are developing outside Eclipse, you must have
@@ -721,7 +762,7 @@ ignore attribute. (<a
<dd>
<ul>
<li>Android SDK Platform-tools revision 9 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r16 is designed for use
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use
with ADT 16.0.0 and later. If you haven't already, we highly recommend updating your
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 16.0.0.</li>
<li>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
@@ -769,7 +810,7 @@ ignore attribute. (<a
<dt>Dependencies:</dt>
<dd>
<ul><li>Android SDK Platform-tools revision 9 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r15 is designed for use
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use
with ADT 15.0.0 and later. If you haven't already, we highly recommend updating your <a
href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 15.0.0.</li>
<li>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
@@ -817,7 +858,7 @@ ignore attribute. (<a
<dt>Dependencies:</dt>
<dd>
<ul><li>Android SDK Platform-tools revision 8 or later.</li>
- <li>If you are developing in Eclipse with ADT, note that the SDK Tools r14 is designed for use
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use
with ADT 14.0.0 and later. If you haven't already, we highly recommend updating your <a
href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 14.0.0.</li>
<li>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
@@ -867,7 +908,7 @@ site</a>.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that the SDK Tools r13 is designed for use with
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use with
ADT 12.0.0 and later. If you haven't already, we highly recommend updating your <a
href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 12.0.0.</p>
@@ -898,7 +939,7 @@ Ant</a> 1.8 or later.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that the SDK Tools r12 is designed for use with
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use with
ADT 12.0.0 and later. If you haven't already, we highly recommend updating your <a
href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 12.0.0.</p>
@@ -926,7 +967,7 @@ Ant</a> 1.8 or later.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that the SDK Tools r11 is designed for use with
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is designed for use with
ADT 10.0.1 and later. If you haven't already, we highly recommend updating your <a
href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 10.0.1.</p>
@@ -954,7 +995,7 @@ Ant</a> 1.8 or later.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that the SDK Tools r10 is
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 10.0.0 and later. After installing SDK Tools r10, we
highly recommend updating your ADT Plugin to 10.0.0.</p>
@@ -985,7 +1026,7 @@ Ant</a> 1.8 or later.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that the SDK Tools r9 is
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 9.0.0 and later. After installing SDK Tools r9, we
highly recommend updating your ADT Plugin to 9.0.0.</p>
@@ -1044,7 +1085,7 @@ resolve the performance issues and it will improve in future releases.</li>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that SDK Tools r8 is
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 8.0.0 and later. After installing SDK Tools r8, we
highly recommend updating your ADT Plugin to 8.0.0.</p>
@@ -1112,7 +1153,7 @@ documentation. </li>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that SDK Tools r7 is
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 0.9.8 and later. After installing SDK Tools r7, we
highly recommend updating your ADT Plugin to 0.9.8.</p>
</dd>
@@ -1146,7 +1187,7 @@ decimal point.</li>
<dl>
<dt>Dependencies:</dt>
<dd>
-<p>If you are developing in Eclipse with ADT, note that SDK Tools r6 is
+<p>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 0.9.7 and later. After installing SDK Tools r6, we
highly recommend updating your ADT Plugin to 0.9.7.</p>
</dd>
@@ -1177,7 +1218,7 @@ provides the equivalent library project support.</p>
<dl>
<dt>Dependencies:</dt>
<dd><ul>
-<li>If you are developing in Eclipse with ADT, note that SDK Tools r5 is
+<li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
designed for use with ADT 0.9.6 and later. After installing SDK Tools r5, we
highly recommend updating your ADT Plugin to 0.9.6.</li>
<li>For Mac OS platforms, OS X 10.4.x (Tiger) is no longer
@@ -1225,7 +1266,7 @@ officially supported. </li>
<div class="toggle-content-toggleme">
<dl>
<dt>Dependencies:</dt>
-<dd><p>SDK Tools r4 is compatible with ADT 0.9.5 and later, but not
+<dd><p>This version of SDK Tools is compatible with ADT 0.9.5 and later, but not
compatible with earlier versions. If you are developing in Eclipse with ADT, you
<strong>must</strong> update your ADT plugin to version 0.9.5 or higher if you
install SDK Tools r4 in your SDK. </p></dd>
@@ -1275,7 +1316,7 @@ skin name specified.</li>
<div class="toggle-content-toggleme">
<dl>
<dt>Dependencies:</dt>
-<dd><p>SDK Tools r3 is compatible with ADT 0.9.4 and later, but not
+<dd><p>This version of SDK Tools is compatible with ADT 0.9.4 and later, but not
compatible with earlier versions. If you are developing in Eclipse with ADT, you
<strong>must</strong> update your ADT plugin to version 0.9.4 or higher if you
install SDK Tools r3 in your SDK.</p>
@@ -1329,4 +1370,3 @@ href="/tools/help/layoutopt.html">layoutopt</a>.</p>
</dl>
</div>
</div>
-
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index 12fc0ae729d4..8d25d96c9116 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -12,6 +12,7 @@ page.title=Support Library Features
<ol>
<li><a href="#v7-appcompat">v7 appcompat library</a></li>
<li><a href="#v7-gridlayout">v7 gridlayout library</a></li>
+ <li><a href="#v7-mediarouter">v7 mediarouter library</a></li>
</ol>
</li>
<li><a href="#v13">v13 Support Library</a></li>
@@ -148,7 +149,6 @@ com.android.support:support-v4:18.0.+
<p>This dependency notation specifies the release version 18.0.0 or higher.</p>
-
<h2 id="v7">v7 Libraries</h2>
<p>There are several libraries designed to be used with Android 2.1 (API level 7) and higher.
@@ -197,9 +197,7 @@ com.android.support:support-v4:18.0.+
com.android.support:appcompat-v7:18.0.+
</pre>
-<p>This dependency notation specifies release version 18.0.0 or higher.</p>
-
-
+<p>This dependency notation specifies the release version 18.0.0 or higher.</p>
<h3 id="v7-gridlayout">v7 gridlayout library</h3>
@@ -220,7 +218,48 @@ com.android.support:appcompat-v7:18.0.+
com.android.support:gridlayout-v7:18.0.+
</pre>
-<p>This dependency notation specifies release version 18.0.0 or higher.</p>
+<p>This dependency notation specifies the release version 18.0.0 or higher.</p>
+
+<h3 id="v7-mediarouter">v7 mediarouter library</h3>
+
+<p>This library provides {@link android.support.v7.media.MediaRouter}, {@link
+android.support.v7.media.MediaRouteProvider}, and related media classes that
+support the <a href="https://developers.google.com/cast/">Google Cast
+developer preview</a>. </p>
+
+<p>In general, the APIs in the v7 mediarouter library provide a means of
+controlling the routing of media channels and streams from the current device to
+external screens, speakers, and other destination devices. The library includes
+APIs for publishing app-specific media route providers, for discovering and
+selecting destination devices, for checking media status, and more. For detailed
+information about the v7 mediarouter library APIs, see the
+{@link android.support.v7.media android.support.v7.media} package in the API
+reference.</p>
+
+<p>The v7 mediarouter library is located in the
+<code>&lt;sdk&gt;/extras/android/support/v7/mediarouter/</code> directory after
+you download the Android Support Library. It's provided as a library project
+with a dependency on the v7 appcompat library, so you'll need to include both
+libraries in your build path when setting up your project. For more information
+on how to set up your project, follow the instructions in <a
+href="{@docRoot}tools/support-library/setup.html#libs-with-res">adding libraries
+with resources</a>. If you are developing in Eclipse/ADT, make sure to include
+both the <code>android-support-v7-mediarouter.jar</code> and
+<code>android-support-v7-appcompat.jar</code> files.</p>
+
+<p>If you are using Android Studio, all you need to do is specify the Gradle build
+script dependency identifier <code>com.android.support:support-v7-mediarouter:&lt;revision&gt;</code>,
+where "18.0.0" is the minimum revision at which the library is available. For example:</p>
+
+<pre>
+com.android.support:support-v7-mediarouter:18.0.0
+</pre>
+
+<p class="caution">The v7 mediarouter library APIs introduced in Support Library
+r18 are subject to change in later revisions of the Support Library. At this
+time, we recommend using the library only in connection with the <a
+href="https://developers.google.com/cast/">Google Cast
+developer preview</a>. </p>
<h2 id="v13">v13 Support Library</h2>
diff --git a/docs/html/tools/support-library/index.jd b/docs/html/tools/support-library/index.jd
index 87ed7f17b13e..06c7a3ff638a 100644
--- a/docs/html/tools/support-library/index.jd
+++ b/docs/html/tools/support-library/index.jd
@@ -22,8 +22,7 @@ page.title=Support Library
</div>
</div>
-<p>The Android Support Library package is a set of code libraries that provide useful and important
- features for Android applications in addition to the framework APIs. These libraries provide
+<p>The Android Support Library package is a set of code libraries that provide
backward-compatible versions of Android framework APIs as well as features that are only available
through the library APIs. Each Support Library is backward-compatible to a specific Android API
level. This design means that your applications can use the libraries' features and still be
@@ -36,7 +35,8 @@ page.title=Support Library
<h2 id="overview">Overview</h2>
<p>Including the Support Libraries in your Android project is considered a best practice for
- application developers. Using the features they provide can help you improve the look of your
+ application developers, depending on the range of platform versions your app is targeting
+ and the APIs that it uses. Using the features the libraries provide can help you improve the look of your
application, increase performance and broaden the reach of your application to more users.
If you use the Android
<a href="{@docRoot}tools/projects/templates.html">code template</a> tools, you will notice that
@@ -136,6 +136,24 @@ page.title=Support Library
</ul>
</dd>
+ <dt>New v7 mediarouter library:</dt>
+ <dd>
+ <p>Added a new mediarouter library that provides support for the <a
+ href="https://developers.google.com/cast/">Google Cast developer preview</a>.
+ The v7 mediarouter library APIs provide a means of controlling the routing of
+ media channels and streams from the current device to external screens,
+ speakers, and other destination devices, with compatibility back to Android 2.1
+ (API level 7). See <a
+ href="{@docRoot}tools/support-library/features.html#v7-mediarouter">V7
+ mediarouter library</a> for more information. </p>
+
+ <p class="caution">The v7 mediarouter library APIs introduced in Support
+ Library r18 are subject to change in later revisions of the Support
+ Library. At this time, we recommend using the library only in connection
+ with the <a href="https://developers.google.com/cast/">Google Cast
+ developer preview</a>.</p>
+ </dd>
+
</dl>
</div>
</div>
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index 37a06f16821b..1646b9138b37 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -172,7 +172,7 @@ Play</a>).</p>
<h2 id="StartActivity">Start an Activity with the Intent</h2>
-<div class="figure" style="width:200px">
+<div class="figure" style="width:200px;margin-top:-10px">
<img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
<p class="img-caption"><strong>Figure 1.</strong> Example of the selection dialog that appears
when more than one app can handle an intent.</p>
@@ -211,11 +211,9 @@ if (isIntentSafe) {
<h2 id="AppChooser">Show an App Chooser</h2>
-<div class="figure" style="width:200px">
+<div class="figure" style="width:200px;margin-top:-10px">
<img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
- <p class="img-caption"><strong>Figure 2.</strong> Example of the chooser dialog that appears
-when you use {@link android.content.Intent#createChooser createChooser()} to ensure
-that the user is always shown a list of apps that respond to your intent.</p>
+ <p class="img-caption"><strong>Figure 2.</strong> A chooser dialog.</p>
</div>
<p>Notice that when you start an activity by passing your {@link android.content.Intent} to {@link
@@ -223,11 +221,13 @@ android.app.Activity#startActivity startActivity()} and there is more than one a
the intent, the user can select which app to use by default (by selecting a checkbox at the bottom
of the dialog; see figure 1). This is nice when performing an action for which the user
generally wants to use the same app every time, such as when opening a web page (users
-likely use just one web browser) or taking a photo (users likely prefer one camera). However, if
-the action to be performed could be handled by multiple apps and the user might
+likely use just one web browser) or taking a photo (users likely prefer one camera).</p>
+
+<p>However, if the action to be performed could be handled by multiple apps and the user might
prefer a different app each time&mdash;such as a "share" action, for which users might have several
-apps through which they might share an item&mdash;you should explicitly show a chooser dialog,
-which forces the user to select which app to use for the action every time (the user cannot select a
+apps through which they might share an item&mdash;you should explicitly show a chooser dialog
+as shown in figure 2. The chooser dialog
+forces the user to select which app to use for the action every time (the user cannot select a
default app for the action).</p>
<p>To show the chooser, create an {@link android.content.Intent} using {@link
@@ -238,8 +238,9 @@ android.app.Activity#startActivity startActivity()}. For example:</p>
Intent intent = new Intent(Intent.ACTION_SEND);
...
-// Always use string resources for UI text. This says something like "Share this photo with"
-String title = getResources().getText(R.string.chooser_title);
+// Always use string resources for UI text.
+// This says something like "Share this photo with"
+String title = (String) getResources().getText(R.string.chooser_title);
// Create and start the chooser
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);
diff --git a/docs/html/training/displaying-bitmaps/cache-bitmap.jd b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
index b1608c3a49bc..25efe1ebbae0 100644
--- a/docs/html/training/displaying-bitmaps/cache-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
@@ -324,14 +324,14 @@ private LruCache&lt;String, Bitmap&gt; mMemoryCache;
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
...
- RetainFragment mRetainFragment =
+ RetainFragment retainFragment =
RetainFragment.findOrCreateRetainFragment(getFragmentManager());
- mMemoryCache = RetainFragment.mRetainedCache;
+ mMemoryCache = retainFragment.mRetainedCache;
if (mMemoryCache == null) {
mMemoryCache = new LruCache&lt;String, Bitmap&gt;(cacheSize) {
... // Initialize cache here as usual
}
- mRetainFragment.mRetainedCache = mMemoryCache;
+ retainFragment.mRetainedCache = mMemoryCache;
}
...
}
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 82fbd1618b4a..72ad018949aa 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -3,14 +3,7 @@ page.trainingcourse=true
page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
@jd:body
-<div id="butterbar-wrapper" >
- <div id="butterbar" >
- <div id="butterbar-message">
-<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/1EHLPGqhbxj2HungHRRN4_0K9TGpc-Izy-u46vBDgS8Q/viewform">
- Take the Android Developer Survey</a>
- </div>
- </div>
-</div>
+
<p>Welcome to Training for Android developers. Here you'll find sets of lessons within classes
that describe how to accomplish a specific task with code samples you can re-use in your app.
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 6cc9d8f14524..e3a7e2bfa84e 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -261,6 +261,13 @@ public class InsetDrawable extends Drawable implements Drawable.Callback
return this;
}
+ /**
+ * Returns the drawable wrapped by this InsetDrawable. May be null.
+ */
+ public Drawable getDrawable() {
+ return mInsetState.mDrawable;
+ }
+
final static class InsetState extends ConstantState {
Drawable mDrawable;
int mChangingConfigurations;
diff --git a/media/java/android/media/FocusRequester.java b/media/java/android/media/FocusRequester.java
new file mode 100644
index 000000000000..020f3e1ee941
--- /dev/null
+++ b/media/java/android/media/FocusRequester.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.media.MediaFocusControl.AudioFocusDeathHandler;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.PrintWriter;
+
+/**
+ * @hide
+ * Class to handle all the information about a user of audio focus. The lifecycle of each
+ * instance is managed by android.media.MediaFocusControl, from its addition to the audio focus
+ * stack to its release.
+ */
+class FocusRequester {
+
+ /**
+ * Used to indicate no audio focus has been gained or lost.
+ */
+ private static final int AUDIOFOCUS_NONE = 0;
+
+ // on purpose not using this classe's name, as it will only be used from MediaFocusControl
+ private static final String TAG = "MediaFocusControl";
+ private static final boolean DEBUG = false;
+
+ private AudioFocusDeathHandler mDeathHandler;
+ private final IAudioFocusDispatcher mFocusDispatcher; // may be null
+ private final IBinder mSourceRef;
+ private final String mClientId;
+ private final String mPackageName;
+ private final int mCallingUid;
+ /**
+ * the audio focus gain request that caused the addition of this object in the focus stack.
+ */
+ private final int mFocusGainRequest;
+ /**
+ * the audio focus loss received my mFocusDispatcher, is MediaFocusControl.AUDIOFOCUS_NONE if
+ * it never lost focus.
+ */
+ private int mFocusLossReceived;
+ /**
+ * the stream type associated with the focus request
+ */
+ private final int mStreamType;
+
+ FocusRequester(int streamType, int focusRequest,
+ IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
+ String pn, int uid) {
+ mStreamType = streamType;
+ mFocusDispatcher = afl;
+ mSourceRef = source;
+ mClientId = id;
+ mDeathHandler = hdlr;
+ mPackageName = pn;
+ mCallingUid = uid;
+ mFocusGainRequest = focusRequest;
+ mFocusLossReceived = AUDIOFOCUS_NONE;
+ }
+
+
+ boolean hasSameClient(String otherClient) {
+ try {
+ return mClientId.compareTo(otherClient) == 0;
+ } catch (NullPointerException e) {
+ return false;
+ }
+ }
+
+ boolean hasSameBinder(IBinder ib) {
+ return (mSourceRef != null) && mSourceRef.equals(ib);
+ }
+
+ boolean hasSamePackage(String pack) {
+ try {
+ return mPackageName.compareTo(pack) == 0;
+ } catch (NullPointerException e) {
+ return false;
+ }
+ }
+
+ boolean hasSameUid(int uid) {
+ return mCallingUid == uid;
+ }
+
+
+ int getGainRequest() {
+ return mFocusGainRequest;
+ }
+
+ int getStreamType() {
+ return mStreamType;
+ }
+
+
+ private static String focusChangeToString(int focus) {
+ switch(focus) {
+ case AUDIOFOCUS_NONE:
+ return "none";
+ case AudioManager.AUDIOFOCUS_GAIN:
+ return "GAIN";
+ case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+ return "GAIN_TRANSIENT";
+ case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+ return "GAIN_TRANSIENT_MAY_DUCK";
+ case AudioManager.AUDIOFOCUS_LOSS:
+ return "LOSS";
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ return "LOSS_TRANSIENT";
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ return "LOSS_TRANSIENT_CAN_DUCK";
+ default:
+ return "[invalid focus change" + focus + "]";
+ }
+ }
+
+ private String focusGainToString() {
+ return focusChangeToString(mFocusGainRequest);
+ }
+
+ private String focusLossToString() {
+ return focusChangeToString(mFocusLossReceived);
+ }
+
+ void dump(PrintWriter pw) {
+ pw.println(" source:" + mSourceRef
+ + " -- pack: " + mPackageName
+ + " -- client: " + mClientId
+ + " -- gain: " + focusGainToString()
+ + " -- loss: " + focusLossToString()
+ + " -- uid: " + mCallingUid
+ + " -- stream: " + mStreamType);
+ }
+
+
+ void release() {
+ try {
+ if (mSourceRef != null && mDeathHandler != null) {
+ mSourceRef.unlinkToDeath(mDeathHandler, 0);
+ mDeathHandler = null;
+ }
+ } catch (java.util.NoSuchElementException e) {
+ Log.e(TAG, "FocusRequester.release() hit ", e);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ release();
+ super.finalize();
+ }
+
+ /**
+ * For a given audio focus gain request, return the audio focus loss type that will result
+ * from it, taking into account any previous focus loss.
+ * @param gainRequest
+ * @return the audio focus loss type that matches the gain request
+ */
+ private int focusLossForGainRequest(int gainRequest) {
+ switch(gainRequest) {
+ case AudioManager.AUDIOFOCUS_GAIN:
+ switch(mFocusLossReceived) {
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ case AudioManager.AUDIOFOCUS_LOSS:
+ case AUDIOFOCUS_NONE:
+ return AudioManager.AUDIOFOCUS_LOSS;
+ }
+ case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+ switch(mFocusLossReceived) {
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ case AUDIOFOCUS_NONE:
+ return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
+ case AudioManager.AUDIOFOCUS_LOSS:
+ return AudioManager.AUDIOFOCUS_LOSS;
+ }
+ case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+ switch(mFocusLossReceived) {
+ case AUDIOFOCUS_NONE:
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
+ case AudioManager.AUDIOFOCUS_LOSS:
+ return AudioManager.AUDIOFOCUS_LOSS;
+ }
+ default:
+ Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest);
+ return AUDIOFOCUS_NONE;
+ }
+ }
+
+ void handleExternalFocusGain(int focusGain) {
+ int focusLoss = focusLossForGainRequest(focusGain);
+ handleFocusLoss(focusLoss);
+ }
+
+ void handleFocusGain(int focusGain) {
+ try {
+ if (mFocusDispatcher != null) {
+ if (DEBUG) {
+ Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to "
+ + mClientId);
+ }
+ mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
+ }
+ mFocusLossReceived = AUDIOFOCUS_NONE;
+ } catch (android.os.RemoteException e) {
+ Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
+ }
+ }
+
+ void handleFocusLoss(int focusLoss) {
+ try {
+ if (focusLoss != mFocusLossReceived) {
+ if (mFocusDispatcher != null) {
+ if (DEBUG) {
+ Log.v(TAG, "dispatching " + focusChangeToString(focusLoss) + " to "
+ + mClientId);
+ }
+ mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
+ }
+ mFocusLossReceived = focusLoss;
+ }
+ } catch (android.os.RemoteException e) {
+ Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
+ }
+ }
+
+}
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index 2b9d809ef3fd..c5b110170c3c 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -66,11 +66,6 @@ public class MediaFocusControl implements OnFinished {
/** Debug volumes */
protected static final boolean DEBUG_VOL = false;
- /**
- * Used to indicate no audio focus has been gained or lost.
- */
- private static final int AUDIOFOCUS_NONE = 0;
-
/** Used to alter media button redirection when the phone is ringing. */
private boolean mIsRinging = false;
@@ -270,11 +265,11 @@ public class MediaFocusControl implements OnFinished {
*/
protected void discardAudioFocusOwner() {
synchronized(mAudioFocusLock) {
- if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
+ if (!mFocusStack.empty()) {
// notify the current focus owner it lost focus after removing it from stack
- final FocusStackEntry exFocusOwner = mFocusStack.pop();
+ final FocusRequester exFocusOwner = mFocusStack.pop();
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
- exFocusOwner.unlinkToDeath();
+ exFocusOwner.release();
// clear RCD
synchronized(mRCStack) {
clearRemoteControlDisplay_syncAfRcs();
@@ -285,128 +280,27 @@ public class MediaFocusControl implements OnFinished {
private void notifyTopOfAudioFocusStack() {
// notify the top of the stack it gained focus
- if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
+ if (!mFocusStack.empty()) {
if (canReassignAudioFocus()) {
mFocusStack.peek().handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
}
}
}
-
- private static class FocusStackEntry {
- int mStreamType = -1;// no stream type
- IAudioFocusDispatcher mFocusDispatcher = null;
- IBinder mSourceRef = null;
- String mClientId;
- /** the audio focus gain request that caused the addition of this entry in the stack */
- int mFocusGainRequest;
- int mFocusLossReceived;
- AudioFocusDeathHandler mHandler;
- String mPackageName;
- int mCallingUid;
-
- static String focusChangeToString(int focus) {
- switch(focus) {
- case AudioManager.AUDIOFOCUS_GAIN:
- return "GAIN";
- case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
- return "GAIN_TRANSIENT";
- case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
- return "GAIN_TRANSIENT_MAY_DUCK";
- case AudioManager.AUDIOFOCUS_LOSS:
- return "LOSS";
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- return "LOSS_TRANSIENT";
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- return "LOSS_TRANSIENT_CAN_DUCK";
- default:
- return "[invalid focus change" + focus + "]";
- }
- }
-
- String focusGainToString() {
- return focusChangeToString(mFocusGainRequest);
- }
-
- String focusLossToString() {
- if (mFocusLossReceived == 0) {
- return "none";
- } else {
- return focusChangeToString(mFocusLossReceived);
- }
- }
-
- FocusStackEntry(int streamType, int focusRequest,
- IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
- String pn, int uid) {
- mStreamType = streamType;
- mFocusDispatcher = afl;
- mSourceRef = source;
- mClientId = id;
- mFocusGainRequest = focusRequest;
- mFocusLossReceived = AUDIOFOCUS_NONE;
- mHandler = hdlr;
- mPackageName = pn;
- mCallingUid = uid;
- }
-
- void unlinkToDeath() {
- try {
- if (mSourceRef != null && mHandler != null) {
- mSourceRef.unlinkToDeath(mHandler, 0);
- mHandler = null;
- }
- } catch (java.util.NoSuchElementException e) {
- Log.e(TAG, "Encountered " + e + " in FocusStackEntry.unlinkToDeath()");
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- unlinkToDeath(); // unlink exception handled inside method
- super.finalize();
- }
-
- /**
- * For a given audio focus gain request, return the audio focus loss type that will result
- * from it.
- * @param gainRequest
- * @return the audio focus loss type that matches the gain request
- */
- int focusLossForGainRequest(int gainRequest) {
- return -1 * gainRequest; // focus loss codes are the inverse of the gain codes
- }
-
- void handleExternalFocusGain(int focusGain) {
- try {
- int focusLoss = focusLossForGainRequest(focusGain);
- mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
- mFocusLossReceived = focusLoss;
- } catch (RemoteException e) {
- Log.e(TAG, " Failure to signal loss of focus: ", e);
- }
- }
-
- void handleFocusGain(int focusGain) {
- try {
- mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
- mFocusLossReceived = AUDIOFOCUS_NONE;
- } catch (RemoteException e) {
- Log.e(TAG, " Failure to signal gain of audio focus due to: ", e);
- }
- }
-
- void handleFocusLoss(int focusLoss) {
- try {
- mFocusDispatcher.dispatchAudioFocusChange(
- focusLoss, mClientId);
- } catch (RemoteException e) {
- Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
- }
+ /**
+ * Focus is requested, propagate the associated loss throughout the stack.
+ * @param focusGain the new focus gain that will later be added at the top of the stack
+ */
+ private void propagateFocusLossFromGain_syncAf(int focusGain) {
+ // going through the audio focus stack to signal new focus, traversing order doesn't
+ // matter as all entries respond to the same external focus gain
+ Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+ while(stackIterator.hasNext()) {
+ stackIterator.next().handleExternalFocusGain(focusGain);
}
}
- private final Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
+ private final Stack<FocusRequester> mFocusStack = new Stack<FocusRequester>();
/**
* Helper function:
@@ -415,16 +309,9 @@ public class MediaFocusControl implements OnFinished {
private void dumpFocusStack(PrintWriter pw) {
pw.println("\nAudio Focus stack entries (last is top of stack):");
synchronized(mAudioFocusLock) {
- Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
+ Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
while(stackIterator.hasNext()) {
- FocusStackEntry fse = stackIterator.next();
- pw.println(" source:" + fse.mSourceRef
- + " -- pack: " + fse.mPackageName
- + " -- client: " + fse.mClientId
- + " -- gain: " + fse.focusGainToString()
- + " -- loss: " + fse.focusLossToString()
- + " -- uid: " + fse.mCallingUid
- + " -- stream: " + fse.mStreamType);
+ stackIterator.next().dump(pw);
}
}
}
@@ -439,11 +326,11 @@ public class MediaFocusControl implements OnFinished {
*/
private void removeFocusStackEntry(String clientToRemove, boolean signal) {
// is the current top of the focus stack abandoning focus? (because of request, not death)
- if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
+ if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientToRemove))
{
//Log.i(TAG, " removeFocusStackEntry() removing top of stack");
- FocusStackEntry fse = mFocusStack.pop();
- fse.unlinkToDeath();
+ FocusRequester fr = mFocusStack.pop();
+ fr.release();
if (signal) {
// notify the new top of the stack it gained focus
notifyTopOfAudioFocusStack();
@@ -457,14 +344,14 @@ public class MediaFocusControl implements OnFinished {
// no need to update focus.
// (using an iterator on the stack so we can safely remove an entry after having
// evaluated it, traversal order doesn't matter here)
- Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
+ Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
while(stackIterator.hasNext()) {
- FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
- if(fse.mClientId.equals(clientToRemove)) {
+ FocusRequester fr = (FocusRequester)stackIterator.next();
+ if(fr.hasSameClient(clientToRemove)) {
Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for "
- + fse.mClientId);
+ + clientToRemove);
stackIterator.remove();
- fse.unlinkToDeath();
+ fr.release();
}
}
}
@@ -478,15 +365,14 @@ public class MediaFocusControl implements OnFinished {
private void removeFocusStackEntryForClient(IBinder cb) {
// is the owner of the audio focus part of the client to remove?
boolean isTopOfStackForClientToRemove = !mFocusStack.isEmpty() &&
- mFocusStack.peek().mSourceRef.equals(cb);
+ mFocusStack.peek().hasSameBinder(cb);
// (using an iterator on the stack so we can safely remove an entry after having
// evaluated it, traversal order doesn't matter here)
- Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
+ Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
while(stackIterator.hasNext()) {
- FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
- if(fse.mSourceRef.equals(cb)) {
- Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for "
- + fse.mClientId);
+ FocusRequester fr = (FocusRequester)stackIterator.next();
+ if(fr.hasSameBinder(cb)) {
+ Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for " + cb);
stackIterator.remove();
// the client just died, no need to unlink to its death
}
@@ -509,7 +395,7 @@ public class MediaFocusControl implements OnFinished {
private boolean canReassignAudioFocus() {
// focus requests are rejected during a phone call or when the phone is ringing
// this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
- if (!mFocusStack.isEmpty() && IN_VOICE_COMM_FOCUS_ID.equals(mFocusStack.peek().mClientId)) {
+ if (!mFocusStack.isEmpty() && mFocusStack.peek().hasSameClient(IN_VOICE_COMM_FOCUS_ID)) {
return false;
}
return true;
@@ -519,7 +405,7 @@ public class MediaFocusControl implements OnFinished {
* Inner class to monitor audio focus client deaths, and remove them from the audio focus
* stack if necessary.
*/
- private class AudioFocusDeathHandler implements IBinder.DeathRecipient {
+ protected class AudioFocusDeathHandler implements IBinder.DeathRecipient {
private IBinder mCb; // To be notified of client's death
AudioFocusDeathHandler(IBinder cb) {
@@ -574,10 +460,10 @@ public class MediaFocusControl implements OnFinished {
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
- if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientId)) {
+ if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientId)) {
// if focus is already owned by this client and the reason for acquiring the focus
// hasn't changed, don't do anything
- if (mFocusStack.peek().mFocusGainRequest == focusChangeHint) {
+ if (mFocusStack.peek().getGainRequest() == focusChangeHint) {
// unlink death handler so it can be gc'ed.
// linkToDeath() creates a JNI global reference preventing collection.
cb.unlinkToDeath(afdh, 0);
@@ -585,20 +471,20 @@ public class MediaFocusControl implements OnFinished {
}
// the reason for the audio focus request has changed: remove the current top of
// stack and respond as if we had a new focus owner
- FocusStackEntry fse = mFocusStack.pop();
- fse.unlinkToDeath();
- }
-
- // notify current top of stack it is losing focus
- if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
- mFocusStack.peek().handleExternalFocusGain(focusChangeHint);
+ FocusRequester fr = mFocusStack.pop();
+ fr.release();
}
// focus requester might already be somewhere below in the stack, remove it
removeFocusStackEntry(clientId, false /* signal */);
+ // propagate the focus change through the stack
+ if (!mFocusStack.empty()) {
+ propagateFocusLossFromGain_syncAf(focusChangeHint);
+ }
+
// push focus requester at the top of the audio focus stack
- mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
+ mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
clientId, afdh, callingPackageName, Binder.getCallingUid()));
// there's a new top of the stack, let the remote control know
@@ -1609,13 +1495,13 @@ public class MediaFocusControl implements OnFinished {
// characteristics:
// - focus gain on STREAM_MUSIC stream
// - non-transient focus gain on a stream other than music
- FocusStackEntry af = null;
+ FocusRequester af = null;
try {
for (int index = mFocusStack.size()-1; index >= 0; index--) {
- FocusStackEntry fse = mFocusStack.elementAt(index);
- if ((fse.mStreamType == AudioManager.STREAM_MUSIC)
- || (fse.mFocusGainRequest == AudioManager.AUDIOFOCUS_GAIN)) {
- af = fse;
+ FocusRequester fr = mFocusStack.elementAt(index);
+ if ((fr.getStreamType() == AudioManager.STREAM_MUSIC)
+ || (fr.getGainRequest() == AudioManager.AUDIOFOCUS_GAIN)) {
+ af = fr;
break;
}
}
@@ -1629,16 +1515,13 @@ public class MediaFocusControl implements OnFinished {
}
// if the audio focus and RC owners belong to different packages, there is a mismatch, clear
- if ((mRCStack.peek().mCallingPackageName != null)
- && (af.mPackageName != null)
- && !(mRCStack.peek().mCallingPackageName.compareTo(
- af.mPackageName) == 0)) {
+ if (!af.hasSamePackage(mRCStack.peek().mCallingPackageName)) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
// if the audio focus didn't originate from the same Uid as the one in which the remote
// control information will be retrieved, clear
- if (mRCStack.peek().mCallingUid != af.mCallingUid) {
+ if (!af.hasSameUid(mRCStack.peek().mCallingUid)) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
diff --git a/packages/DocumentsUI/res/layout/dialog_create_dir.xml b/packages/DocumentsUI/res/layout/dialog_create_dir.xml
new file mode 100644
index 000000000000..54e26b40dfdf
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/dialog_create_dir.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="?android:attr/listPreferredItemPaddingEnd">
+
+ <EditText
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BackendFragment.java b/packages/DocumentsUI/src/com/android/documentsui/BackendFragment.java
index 2980e2338a33..fc13487a35ff 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BackendFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BackendFragment.java
@@ -21,9 +21,15 @@ import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.RootColumns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -39,11 +45,11 @@ import com.google.android.collect.Lists;
import java.util.List;
/**
- * Display all known storage backends.
+ * Display all known storage roots.
*/
public class BackendFragment extends Fragment {
- // TODO: handle multiple accounts from single backend
+ // TODO: cluster backends by type
private GridView mGridView;
private BackendAdapter mAdapter;
@@ -57,19 +63,69 @@ public class BackendFragment extends Fragment {
ft.commitAllowingStateLoss();
}
+ public static class Root {
+ public int rootType;
+ public Uri uri;
+ public Drawable icon;
+ public String title;
+ public String summary;
+
+ public static Root fromCursor(Context context, ProviderInfo info, Cursor cursor) {
+ final Root root = new Root();
+
+ root.rootType = cursor.getInt(cursor.getColumnIndex(RootColumns.ROOT_TYPE));
+ root.uri = DocumentsContract.buildDocumentUri(
+ info.authority, cursor.getString(cursor.getColumnIndex(RootColumns.GUID)));
+
+ final PackageManager pm = context.getPackageManager();
+ final int icon = cursor.getInt(cursor.getColumnIndex(RootColumns.ICON));
+ if (icon != 0) {
+ try {
+ root.icon = pm.getResourcesForApplication(info.applicationInfo)
+ .getDrawable(icon);
+ } catch (NotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ root.icon = info.loadIcon(pm);
+ }
+
+ root.title = cursor.getString(cursor.getColumnIndex(RootColumns.TITLE));
+ if (root.title == null) {
+ root.title = info.loadLabel(pm).toString();
+ }
+
+ root.summary = cursor.getString(cursor.getColumnIndex(RootColumns.SUMMARY));
+
+ return root;
+ }
+ }
+
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final Context context = inflater.getContext();
- // Gather known storage providers
+ // Gather roots from known storage providers
final List<ProviderInfo> providers = context.getPackageManager()
.queryContentProviders(null, -1, PackageManager.GET_META_DATA);
- final List<ProviderInfo> backends = Lists.newArrayList();
+ final List<Root> roots = Lists.newArrayList();
for (ProviderInfo info : providers) {
if (info.metaData != null
&& info.metaData.containsKey(DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
- backends.add(info);
+ // TODO: populate roots on background thread, and cache results
+ final Uri uri = DocumentsContract.buildRootsUri(info.authority);
+ final Cursor cursor = context.getContentResolver()
+ .query(uri, null, null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ roots.add(Root.fromCursor(context, info, cursor));
+ }
+ } finally {
+ cursor.close();
+ }
}
}
@@ -78,7 +134,7 @@ public class BackendFragment extends Fragment {
mGridView = (GridView) view.findViewById(R.id.grid);
mGridView.setOnItemClickListener(mItemListener);
- mAdapter = new BackendAdapter(context, backends);
+ mAdapter = new BackendAdapter(context, roots);
mGridView.setAdapter(mAdapter);
mGridView.setNumColumns(GridView.AUTO_FIT);
@@ -88,13 +144,13 @@ public class BackendFragment extends Fragment {
private OnItemClickListener mItemListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final ProviderInfo info = mAdapter.getItem(position);
- ((DocumentsActivity) getActivity()).onBackendPicked(info);
+ final Root root = mAdapter.getItem(position);
+ ((DocumentsActivity) getActivity()).onRootPicked(root);
}
};
- public static class BackendAdapter extends ArrayAdapter<ProviderInfo> {
- public BackendAdapter(Context context, List<ProviderInfo> list) {
+ public static class BackendAdapter extends ArrayAdapter<Root> {
+ public BackendAdapter(Context context, List<Root> list) {
super(context, android.R.layout.simple_list_item_1, list);
}
@@ -109,9 +165,9 @@ public class BackendFragment extends Fragment {
final TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
final PackageManager pm = parent.getContext().getPackageManager();
- final ProviderInfo info = getItem(position);
- icon.setImageDrawable(info.loadIcon(pm));
- text1.setText(info.loadLabel(pm));
+ final Root root = getItem(position);
+ icon.setImageDrawable(root.icon);
+ text1.setText(root.title);
return convertView;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index c45d2b4990ff..e61cea6d7e37 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -21,15 +21,20 @@ import static com.android.documentsui.DirectoryFragment.getCursorString;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.FragmentManager.BackStackEntry;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.content.ClipData;
import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
@@ -44,8 +49,11 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.EditText;
import android.widget.TextView;
+import com.android.documentsui.BackendFragment.Root;
+
import java.util.Arrays;
import java.util.List;
@@ -160,7 +168,7 @@ public class DocumentsActivity extends Activity {
getFragmentManager().popBackStack();
updateActionBar();
} else if (id == R.id.menu_create_dir) {
- // TODO: show dialog to create directory
+ CreateDirectoryFragment.show(getFragmentManager());
}
return super.onOptionsItemSelected(item);
}
@@ -232,11 +240,8 @@ public class DocumentsActivity extends Activity {
invalidateOptionsMenu();
}
- public void onBackendPicked(ProviderInfo info) {
- final Uri uri = DocumentsContract.buildDocumentUri(
- info.authority, DocumentsContract.ROOT_GUID);
- final CharSequence displayName = info.loadLabel(getPackageManager());
- DirectoryFragment.show(getFragmentManager(), uri, displayName.toString());
+ public void onRootPicked(Root root) {
+ DirectoryFragment.show(getFragmentManager(), root.uri, root.title);
}
public void onDocumentPicked(Document doc) {
@@ -263,8 +268,12 @@ public class DocumentsActivity extends Activity {
}
public void onSaveRequested(String mimeType, String displayName) {
- // TODO: create file, confirming before overwriting
- final Uri uri = null;
+ final ContentValues values = new ContentValues();
+ values.put(DocumentColumns.MIME_TYPE, mimeType);
+ values.put(DocumentColumns.DISPLAY_NAME, displayName);
+
+ // TODO: handle errors from remote side
+ final Uri uri = getContentResolver().insert(mCurrentDir, values);
onFinished(uri);
}
@@ -283,11 +292,10 @@ public class DocumentsActivity extends Activity {
intent.setClipData(clipData);
}
- intent.addFlags(
- Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
- if (mAction == ACTION_CREATE) {
- intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- }
+ // TODO: omit WRITE and PERSIST for GET_CONTENT
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
setResult(Activity.RESULT_OK, intent);
finish();
@@ -318,6 +326,24 @@ public class DocumentsActivity extends Activity {
doc.displayName = getCursorString(cursor, DocumentColumns.DISPLAY_NAME);
return doc;
}
+
+ public static Document fromUri(ContentResolver resolver, Uri uri) {
+ final Document doc = new Document();
+ doc.uri = uri;
+
+ final Cursor cursor = resolver.query(uri, null, null, null, null);
+ try {
+ if (!cursor.moveToFirst()) {
+ throw new IllegalArgumentException("Missing details for " + uri);
+ }
+ doc.mimeType = getCursorString(cursor, DocumentColumns.MIME_TYPE);
+ doc.displayName = getCursorString(cursor, DocumentColumns.DISPLAY_NAME);
+ } finally {
+ cursor.close();
+ }
+
+ return doc;
+ }
}
public static boolean mimeMatches(String filter, String[] tests) {
@@ -359,4 +385,50 @@ public class DocumentsActivity extends Activity {
}
}
}
+
+ private static final String TAG_CREATE_DIRECTORY = "create_directory";
+
+ public static class CreateDirectoryFragment extends DialogFragment {
+ public static void show(FragmentManager fm) {
+ final CreateDirectoryFragment dialog = new CreateDirectoryFragment();
+ dialog.show(fm, TAG_CREATE_DIRECTORY);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getActivity();
+ final ContentResolver resolver = context.getContentResolver();
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+
+ final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
+ final EditText text1 = (EditText)view.findViewById(android.R.id.text1);
+
+ builder.setTitle(R.string.menu_create_dir);
+ builder.setView(view);
+
+ builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final String displayName = text1.getText().toString();
+
+ final ContentValues values = new ContentValues();
+ values.put(DocumentColumns.MIME_TYPE, DocumentsContract.MIME_TYPE_DIRECTORY);
+ values.put(DocumentColumns.DISPLAY_NAME, displayName);
+
+ // TODO: handle errors from remote side
+ final DocumentsActivity activity = (DocumentsActivity) getActivity();
+ final Uri uri = resolver.insert(activity.mCurrentDir, values);
+
+ // Navigate into newly created child
+ final Document doc = Document.fromUri(resolver, uri);
+ activity.onDocumentPicked(doc);
+ }
+ });
+ builder.setNegativeButton(android.R.string.cancel, null);
+
+ return builder.create();
+ }
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index 19a1d2a45baa..a2a4f7cb285f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -82,7 +82,7 @@ public class SaveFragment extends Fragment {
@Override
public void onClick(View v) {
final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
- final String displayName = getArguments().getString(EXTRA_DISPLAY_NAME);
+ final String displayName = mDisplayName.getText().toString();
((DocumentsActivity) getActivity()).onSaveRequested(mimeType, displayName);
}
};
diff --git a/packages/ExternalStorageProvider/res/values/strings.xml b/packages/ExternalStorageProvider/res/values/strings.xml
index 4374cfc6e7b4..0eaf500a03dd 100644
--- a/packages/ExternalStorageProvider/res/values/strings.xml
+++ b/packages/ExternalStorageProvider/res/values/strings.xml
@@ -16,4 +16,5 @@
<resources>
<string name="app_label">External Storage</string>
+ <string name="root_internal_storage">Internal storage</string>
</resources>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index f75e3bd9b3e8..bf5811b682e8 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -28,14 +28,17 @@ import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.DocumentColumns;
+import android.provider.DocumentsContract.RootColumns;
+import android.util.Log;
import android.webkit.MimeTypeMap;
-import com.android.internal.annotations.GuardedBy;
-import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
import java.io.File;
import java.io.FileNotFoundException;
-import java.util.ArrayList;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
public class ExternalStorageProvider extends ContentProvider {
private static final String TAG = "ExternalStorage";
@@ -44,33 +47,65 @@ public class ExternalStorageProvider extends ContentProvider {
// TODO: support searching
// TODO: support multiple storage devices
- // TODO: persist GUIDs across launches
private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- private static final int URI_DOCS_ID = 1;
- private static final int URI_DOCS_ID_CONTENTS = 2;
- private static final int URI_SEARCH = 3;
+ private static final int URI_ROOTS = 1;
+ private static final int URI_DOCS_ID = 2;
+ private static final int URI_DOCS_ID_CONTENTS = 3;
+ private static final int URI_DOCS_ID_SEARCH = 4;
- static {
- sMatcher.addURI(AUTHORITY, "docs/#", URI_DOCS_ID);
- sMatcher.addURI(AUTHORITY, "docs/#/contents", URI_DOCS_ID_CONTENTS);
- sMatcher.addURI(AUTHORITY, "search", URI_SEARCH);
+ private HashMap<String, Root> mRoots = Maps.newHashMap();
+
+ private static class Root {
+ public int rootType;
+ public String name;
+ public int icon = 0;
+ public String title = null;
+ public String summary = null;
+ public File path;
}
- @GuardedBy("mFiles")
- private ArrayList<File> mFiles = Lists.newArrayList();
+ static {
+ sMatcher.addURI(AUTHORITY, "roots", URI_ROOTS);
+ sMatcher.addURI(AUTHORITY, "docs/*", URI_DOCS_ID);
+ sMatcher.addURI(AUTHORITY, "docs/*/contents", URI_DOCS_ID_CONTENTS);
+ sMatcher.addURI(AUTHORITY, "docs/*/search", URI_DOCS_ID_SEARCH);
+ }
@Override
public boolean onCreate() {
- mFiles.clear();
- mFiles.add(Environment.getExternalStorageDirectory());
+ mRoots.clear();
+
+ final Root root = new Root();
+ root.rootType = DocumentsContract.ROOT_TYPE_DEVICE_ADVANCED;
+ root.name = "internal";
+ root.title = getContext().getString(R.string.root_internal_storage);
+ root.path = Environment.getExternalStorageDirectory();
+ mRoots.put(root.name, root);
+
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
+ final int match = sMatcher.match(uri);
+ if (match == URI_ROOTS) {
+ // TODO: support custom projections
+ projection = new String[] {
+ RootColumns.ROOT_TYPE, RootColumns.GUID, RootColumns.ICON, RootColumns.TITLE,
+ RootColumns.SUMMARY, RootColumns.AVAILABLE_BYTES };
+
+ final MatrixCursor cursor = new MatrixCursor(projection);
+ for (Root root : mRoots.values()) {
+ final String guid = fileToGuid(root.path);
+ cursor.addRow(new Object[] {
+ root.rootType, guid, root.icon, root.title, root.summary,
+ root.path.getFreeSpace() });
+ }
+ return cursor;
+ }
// TODO: support custom projections
projection = new String[] {
@@ -79,21 +114,37 @@ public class ExternalStorageProvider extends ContentProvider {
DocumentColumns.MIME_TYPE, DocumentColumns.LAST_MODIFIED, DocumentColumns.FLAGS };
final MatrixCursor cursor = new MatrixCursor(projection);
- switch (sMatcher.match(uri)) {
+ switch (match) {
case URI_DOCS_ID: {
- final int id = Integer.parseInt(uri.getPathSegments().get(1));
- synchronized (mFiles) {
- includeFileLocked(cursor, id);
- }
+ final String guid = uri.getPathSegments().get(1);
+ includeFile(cursor, guid);
break;
}
case URI_DOCS_ID_CONTENTS: {
- final int parentId = Integer.parseInt(uri.getPathSegments().get(1));
- synchronized (mFiles) {
- final File parent = mFiles.get(parentId);
- for (File file : parent.listFiles()) {
- final int id = findOrCreateFileLocked(file);
- includeFileLocked(cursor, id);
+ final String guid = uri.getPathSegments().get(1);
+ final File parent = guidToFile(guid);
+ for (File file : parent.listFiles()) {
+ includeFile(cursor, fileToGuid(file));
+ }
+ break;
+ }
+ case URI_DOCS_ID_SEARCH: {
+ final String guid = uri.getPathSegments().get(1);
+ final File parent = guidToFile(guid);
+ final String query = uri.getQueryParameter(DocumentsContract.PARAM_QUERY).toLowerCase();
+
+ final LinkedList<File> pending = new LinkedList<File>();
+ pending.add(parent);
+ while (!pending.isEmpty() && cursor.getCount() < 20) {
+ final File file = pending.removeFirst();
+ if (file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ pending.add(child);
+ }
+ } else {
+ if (file.getName().toLowerCase().contains(query)) {
+ includeFile(cursor, fileToGuid(file));
+ }
}
}
break;
@@ -107,43 +158,61 @@ public class ExternalStorageProvider extends ContentProvider {
return cursor;
}
- private int findOrCreateFileLocked(File file) {
- int id = mFiles.indexOf(file);
- if (id == -1) {
- id = mFiles.size();
- mFiles.add(file);
+ private String fileToGuid(File file) {
+ final String path = file.getAbsolutePath();
+ for (Root root : mRoots.values()) {
+ final String rootPath = root.path.getAbsolutePath();
+ if (path.startsWith(rootPath)) {
+ return root.name + ':' + Uri.encode(path.substring(rootPath.length()));
+ }
}
- return id;
+
+ throw new IllegalArgumentException("Failed to find root for " + file);
+ }
+
+ private File guidToFile(String guid) {
+ final int split = guid.indexOf(':');
+ final String name = guid.substring(0, split);
+ final Root root = mRoots.get(name);
+ if (root != null) {
+ final String path = Uri.decode(guid.substring(split + 1));
+ return new File(root.path, path);
+ }
+
+ throw new IllegalArgumentException("Failed to find root for " + guid);
}
- private void includeFileLocked(MatrixCursor cursor, int id) {
- final File file = mFiles.get(id);
+ private void includeFile(MatrixCursor cursor, String guid) {
int flags = 0;
+ final File file = guidToFile(guid);
+ if (file.isDirectory()) {
+ flags |= DocumentsContract.FLAG_SUPPORTS_SEARCH;
+ }
if (file.isDirectory() && file.canWrite()) {
flags |= DocumentsContract.FLAG_SUPPORTS_CREATE;
}
if (file.canWrite()) {
flags |= DocumentsContract.FLAG_SUPPORTS_RENAME;
+ flags |= DocumentsContract.FLAG_SUPPORTS_DELETE;
}
- final String mimeType = getTypeLocked(id);
+ final String mimeType = getTypeForFile(file);
if (mimeType.startsWith("image/")) {
flags |= DocumentsContract.FLAG_SUPPORTS_THUMBNAIL;
}
+ final long id = guid.hashCode();
cursor.addRow(new Object[] {
- id, file.getName(), file.length(), id, mimeType, file.lastModified(), flags });
+ id, file.getName(), file.length(), guid, mimeType, file.lastModified(), flags });
}
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case URI_DOCS_ID: {
- final int id = Integer.parseInt(uri.getPathSegments().get(1));
- synchronized (mFiles) {
- return getTypeLocked(id);
- }
+ final String guid = uri.getPathSegments().get(1);
+ return getTypeForFile(guidToFile(guid));
}
default: {
throw new UnsupportedOperationException("Unsupported Uri " + uri);
@@ -151,16 +220,18 @@ public class ExternalStorageProvider extends ContentProvider {
}
}
- private String getTypeLocked(int id) {
- final File file = mFiles.get(id);
-
+ private String getTypeForFile(File file) {
if (file.isDirectory()) {
return DocumentsContract.MIME_TYPE_DIRECTORY;
+ } else {
+ return getTypeForName(file.getName());
}
+ }
- final int lastDot = file.getName().lastIndexOf('.');
+ private String getTypeForName(String name) {
+ final int lastDot = name.lastIndexOf('.');
if (lastDot >= 0) {
- final String extension = file.getName().substring(lastDot + 1);
+ final String extension = name.substring(lastDot + 1);
final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mime != null) {
return mime;
@@ -174,12 +245,11 @@ public class ExternalStorageProvider extends ContentProvider {
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
switch (sMatcher.match(uri)) {
case URI_DOCS_ID: {
- final int id = Integer.parseInt(uri.getPathSegments().get(1));
- synchronized (mFiles) {
- final File file = mFiles.get(id);
- // TODO: turn into thumbnail
- return ParcelFileDescriptor.open(file, ContentResolver.modeToMode(uri, mode));
- }
+ final String guid = uri.getPathSegments().get(1);
+ final File file = guidToFile(guid);
+
+ // TODO: offer as thumbnail
+ return ParcelFileDescriptor.open(file, ContentResolver.modeToMode(uri, mode));
}
default: {
throw new UnsupportedOperationException("Unsupported Uri " + uri);
@@ -189,16 +259,84 @@ public class ExternalStorageProvider extends ContentProvider {
@Override
public Uri insert(Uri uri, ContentValues values) {
- throw new UnsupportedOperationException();
+ switch (sMatcher.match(uri)) {
+ case URI_DOCS_ID: {
+ final String guid = uri.getPathSegments().get(1);
+ final File parent = guidToFile(guid);
+
+ final String mimeType = values.getAsString(DocumentColumns.MIME_TYPE);
+ final String name = validateDisplayName(
+ values.getAsString(DocumentColumns.DISPLAY_NAME), mimeType);
+
+ final File file = new File(parent, name);
+ if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(mimeType)) {
+ if (!file.mkdir()) {
+ return null;
+ }
+
+ } else {
+ try {
+ if (!file.createNewFile()) {
+ return null;
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to create file", e);
+ return null;
+ }
+ }
+
+ return DocumentsContract.buildDocumentUri(AUTHORITY, fileToGuid(file));
+ }
+ default: {
+ throw new UnsupportedOperationException("Unsupported Uri " + uri);
+ }
+ }
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException();
+ switch (sMatcher.match(uri)) {
+ case URI_DOCS_ID: {
+ final String guid = uri.getPathSegments().get(1);
+ final File file = guidToFile(guid);
+ final File newFile = new File(
+ file.getParentFile(), values.getAsString(DocumentColumns.DISPLAY_NAME));
+ return file.renameTo(newFile) ? 1 : 0;
+ }
+ default: {
+ throw new UnsupportedOperationException("Unsupported Uri " + uri);
+ }
+ }
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException();
+ switch (sMatcher.match(uri)) {
+ case URI_DOCS_ID: {
+ final String guid = uri.getPathSegments().get(1);
+ final File file = guidToFile(guid);
+ return file.delete() ? 1 : 0;
+ }
+ default: {
+ throw new UnsupportedOperationException("Unsupported Uri " + uri);
+ }
+ }
+ }
+
+ private String validateDisplayName(String displayName, String mimeType) {
+ if (DocumentsContract.MIME_TYPE_DIRECTORY.equals(mimeType)) {
+ return displayName;
+ } else {
+ // Try appending meaningful extension if needed
+ if (!mimeType.equals(getTypeForName(displayName))) {
+ final String extension = MimeTypeMap.getSingleton()
+ .getExtensionFromMimeType(mimeType);
+ if (extension != null) {
+ displayName += "." + extension;
+ }
+ }
+
+ return displayName;
+ }
}
}
diff --git a/preloaded-classes b/preloaded-classes
index 45d27eeddbb4..064ca3a12d75 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1671,7 +1671,6 @@ com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
com.android.org.bouncycastle.jce.provider.CertBlacklist
com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities
-com.android.org.bouncycastle.jce.provider.JDKKeyStore
com.android.org.bouncycastle.jce.provider.PKIXCRLUtil
com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
com.android.org.bouncycastle.jce.provider.PKIXNameConstraintValidator
@@ -2026,7 +2025,6 @@ java.net.Proxy$Type
java.net.ProxySelector
java.net.ProxySelectorImpl
java.net.ResponseCache
-java.net.ResponseSource
java.net.Socket
java.net.SocketAddress
java.net.SocketImpl
@@ -2463,7 +2461,6 @@ libcore.io.StructLinger
libcore.io.StructPasswd
libcore.io.StructPollfd
libcore.io.StructStat
-libcore.io.StructStatFs
libcore.io.StructTimeval
libcore.io.StructUcred
libcore.io.StructUtsname
@@ -2471,26 +2468,8 @@ libcore.math.MathUtils
libcore.net.MimeUtils
libcore.net.RawSocket
libcore.net.UriCodec
-libcore.net.http.AbstractHttpInputStream
-libcore.net.http.FixedLengthInputStream
-libcore.net.http.HeaderParser$CacheControlHandler
-libcore.net.http.HttpConnection
-libcore.net.http.HttpConnection$Address
-libcore.net.http.HttpConnectionPool
libcore.net.http.HttpDate
libcore.net.http.HttpDate$1
-libcore.net.http.HttpEngine
-libcore.net.http.HttpEngine$1
-libcore.net.http.HttpHandler
-libcore.net.http.HttpURLConnectionImpl
-libcore.net.http.HttpURLConnectionImpl$Retry
-libcore.net.http.HttpsHandler
-libcore.net.http.RawHeaders
-libcore.net.http.RawHeaders$1
-libcore.net.http.RequestHeaders
-libcore.net.http.RequestHeaders$1
-libcore.net.http.ResponseHeaders
-libcore.net.http.ResponseHeaders$1
libcore.net.url.FileHandler
libcore.net.url.FileURLConnection
libcore.net.url.JarHandler
@@ -2516,9 +2495,6 @@ org.apache.harmony.dalvik.NativeTestTarget
org.apache.harmony.dalvik.ddmc.Chunk
org.apache.harmony.dalvik.ddmc.ChunkHandler
org.apache.harmony.dalvik.ddmc.DdmServer
-org.apache.harmony.lang.annotation.AnnotationFactory
-org.apache.harmony.lang.annotation.AnnotationMember
-org.apache.harmony.lang.annotation.AnnotationMember$DefaultValues
org.apache.harmony.luni.internal.util.TimezoneGetter
org.apache.harmony.security.asn1.ASN1Any
org.apache.harmony.security.asn1.ASN1BitString
@@ -2566,8 +2542,6 @@ org.apache.harmony.security.fortress.Services
org.apache.harmony.security.provider.cert.DRLCertFactory
org.apache.harmony.security.provider.cert.X509CertImpl
org.apache.harmony.security.provider.crypto.CryptoProvider
-org.apache.harmony.security.provider.crypto.RandomBitsSupplier
-org.apache.harmony.security.provider.crypto.SHA1_Data
org.apache.harmony.security.utils.AlgNameMapper
org.apache.harmony.security.utils.ObjectIdentifier
org.apache.harmony.security.x501.AttributeTypeAndValue
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 39c0bddf2dcb..dc8fab6135b2 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -521,6 +521,14 @@ class AlarmManagerService extends IAlarmManager.Stub {
throw new IllegalArgumentException("Invalid alarm type " + type);
}
+ if (triggerAtTime < 0) {
+ final long who = Binder.getCallingUid();
+ final long what = Binder.getCallingPid();
+ Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + who
+ + " pid=" + what);
+ triggerAtTime = 0;
+ }
+
final long nowElapsed = SystemClock.elapsedRealtime();
final long triggerElapsed = convertToElapsed(triggerAtTime, type);
final long maxElapsed;
@@ -567,7 +575,12 @@ class AlarmManagerService extends IAlarmManager.Stub {
}
if (DEBUG_VALIDATE) {
- if (doValidate && validateConsistencyLocked()) {
+ if (doValidate && !validateConsistencyLocked()) {
+ Slog.v(TAG, "Tipping-point operation: type=" + type + " when=" + when
+ + " when(hex)=" + Long.toHexString(when)
+ + " whenElapsed=" + whenElapsed + " maxWhen=" + maxWhen
+ + " interval=" + interval + " op=" + operation
+ + " standalone=" + isStandalone);
rebatchAllAlarmsLocked(false);
reschedule = true;
}
@@ -586,8 +599,9 @@ class AlarmManagerService extends IAlarmManager.Stub {
final int NZ = mAlarmBatches.size();
for (int iz = 0; iz < NZ; iz++) {
Batch bz = mAlarmBatches.get(iz);
- Slog.v(TAG, "Batch " + iz + ": " + bz);
+ pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz);
dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC);
+ pw.flush();
Slog.v(TAG, bs.toString());
bs.reset();
}
@@ -626,15 +640,17 @@ class AlarmManagerService extends IAlarmManager.Stub {
private void rescheduleKernelAlarmsLocked() {
// Schedule the next upcoming wakeup alarm. If there is a deliverable batch
// prior to that which contains no wakeups, we schedule that as well.
- final Batch firstWakeup = findFirstWakeupBatchLocked();
- final Batch firstBatch = mAlarmBatches.get(0);
- if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
- mNextWakeup = firstWakeup.start;
- setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
- }
- if (firstBatch != firstWakeup && mNextNonWakeup != firstBatch.start) {
- mNextNonWakeup = firstBatch.start;
- setLocked(ELAPSED_REALTIME, firstBatch.start);
+ if (mAlarmBatches.size() > 0) {
+ final Batch firstWakeup = findFirstWakeupBatchLocked();
+ final Batch firstBatch = mAlarmBatches.get(0);
+ if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
+ mNextWakeup = firstWakeup.start;
+ setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
+ }
+ if (firstBatch != firstWakeup && mNextNonWakeup != firstBatch.start) {
+ mNextNonWakeup = firstBatch.start;
+ setLocked(ELAPSED_REALTIME, firstBatch.start);
+ }
}
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 35656f8367c2..8200a690e0db 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -919,7 +919,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
return true;
}
- Slog.w(TAG, "--- IPC called from background users. Ignore. \n" + getStackTrace());
+ Slog.w(TAG, "--- IPC called from background users. Ignore. \n"
+ + InputMethodUtils.getStackTrace());
return false;
}
@@ -2473,7 +2474,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
HashMap<String, InputMethodInfo> map, boolean resetDefaultEnabledIme) {
if (DEBUG) {
Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
- + " \n ------ \n" + getStackTrace());
+ + " \n ------ \n" + InputMethodUtils.getStackTrace());
}
list.clear();
map.clear();
@@ -3468,22 +3469,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- // ----------------------------------------------------------------------
- // Utilities for debug
- private static String getStackTrace() {
- final StringBuilder sb = new StringBuilder();
- try {
- throw new RuntimeException();
- } catch (RuntimeException e) {
- final StackTraceElement[] frames = e.getStackTrace();
- // Start at 1 because the first frame is here and we don't care about it
- for (int j = 1; j < frames.length; ++j) {
- sb.append(frames[j].toString() + "\n");
- }
- }
- return sb.toString();
- }
-
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3d0fe0f33087..c7b2213f94a7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -11531,7 +11531,11 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
pw.print(voltile); pw.println(" kB volatile");
}
- pw.print(" TUNING: ");
+ pw.print(" Tuning: ");
+ pw.print(ActivityManager.staticGetMemoryClass());
+ pw.print(" (large ");
+ pw.print(ActivityManager.staticGetLargeMemoryClass());
+ pw.print("), oom ");
pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
pw.print(" kB");
if (ActivityManager.isLowRamDeviceStatic()) {
@@ -11546,6 +11550,10 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
pw.println(voltile);
pw.print("tuning,");
+ pw.print(ActivityManager.staticGetMemoryClass());
+ pw.print(',');
+ pw.print(ActivityManager.staticGetLargeMemoryClass());
+ pw.print(',');
pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
if (ActivityManager.isLowRamDeviceStatic()) {
pw.print(",low-ram");
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 2149190b10be..3797b49cc32d 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -934,6 +934,9 @@ bool AaptGroupEntry::getMncName(const char* name,
if (out) {
out->mnc = atoi(val);
+ if (out->mnc == 0) {
+ out->mnc = ACONFIGURATION_MNC_ZERO;
+ }
}
return true;