Merge "New null (disconnected) RSSI for wifi and mobile." into jb-dev
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9a8d802..2eea171 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1852,14 +1852,17 @@
int[] rowIds = {R.id.inbox_text0, R.id.inbox_text1, R.id.inbox_text2, R.id.inbox_text3,
R.id.inbox_text4};
+ // Make sure all rows are gone in case we reuse a view.
+ for (int rowId : rowIds) {
+ contentView.setViewVisibility(rowId, View.GONE);
+ }
+
int i=0;
while (i < mTexts.size() && i < rowIds.length) {
CharSequence str = mTexts.get(i);
if (str != null && !str.equals("")) {
contentView.setViewVisibility(rowIds[i], View.VISIBLE);
contentView.setTextViewText(rowIds[i], str);
- } else {
- contentView.setViewVisibility(rowIds[i], View.GONE);
}
i++;
}
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index c59ed18..a643c8a 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -261,6 +261,8 @@
@Override
protected void onClick() {
+ if (mDialog != null && mDialog.isShowing()) return;
+
showDialog(null);
}
diff --git a/core/java/android/webkit/WebCoreThreadWatchdog.java b/core/java/android/webkit/WebCoreThreadWatchdog.java
index 655db31..a22e6e8 100644
--- a/core/java/android/webkit/WebCoreThreadWatchdog.java
+++ b/core/java/android/webkit/WebCoreThreadWatchdog.java
@@ -26,6 +26,10 @@
import android.os.Process;
import android.webkit.WebViewCore.EventHub;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
// A Runnable that will monitor if the WebCore thread is still
// processing messages by pinging it every so often. It is safe
// to call the public methods of this class from any thread.
@@ -51,25 +55,31 @@
// After the first timeout, use a shorter period before re-prompting the user.
private static final int SUBSEQUENT_TIMEOUT_PERIOD = 15 * 1000;
- private Context mContext;
private Handler mWebCoreThreadHandler;
private Handler mHandler;
private boolean mPaused;
+ private Set<WebViewClassic> mWebViews;
+
private static WebCoreThreadWatchdog sInstance;
- public synchronized static WebCoreThreadWatchdog start(Context context,
- Handler webCoreThreadHandler) {
+ public synchronized static WebCoreThreadWatchdog start(Handler webCoreThreadHandler) {
if (sInstance == null) {
- sInstance = new WebCoreThreadWatchdog(context, webCoreThreadHandler);
+ sInstance = new WebCoreThreadWatchdog(webCoreThreadHandler);
new Thread(sInstance, "WebCoreThreadWatchdog").start();
}
return sInstance;
}
- public synchronized static void updateContext(Context context) {
+ public synchronized static void registerWebView(WebViewClassic w) {
if (sInstance != null) {
- sInstance.setContext(context);
+ sInstance.addWebView(w);
+ }
+ }
+
+ public synchronized static void unregisterWebView(WebViewClassic w) {
+ if (sInstance != null) {
+ sInstance.removeWebView(w);
}
}
@@ -85,12 +95,18 @@
}
}
- private void setContext(Context context) {
- mContext = context;
+ private void addWebView(WebViewClassic w) {
+ if (mWebViews == null) {
+ mWebViews = new HashSet<WebViewClassic>();
+ }
+ mWebViews.add(w);
}
- private WebCoreThreadWatchdog(Context context, Handler webCoreThreadHandler) {
- mContext = context;
+ private void removeWebView(WebViewClassic w) {
+ mWebViews.remove(w);
+ }
+
+ private WebCoreThreadWatchdog(Handler webCoreThreadHandler) {
mWebCoreThreadHandler = webCoreThreadHandler;
}
@@ -147,39 +163,41 @@
break;
case TIMED_OUT:
- if ((mContext == null) || !(mContext instanceof Activity)) return;
- new AlertDialog.Builder(mContext)
- .setMessage(com.android.internal.R.string.webpage_unresponsive)
- .setPositiveButton(com.android.internal.R.string.force_close,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // User chose to force close.
- Process.killProcess(Process.myPid());
+ boolean postedDialog = false;
+ synchronized (WebCoreThreadWatchdog.class) {
+ Iterator<WebViewClassic> it = mWebViews.iterator();
+ // Check each WebView we are aware of and find one that is capable of
+ // showing the user a prompt dialog.
+ while (it.hasNext()) {
+ WebView activeView = it.next().getWebView();
+
+ if (activeView.getWindowToken() != null &&
+ activeView.getViewRootImpl() != null) {
+ postedDialog = activeView.post(new PageNotRespondingRunnable(
+ activeView.getContext(), this));
+
+ if (postedDialog) {
+ // We placed the message into the UI thread for an attached
+ // WebView so we've made our best attempt to display the
+ // "page not responding" dialog to the user. Although the
+ // message is in the queue, there is no guarantee when/if
+ // the runnable will execute. In the case that the runnable
+ // never executes, the user will need to terminate the
+ // process manually.
+ break;
}
- })
- .setNegativeButton(com.android.internal.R.string.wait,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // The user chose to wait. The last HEARTBEAT message
- // will still be in the WebCore thread's queue, so all
- // we need to do is post another TIMED_OUT so that the
- // user will get prompted again if the WebCore thread
- // doesn't sort itself out.
- sendMessageDelayed(obtainMessage(TIMED_OUT),
- SUBSEQUENT_TIMEOUT_PERIOD);
- }
- })
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- sendMessageDelayed(obtainMessage(TIMED_OUT),
- SUBSEQUENT_TIMEOUT_PERIOD);
- }
- })
- .setIcon(android.R.drawable.ic_dialog_alert)
- .show();
+ }
+ }
+
+ if (!postedDialog) {
+ // There's no active webview we can use to show the dialog, so
+ // wait again. If we never get a usable view, the user will
+ // never get the chance to terminate the process, and will
+ // need to do it manually.
+ sendMessageDelayed(obtainMessage(TIMED_OUT),
+ SUBSEQUENT_TIMEOUT_PERIOD);
+ }
+ }
break;
}
}
@@ -205,4 +223,55 @@
Looper.loop();
}
+
+ private class PageNotRespondingRunnable implements Runnable {
+ Context mContext;
+ private Handler mWatchdogHandler;
+
+ public PageNotRespondingRunnable(Context context, Handler watchdogHandler) {
+ mContext = context;
+ mWatchdogHandler = watchdogHandler;
+ }
+
+ @Override
+ public void run() {
+ // This must run on the UI thread as it is displaying an AlertDialog.
+ assert Looper.getMainLooper().getThread() == Thread.currentThread();
+ new AlertDialog.Builder(mContext)
+ .setMessage(com.android.internal.R.string.webpage_unresponsive)
+ .setPositiveButton(com.android.internal.R.string.force_close,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // User chose to force close.
+ Process.killProcess(Process.myPid());
+ }
+ })
+ .setNegativeButton(com.android.internal.R.string.wait,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // The user chose to wait. The last HEARTBEAT message
+ // will still be in the WebCore thread's queue, so all
+ // we need to do is post another TIMED_OUT so that the
+ // user will get prompted again if the WebCore thread
+ // doesn't sort itself out.
+ mWatchdogHandler.sendMessageDelayed(
+ mWatchdogHandler.obtainMessage(TIMED_OUT),
+ SUBSEQUENT_TIMEOUT_PERIOD);
+ }
+ })
+ .setOnCancelListener(
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mWatchdogHandler.sendMessageDelayed(
+ mWatchdogHandler.obtainMessage(TIMED_OUT),
+ SUBSEQUENT_TIMEOUT_PERIOD);
+ }
+ })
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show();
+ }
+ }
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 7786564..5b266ca 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -431,14 +431,18 @@
boolean isCharacterDelete = false;
int textLength = text.length();
int originalLength = original.length();
- if (textLength > originalLength) {
- isCharacterAdd = (textLength == originalLength + 1)
- && TextUtils.regionMatches(text, 0, original, 0,
- originalLength);
- } else if (originalLength > textLength) {
- isCharacterDelete = (textLength == originalLength - 1)
- && TextUtils.regionMatches(text, 0, original, 0,
- textLength);
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ if (selectionStart == selectionEnd) {
+ if (textLength > originalLength) {
+ isCharacterAdd = (textLength == originalLength + 1)
+ && TextUtils.regionMatches(text, 0, original, 0,
+ originalLength);
+ } else if (originalLength > textLength) {
+ isCharacterDelete = (textLength == originalLength - 1)
+ && TextUtils.regionMatches(text, 0, original, 0,
+ textLength);
+ }
}
if (isCharacterAdd) {
sendCharacter(text.charAt(textLength - 1));
@@ -3365,11 +3369,6 @@
nativeSetPauseDrawing(mNativeClass, false);
}
}
- // Ensure that the watchdog has a currently valid Context to be able to display
- // a prompt dialog. For example, if the Activity was finished whilst the WebCore
- // thread was blocked and the Activity is started again, we may reuse the blocked
- // thread, but we'll have a new Activity.
- WebCoreThreadWatchdog.updateContext(mContext);
// We get a call to onResume for new WebViews (i.e. mIsPaused will be false). We need
// to ensure that the Watchdog thread is running for the new WebView, so call
// it outside the if block above.
@@ -7486,6 +7485,7 @@
int cursorPosition = start + text.length();
replaceTextfieldText(start, end, text,
cursorPosition, cursorPosition);
+ selectionDone();
break;
}
@@ -7512,7 +7512,9 @@
}
case CLEAR_CARET_HANDLE:
- selectionDone();
+ if (mIsCaretSelection) {
+ selectionDone();
+ }
break;
case KEY_PRESS:
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 76cd1c9..af7914e 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -178,8 +178,10 @@
// Start the singleton watchdog which will monitor the WebCore thread
// to verify it's still processing messages.
- WebCoreThreadWatchdog.start(context, sWebCoreHandler);
+ WebCoreThreadWatchdog.start(sWebCoreHandler);
}
+ // Make sure the Watchdog is aware of this new WebView.
+ WebCoreThreadWatchdog.registerWebView(w);
}
// Create an EventHub to handle messages before and after the thread is
// ready.
@@ -1979,6 +1981,7 @@
mEventHub.sendMessageAtFrontOfQueue(
Message.obtain(null, EventHub.DESTROY));
mEventHub.blockMessages();
+ WebCoreThreadWatchdog.unregisterWebView(mWebViewClassic);
}
}
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
index 9eeb311..c5a86d8 100644
--- a/core/java/android/webkit/WebViewInputDispatcher.java
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -822,21 +822,31 @@
}
private void enqueueEventLocked(DispatchEvent d) {
- if (!shouldSkipWebKit(d.mEventType)) {
+ if (!shouldSkipWebKit(d)) {
enqueueWebKitEventLocked(d);
} else {
enqueueUiEventLocked(d);
}
}
- private boolean shouldSkipWebKit(int eventType) {
- switch (eventType) {
+ private boolean shouldSkipWebKit(DispatchEvent d) {
+ switch (d.mEventType) {
case EVENT_TYPE_CLICK:
case EVENT_TYPE_HOVER:
case EVENT_TYPE_SCROLL:
case EVENT_TYPE_HIT_TEST:
return false;
case EVENT_TYPE_TOUCH:
+ // TODO: This should be cleaned up. We now have WebViewInputDispatcher
+ // and WebViewClassic both checking for slop and doing their own
+ // thing - they should be consolidated. And by consolidated, I mean
+ // WebViewClassic's version should just be deleted.
+ // The reason this is done is because webpages seem to expect
+ // that they only get an ontouchmove if the slop has been exceeded.
+ if (mIsTapCandidate && d.mEvent != null
+ && d.mEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ return true;
+ }
return !mPostSendTouchEventsToWebKit
|| mPostDoNotSendTouchEventsToWebKitUntilNextGesture;
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 821a251b..987c0ac 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1623,7 +1623,7 @@
if (line.startsWith("File")) {
int equals = line.indexOf('=');
if (equals > 0) {
- cachePlaylistEntry(line, playListDirectory);
+ cachePlaylistEntry(line.substring(equals + 1), playListDirectory);
}
}
line = reader.readLine();