Merge "Import translations. DO NOT MERGE" into jb-mr1-aah-dev
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 85972c3..84cde52 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -36,6 +36,8 @@
 import android.inputmethodservice.ExtractEditText;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.DynamicLayout;
@@ -187,6 +189,8 @@
 
     private TextView mTextView;
 
+    private final UserDictionaryListener mUserDictionaryListener = new UserDictionaryListener();
+
     Editor(TextView textView) {
         mTextView = textView;
     }
@@ -2602,6 +2606,11 @@
                 Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
                 intent.putExtra("word", originalText);
                 intent.putExtra("locale", mTextView.getTextServicesLocale().toString());
+                // Put a listener to replace the original text with a word which the user
+                // modified in a user dictionary dialog.
+                mUserDictionaryListener.waitForUserDictionaryAdded(
+                        mTextView, originalText, spanStart, spanEnd);
+                intent.putExtra("listener", new Messenger(mUserDictionaryListener));
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mTextView.getContext().startActivity(intent);
                 // There is no way to know if the word was indeed added. Re-check.
@@ -3820,4 +3829,61 @@
         boolean mContentChanged;
         int mChangedStart, mChangedEnd, mChangedDelta;
     }
+
+    /**
+     * @hide
+     */
+    public static class UserDictionaryListener extends Handler {
+        public TextView mTextView;
+        public String mOriginalWord;
+        public int mWordStart;
+        public int mWordEnd;
+
+        public void waitForUserDictionaryAdded(
+                TextView tv, String originalWord, int spanStart, int spanEnd) {
+            mTextView = tv;
+            mOriginalWord = originalWord;
+            mWordStart = spanStart;
+            mWordEnd = spanEnd;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final int code = msg.what;
+            if (code == 0) { /* CODE_WORD_ADDED */
+                if (!(msg.obj instanceof Bundle)) {
+                    Log.w(TAG, "Illegal message. Abort handling onUserDictionaryAdded.");
+                    return;
+                }
+                final Bundle bundle = (Bundle)msg.obj;
+                final String originalWord = bundle.getString("originalWord");
+                final String addedWord = bundle.getString("word");
+                onUserDictionaryAdded(originalWord, addedWord);
+            }
+        }
+
+        private void onUserDictionaryAdded(String originalWord, String addedWord) {
+            if (TextUtils.isEmpty(mOriginalWord) || TextUtils.isEmpty(addedWord)) {
+                return;
+            }
+            if (mWordStart < 0 || mWordEnd >= mTextView.length()) {
+                return;
+            }
+            if (!mOriginalWord.equals(originalWord)) {
+                return;
+            }
+            if (originalWord.equals(addedWord)) {
+                return;
+            }
+            final Editable editable = (Editable) mTextView.getText();
+            final String currentWord = editable.toString().substring(mWordStart, mWordEnd);
+            if (!currentWord.equals(originalWord)) {
+                return;
+            }
+            mTextView.replaceText_internal(mWordStart, mWordEnd, addedWord);
+            // Move cursor at the end of the replaced word
+            final int newCursorPosition = mWordStart + addedWord.length();
+            mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
+        }
+    }
 }
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
index 9f0dfe5..554866d 100755
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -14,8 +14,8 @@
        <ol>
        <li><a href="#QueryDetails">Querying Items Available for Purchase</a><li>
        <li><a href="#Purchase">Purchasing an Item</a></li>
-       <li><a href="QueryPurchases">Querying Purchased Items</a></li>
-       <li><a href="Consume">Consuming a Purchase</a><li>
+       <li><a href="#QueryPurchases">Querying Purchased Items</a></li>
+       <li><a href="#Consume">Consuming a Purchase</a><li>
        </ol>
     </li>
   </ol>
