Merge "Camera2: remove CameraDevice#getProperties" into klp-dev
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 97cb815..61e071b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4679,8 +4679,6 @@
assumeLayout();
}
- boolean changed = false;
-
if (mMovement != null) {
/* This code also provides auto-scrolling when a cursor is moved using a
* CursorController (insertion point or selection limits).
@@ -4703,10 +4701,10 @@
}
if (curs >= 0) {
- changed = bringPointIntoView(curs);
+ bringPointIntoView(curs);
}
} else {
- changed = bringTextIntoView();
+ bringTextIntoView();
}
// This has to be checked here since:
@@ -4727,7 +4725,7 @@
getViewTreeObserver().removeOnPreDrawListener(this);
mPreDrawRegistered = false;
- return !changed;
+ return true;
}
@Override
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index 009b729..fbdf318 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -33,6 +33,7 @@
import android.media.SubtitleTrack.RenderingWidget;
import android.media.WebVttRenderer;
import android.net.Uri;
+import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
@@ -879,4 +880,10 @@
invalidate();
}
+
+ /** @hide */
+ @Override
+ public Looper getSubtitleLooper() {
+ return Looper.getMainLooper();
+ }
}
diff --git a/docs/html/guide/topics/ui/controls/checkbox.jd b/docs/html/guide/topics/ui/controls/checkbox.jd
index 99140b5..2a64e38 100644
--- a/docs/html/guide/topics/ui/controls/checkbox.jd
+++ b/docs/html/guide/topics/ui/controls/checkbox.jd
@@ -94,7 +94,7 @@
android.view.View} that was clicked)</li>
</ul>
-<p class="note"><strong>Tip:</strong> If you need to change the radio button state
+<p class="note"><strong>Tip:</strong> If you need to change the checkbox state
yourself (such as when loading a saved {@link android.preference.CheckBoxPreference}),
use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
android.widget.CompoundButton#toggle()} method.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index 09767bf..d934c4b 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -593,7 +593,7 @@
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Send the negative button event back to the host activity
- mListener.onDialogPositiveClick(NoticeDialogFragment.this);
+ mListener.onDialogNegativeClick(NoticeDialogFragment.this);
}
});
return builder.create();
diff --git a/docs/html/training/articles/security-ssl.jd b/docs/html/training/articles/security-ssl.jd
index d3f68e2..f52865a 100644
--- a/docs/html/training/articles/security-ssl.jd
+++ b/docs/html/training/articles/security-ssl.jd
@@ -250,7 +250,7 @@
This is similar to an unknown certificate authority, so you can use the
same approach from the previous section.</p>
-<p>You can create yout own {@link javax.net.ssl.TrustManager},
+<p>You can create your own {@link javax.net.ssl.TrustManager},
this time trusting the server certificate directly. This has all of the
downsides discussed earlier of tying your app directly to a certificate, but can be done
securely. However, you should be careful to make sure your self-signed certificate has a
diff --git a/docs/html/training/articles/smp.jd b/docs/html/training/articles/smp.jd
index 0f667d7..7240eec 100644
--- a/docs/html/training/articles/smp.jd
+++ b/docs/html/training/articles/smp.jd
@@ -1057,7 +1057,7 @@
fix them. Before we do that, we need to discuss the use of a basic language
feature.</p>
-<h4 id="volatile">C/C+++ and "volatile"</h4>
+<h4 id="volatile">C/C++ and "volatile"</h4>
<p>When writing single-threaded code, declaring a variable “volatile” can be
very useful. The compiler will not omit or reorder accesses to volatile
diff --git a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
index 11a05e1..fb5096d 100644
--- a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
+++ b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
@@ -49,7 +49,8 @@
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
-boolean isConnected = activeNetwork.isConnectedOrConnecting();</pre>
+boolean isConnected = activeNetwork != null &&
+ activeNetwork.isConnectedOrConnecting();</pre>
<h2 id="DetermineType">Determine the Type of your Internet Connection</h2>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index a3c9dac..77ac235 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -576,29 +576,6 @@
</li>
</ul>
</li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/id-auth/index.html"
- description=
- "How to remember the user by account, authenticate the user, acquire user permission
- for the user's online data, and create custom accounts on the device."
- >Remembering Users</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/id-auth/identify.html">
- Remembering Your User
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/id-auth/authenticate.html">
- Authenticating to OAuth2 Services
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/id-auth/custom_auth.html">
- Creating a Custom Account Type
- </a>
- </li>
- </ul>
- </li>
<li class="nav-section">
<div class="nav-section-header">
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index deba2cc..def9aa7 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1772,6 +1772,9 @@
mSelectedSubtitleTrackIndex = -1;
}
setOnSubtitleDataListener(null);
+ if (track == null) {
+ return;
+ }
for (int i = 0; i < mInbandSubtitleTracks.length; i++) {
if (mInbandSubtitleTracks[i] == track) {
Log.v(TAG, "Selecting subtitle track " + i);
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 5127479..06af5de 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -374,7 +374,7 @@
* Called when a sound has completed loading.
*
* @param soundPool SoundPool object from the load() method
- * @param soundPool the sample ID of the sound loaded.
+ * @param sampleId the sample ID of the sound loaded.
* @param status the status of the load operation (0 = success)
*/
public void onLoadComplete(SoundPool soundPool, int sampleId, int status);
diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java
index 8090561..13205bc 100644
--- a/media/java/android/media/SubtitleController.java
+++ b/media/java/android/media/SubtitleController.java
@@ -21,6 +21,9 @@
import android.content.Context;
import android.media.SubtitleTrack.RenderingWidget;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.view.accessibility.CaptioningManager;
/**
@@ -37,6 +40,34 @@
private SubtitleTrack mSelectedTrack;
private boolean mShowing;
private CaptioningManager mCaptioningManager;
+ private Handler mHandler;
+
+ private static final int WHAT_SHOW = 1;
+ private static final int WHAT_HIDE = 2;
+ private static final int WHAT_SELECT_TRACK = 3;
+ private static final int WHAT_SELECT_DEFAULT_TRACK = 4;
+
+ private final Handler.Callback mCallback = new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case WHAT_SHOW:
+ doShow();
+ return true;
+ case WHAT_HIDE:
+ doHide();
+ return true;
+ case WHAT_SELECT_TRACK:
+ doSelectTrack((SubtitleTrack)msg.obj);
+ return true;
+ case WHAT_SELECT_DEFAULT_TRACK:
+ doSelectDefaultTrack();
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
new CaptioningManager.CaptioningChangeListener() {
@@ -112,7 +143,7 @@
* in-band data from the {@link MediaPlayer}. However, this does
* not change the subtitle visibility.
*
- * Must be called from the UI thread.
+ * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
*
* @param track The subtitle track to select. This must be one of the
* tracks in {@link #getTracks}.
@@ -122,9 +153,15 @@
if (track != null && !mTracks.contains(track)) {
return false;
}
+
+ processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
+ return true;
+ }
+
+ private void doSelectTrack(SubtitleTrack track) {
mTrackIsExplicit = true;
if (mSelectedTrack == track) {
- return true;
+ return;
}
if (mSelectedTrack != null) {
@@ -145,7 +182,6 @@
if (mListener != null) {
mListener.onSubtitleTrackSelected(track);
}
- return true;
}
/**
@@ -170,8 +206,6 @@
*
* The default values for these flags are DEFAULT=no, AUTOSELECT=yes
* and FORCED=no.
- *
- * Must be called from the UI thread.
*/
public SubtitleTrack getDefaultTrack() {
SubtitleTrack bestTrack = null;
@@ -226,8 +260,12 @@
private boolean mTrackIsExplicit = false;
private boolean mVisibilityIsExplicit = false;
- /** @hide - called from UI thread */
+ /** @hide - should be called from anchor thread */
public void selectDefaultTrack() {
+ processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
+ }
+
+ private void doSelectDefaultTrack() {
if (mTrackIsExplicit) {
// If track selection is explicit, but visibility
// is not, it falls back to the captioning setting
@@ -259,8 +297,9 @@
}
}
- /** @hide - called from UI thread */
+ /** @hide - must be called from anchor thread */
public void reset() {
+ checkAnchorLooper();
hide();
selectTrack(null);
mTracks.clear();
@@ -301,9 +340,13 @@
/**
* Show the selected (or default) subtitle track.
*
- * Must be called from the UI thread.
+ * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
*/
public void show() {
+ processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
+ }
+
+ private void doShow() {
mShowing = true;
mVisibilityIsExplicit = true;
if (mSelectedTrack != null) {
@@ -314,9 +357,13 @@
/**
* Hide the selected (or default) subtitle track.
*
- * Must be called from the UI thread.
+ * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
*/
public void hide() {
+ processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
+ }
+
+ private void doHide() {
mVisibilityIsExplicit = true;
if (mSelectedTrack != null) {
mSelectedTrack.hide();
@@ -384,25 +431,53 @@
* @hide
*/
public void setSubtitleWidget(RenderingWidget subtitleWidget);
+
+ /**
+ * Anchors provide the looper on which all track visibility changes
+ * (track.show/hide, setSubtitleWidget) will take place.
+ * @hide
+ */
+ public Looper getSubtitleLooper();
}
private Anchor mAnchor;
- /** @hide - called from UI thread */
+ /**
+ * @hide - called from anchor's looper (if any, both when unsetting and
+ * setting)
+ */
public void setAnchor(Anchor anchor) {
if (mAnchor == anchor) {
return;
}
if (mAnchor != null) {
+ checkAnchorLooper();
mAnchor.setSubtitleWidget(null);
}
mAnchor = anchor;
+ mHandler = null;
if (mAnchor != null) {
+ mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
+ checkAnchorLooper();
mAnchor.setSubtitleWidget(getRenderingWidget());
}
}
+ private void checkAnchorLooper() {
+ assert mHandler != null : "Should have a looper already";
+ assert Looper.myLooper() == mHandler.getLooper() : "Must be called from the anchor's looper";
+ }
+
+ private void processOnAnchor(Message m) {
+ assert mHandler != null : "Should have a looper already";
+ if (Looper.myLooper() == mHandler.getLooper()) {
+ mHandler.dispatchMessage(m);
+ } else {
+ mHandler.sendMessage(m);
+ }
+ }
+
public interface Listener {
/**
* Called when a subtitle track has been selected.