diff --git a/docs/html/training/load-data-background/handle-results.jd b/docs/html/training/load-data-background/handle-results.jd
new file mode 100644
index 0000000..ce0024f
--- /dev/null
+++ b/docs/html/training/load-data-background/handle-results.jd
@@ -0,0 +1,137 @@
+page.title=Handling the Results
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+  <div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li>
+    <a href="#HandleResults">Handle Query Results</a>
+  </li>
+  <li>
+    <a href="#HandleReset">Delete Old Cursor References</a></li>
+</ol>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+  </div>
+</div>
+
+<p>
+    As shown in the previous lesson, you should begin loading your data with a
+    {@link android.support.v4.content.CursorLoader} in your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader
+    onCreateLoader()}. The loader then provides the query results to your
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} in your
+    implementation of {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished
+    LoaderCallbacks.onLoadFinished()}. One of the incoming arguments to this method is a
+    {@link android.database.Cursor} containing the query results. You can use this object to
+    update your data display or do further processing.
+</p>
+<p>
+    Besides
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} and
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
+    you also have to implement
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}.
+    This method is invoked when {@link android.support.v4.content.CursorLoader} detects
+    that data associated with the {@link android.database.Cursor} has changed. When the
+    data changes, the framework also re-runs the current query.
+</p>
+<h2 id="HandleResults">Handle Query Results</h2>
+<p>
+    To display {@link android.database.Cursor} data returned by
+    {@link android.support.v4.content.CursorLoader}, use a
+    {@link android.view.View} class that implements {@link android.widget.AdapterView} and
+    provide the view with an adapter that implements
+    {@link android.support.v4.widget.CursorAdapter}. The system then automatically moves data from
+    the {@link android.database.Cursor} to the view.
+</p>
+<p>
+    You can set up the linkage between the view and adapter before you have any data to display,
+    and then move a {@link android.database.Cursor} into the adapter in the
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+    method. As soon as you move the {@link android.database.Cursor} into the adapter, the
+    system automatically updates the view. This also happens if you change the contents of the
+    {@link android.database.Cursor}.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+public String[] mFromColumns = {
+    DataProviderContract.IMAGE_PICTURENAME_COLUMN
+};
+public int[] mToFields = {
+    R.id.PictureName
+};
+// Gets a handle to a List View
+ListView mListView = (ListView) findViewById(R.id.dataList);
+/*
+ * Defines a SimpleCursorAdapter for the ListView
+ *
+ */
+SimpleCursorAdapter mAdapter =
+    new SimpleCursorAdapter(
+            this,                // Current context
+            R.layout.list_item,  // Layout for a single row
+            null,                // No Cursor yet
+            mFromColumns,        // Cursor columns to use
+            mToFields,           // Layout fields to use
+            0                    // No flags
+    );
+// Sets the adapter for the view
+mListView.setAdapter(mAdapter);
+...
+/*
+ * Defines the callback that {@link android.support.v4.content.CursorLoader} calls
+ * when it's finished its query
+ */
+&#64;Override
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
+    ...
+    /*
+     * Moves the query results into the adapter, causing the
+     * ListView fronting this adapter to re-display
+     */
+    mAdapter.changeCursor(cursor);
+}
+</pre>
+<h2 id="HandleReset">Delete Old Cursor References</h2>
+<p>
+    The {@link android.support.v4.content.CursorLoader} is reset whenever its
+    {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated
+    with the {@link android.database.Cursor} has changed. Before re-running the query,
+    the framework calls your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In
+    this callback, you should delete all references to the current {@link android.database.Cursor}
+    in order to prevent memory leaks. Once
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
+    finishes, {@link android.support.v4.content.CursorLoader} re-runs its query.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+/*
+ * Invoked when the CursorLoader is being reset. For example, this is
+ * called if the data in the provider changes and the Cursor becomes stale.
+ */
+&#64;Override
+public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+    
+    /*
+     * Clears out the adapter's reference to the Cursor.
+     * This prevents memory leaks.
+     */
+    mAdapter.changeCursor(null);
+}
+</pre>
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
new file mode 100644
index 0000000..dc9d84a
--- /dev/null
+++ b/docs/html/training/load-data-background/index.jd
@@ -0,0 +1,77 @@
+page.title=Loading Data in the Background
+trainingnavtop=true
+startpage=true
+
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<ul>
+    <li>
+        Android 1.6 or later
+    </li>
+</ul>
+
+<!-- related docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/loaders.html">Loaders</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/topics/data/data-storage.html#db">Using Databases</a>
+    </li>
+    <li>
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">Content Provider Basics</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    Querying a {@link android.content.ContentProvider} for data you want to display takes time.
+    If you run the query directly from an {@link android.app.Activity}, it may get blocked and
+    cause the system to issue an "Application Not Responding" message. Even if it doesn't, users
+    will see an annoying delay in the UI. To avoid these problems, you should initiate a query on a
+    separate thread, wait for it to finish, and then display the results.
+</p>
+<p>
+    You can do this in a straightforward way by using an object that runs a query asynchronously in
+    the background and reconnects to your {@link android.app.Activity} when it's finished. This
+    object is a {@link android.support.v4.content.CursorLoader}. Besides doing the initial
+    background query, a {@link android.support.v4.content.CursorLoader} automatically re-runs the
+    query when data associated with the query changes.
+</p>
+<p>
+    This class describes how to use a {@link android.support.v4.content.CursorLoader} to run a
+    background query. Examples in this class use the {@link android.support.v4 v4 support library}
+    versions of classes, which support platforms starting with Android 1.6.
+</p>
+<h2>Lessons</h2>
+<dl>
+    <dt>
+        <strong><a href="setup-loader.html">Running a Query with a CursorLoader</a></strong>
+    </dt>
+    <dd>
+        Learn how to run a query in the background, using a
+        {@link android.support.v4.content.CursorLoader}.
+    </dd>
+    <dt>
+        <strong>
+        <a href="handle-results.html">Handling the Results</a>
+        </strong>
+    </dt>
+    <dd>
+        Learn how to handle the {@link android.database.Cursor} returned from the query, and how
+        to remove references to the current {@link android.database.Cursor} when the loader
+        framework re-sets the {@link android.support.v4.content.CursorLoader}.
+    </dd>
+</dl>
diff --git a/docs/html/training/load-data-background/setup-loader.jd b/docs/html/training/load-data-background/setup-loader.jd
new file mode 100644
index 0000000..17fe7b0
--- /dev/null
+++ b/docs/html/training/load-data-background/setup-loader.jd
@@ -0,0 +1,142 @@
+page.title=Running a Query with a CursorLoader
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+  <div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#Extend">Define an Activity That Uses CursorLoader</a>
+    </li>
+    <li>
+        <a href="#InitializeLoader">Initialize the Query</a>
+    </li>
+    <li>
+        <a href="#DefineLaunch">Start the Query</a>
+    </li>
+</ol>
+
+<h2>Try it out</h2>
+<div class="download-box">
+    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
+    <p class="filename">ThreadSample.zip</p>
+</div>
+
+  </div>
+</div>
+<p>
+    A {@link android.support.v4.content.CursorLoader} runs an asynchronous query in the background
+    against a {@link android.content.ContentProvider}, and returns the results to the
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} from which it
+    was called. This allows the {@link android.app.Activity} or
+    {@link android.support.v4.app.FragmentActivity} to continue to interact with the user while the
+    query is ongoing.
+</p>
+<h2 id="Extend">Define an Activity That Uses CursorLoader</h2>
+<p>
+    To use a {@link android.support.v4.content.CursorLoader} with an
+    {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity}, use the
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks LoaderCallbacks&lt;Cursor&gt;}
+    interface. A {@link android.support.v4.content.CursorLoader} invokes callbacks defined
+    in this interface to communicate with the class; this lesson and the next one
+    describe each callback in detail.
+</p>
+<p>
+    For example, this is how you should define a {@link android.support.v4.app.FragmentActivity}
+    that uses the support library version of {@link android.support.v4.content.CursorLoader}. By
+    extending {@link android.support.v4.app.FragmentActivity}, you get support for
+    {@link android.support.v4.content.CursorLoader} as well as
+    {@link android.support.v4.app.Fragment}:
+</p>
+<pre>
+public class PhotoThumbnailFragment extends FragmentActivity implements
+        LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
+...
+}
+</pre>
+<h2 id="InitializeLoader">Initialize the Query</h2>
+<p>
+    To initialize a query, call
+    {@link android.support.v4.app.LoaderManager#initLoader LoaderManager.initLoader()}. This
+    initializes the background framework. You can do this after the user has entered data that's
+    used in the query, or, if you don't need any user data, you can do it in
+    {@link android.support.v4.app.FragmentActivity#onCreate onCreate()} or
+    {@link android.support.v4.app.Fragment#onCreateView onCreateView()}. For example:
+</p>
+<pre>
+    // Identifies a particular Loader being used in this component
+    private static final int URL_LOADER = 0;
+    ...
+    /* When the system is ready for the Fragment to appear, this displays
+     * the Fragment's View
+     */
+    public View onCreateView(
+            LayoutInflater inflater,
+            ViewGroup viewGroup,
+            Bundle bundle) {
+        ...
+        /*
+         * Initializes the CursorLoader. The URL_LOADER value is eventually passed
+         * to onCreateLoader().
+         */
+        getLoaderManager().initLoader(URL_LOADER, null, this);
+        ...
+    }
+</pre>
+<p class="note">
+    <strong>Note:</strong> The method {@link android.support.v4.app.Fragment#getLoaderManager
+    getLoaderManager()} is only available in the {@link android.support.v4.app.Fragment} class. To
+    get a {@link android.support.v4.app.LoaderManager} in a
+    {@link android.support.v4.app.FragmentActivity}, call
+    {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager
+    getSupportLoaderManager()}.
+</p>
+<h2 id="DefineLaunch">Start the Query</h2>
+<p>
+    As soon as the background framework is initialized, it calls your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
+    To start the query, return a {@link android.support.v4.content.CursorLoader} from this method.
+    You can instantiate an empty {@link android.support.v4.content.CursorLoader} and then use its
+    methods to define your query, or you can instantiate the object and define the query at the
+    same time:
+</p>
+<pre>
+/*
+* Callback that's invoked when the system has initialized the Loader and
+* is ready to start the query. This usually happens when initLoader() is
+* called. The loaderID argument contains the ID value passed to the
+* initLoader() call.
+*/
+&#64;Override
+public Loader&lt;Cursor&gt; onCreateLoader(int loaderID, Bundle bundle)
+{
+    /*
+     * Takes action based on the ID of the Loader that's being created
+     */
+    switch (loaderID) {
+        case URL_LOADER:
+            // Returns a new CursorLoader
+            return new CursorLoader(
+                        getActivity(),   // Parent activity context
+                        mDataUrl,        // Table to query
+                        mProjection,     // Projection to return
+                        null,            // No selection clause
+                        null,            // No selection arguments
+                        null             // Default sort order
+        );
+        default:
+            // An invalid id was passed in
+            return null;
+    }
+}
+</pre>
+<p>
+    Once the background framework has the object, it starts the query in the background. When the
+    query is done, the background framework calls
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
+    which is described in the next lesson.
+</p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 0f6994e..77909b8 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -1028,8 +1028,6 @@
           </li>
         </ul>
       </li>
-      
-      
       <li class="nav-section">
         <div class="nav-section-header">
           <a href="<?cs var:toroot ?>training/monetization/index.html"
@@ -1050,7 +1048,6 @@
   <!-- End best Publishing -->
 
 </ul><!-- nav -->
-
 <script type="text/javascript">
 <!--
     buildToggleLists();
diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java
index dd0b5b3..c9e0da5 100644
--- a/services/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/java/com/android/server/dreams/DreamManagerService.java
@@ -385,6 +385,9 @@
     }
 
     private static ComponentName[] componentsFromString(String names) {
+        if (names == null) {
+            return null;
+        }
         String[] namesArray = names.split(",");
         ComponentName[] componentNames = new ComponentName[namesArray.length];
         for (int i = 0; i < namesArray.length; i++) {