summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/animation/AnimatorInflater.java2
-rw-r--r--core/java/android/animation/ArgbEvaluator.java (renamed from core/java/android/animation/RGBEvaluator.java)2
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java2
-rw-r--r--core/java/android/content/pm/ComponentInfo.java7
-rw-r--r--core/java/android/database/sqlite/SQLiteStatement.java12
-rw-r--r--core/java/android/os/Environment.java2
-rw-r--r--core/java/android/provider/ContactsContract.java12
-rw-r--r--core/java/android/view/ViewRoot.java5
-rw-r--r--core/java/android/webkit/WebTextView.java16
-rw-r--r--core/java/android/webkit/WebView.java177
-rw-r--r--core/java/android/webkit/WebViewCore.java2
-rw-r--r--core/java/android/webkit/WebViewDatabase.java8
-rw-r--r--core/java/android/widget/AbsListView.java5
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java10
-rw-r--r--core/java/android/widget/ListPopupWindow.java10
-rw-r--r--core/java/android/widget/PopupWindow.java15
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuView.java4
-rw-r--r--core/java/com/android/internal/view/menu/MenuPopupHelper.java4
18 files changed, 163 insertions, 132 deletions
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index 6e589e4..bcab66e 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -215,7 +215,7 @@ public class AnimatorInflater {
(toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
// special case for colors: ignore valueType and get ints
getFloats = false;
- anim.setEvaluator(new RGBEvaluator());
+ anim.setEvaluator(new ArgbEvaluator());
}
if (getFloats) {
diff --git a/core/java/android/animation/RGBEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index bae0af0..c3875be 100644
--- a/core/java/android/animation/RGBEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -20,7 +20,7 @@ package android.animation;
* This evaluator can be used to perform type interpolation between integer
* values that represent ARGB colors.
*/
-public class RGBEvaluator implements TypeEvaluator {
+public class ArgbEvaluator implements TypeEvaluator {
/**
* This function returns the calculated in-between value for a color
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index cfecec1..f884473 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -862,7 +862,7 @@ public class ValueAnimator extends Animator {
* of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
* are not one of these primitive types, or if different evaluation is desired (such as is
* necessary with int values that represent colors), a custom evaluator needs to be assigned.
- * For example, when running an animation on color values, the {@link RGBEvaluator}
+ * For example, when running an animation on color values, the {@link ArgbEvaluator}
* should be used to get correct RGB color interpolation.
*
* <p>If this ValueAnimator has only one set of values being animated between, this evaluator
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index f16c4ef..2812477 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -98,6 +98,13 @@ public class ComponentInfo extends PackageItemInfo {
}
return name;
}
+
+ /**
+ * Return whether this component and its enclosing application are enabled.
+ */
+ public boolean isEnabled() {
+ return enabled && applicationInfo.enabled;
+ }
/**
* Return the icon resource identifier to use for this component. If
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 5e96928..c76cc6c 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -131,6 +131,10 @@ public class SQLiteStatement extends SQLiteProgram
long retValue = native_1x1_long();
mDatabase.logTimeStat(mSql, timeStart);
return retValue;
+ } catch (SQLiteDoneException e) {
+ throw new SQLiteDoneException(
+ "expected 1 row from this query but query returned no data. check the query: " +
+ mSql);
} finally {
releaseAndUnlock();
}
@@ -150,6 +154,10 @@ public class SQLiteStatement extends SQLiteProgram
String retValue = native_1x1_string();
mDatabase.logTimeStat(mSql, timeStart);
return retValue;
+ } catch (SQLiteDoneException e) {
+ throw new SQLiteDoneException(
+ "expected 1 row from this query but query returned no data. check the query: " +
+ mSql);
} finally {
releaseAndUnlock();
}
@@ -172,6 +180,10 @@ public class SQLiteStatement extends SQLiteProgram
} catch (IOException ex) {
Log.e(TAG, "simpleQueryForBlobFileDescriptor() failed", ex);
return null;
+ } catch (SQLiteDoneException e) {
+ throw new SQLiteDoneException(
+ "expected 1 row from this query but query returned no data. check the query: " +
+ mSql);
} finally {
releaseAndUnlock();
}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 4688847..4f188f8 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -414,8 +414,6 @@ public class Environment {
* emulated. If true, the device does not have real external storage
* and certain system services such as the package manager use this
* to determine where to install an application.
- *
- * @hide
*/
public static boolean isExternalStorageEmulated() {
if (mIsExternalStorageEmulated == null) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index d1ca0c9..ee091f0 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3430,12 +3430,6 @@ public final class ContactsContract {
* <th colspan='4'>PhoneLookup</th>
* </tr>
* <tr>
- * <td>long</td>
- * <td>{@link #_ID}</td>
- * <td>read-only</td>
- * <td>Data row ID.</td>
- * </tr>
- * <tr>
* <td>String</td>
* <td>{@link #NUMBER}</td>
* <td>read-only</td>
@@ -3462,6 +3456,12 @@ public final class ContactsContract {
* <th colspan='4'>Join with {@link Contacts}</th>
* </tr>
* <tr>
+ * <td>long</td>
+ * <td>{@link #_ID}</td>
+ * <td>read-only</td>
+ * <td>Contact ID.</td>
+ * </tr>
+ * <tr>
* <td>String</td>
* <td>{@link #LOOKUP_KEY}</td>
* <td>read-only</td>
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 366393c..7c55f7b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1073,11 +1073,6 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
surfaceChanged = true;
-
- if (mAttachInfo.mHardwareRenderer != null) {
- // This will bail out early if already initialized
- mAttachInfo.mHardwareRenderer.initialize(mHolder);
- }
}
if (surfaceChanged) {
mSurfaceHolderCallback.surfaceChanged(mSurfaceHolder,
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 4c2f0b4..1313fcc 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -204,11 +204,6 @@ import junit.framework.Assert;
case KeyEvent.KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
- if (!mWebView.nativeCursorMatchesFocus()) {
- return down ? mWebView.onKeyDown(keyCode, event) : mWebView
- .onKeyUp(keyCode, event);
-
- }
isArrowKey = true;
break;
}
@@ -258,10 +253,6 @@ import junit.framework.Assert;
if (isPopupShowing()) {
return super.dispatchKeyEvent(event);
}
- if (!mWebView.nativeCursorMatchesFocus()) {
- return down ? mWebView.onKeyDown(keyCode, event) : mWebView
- .onKeyUp(keyCode, event);
- }
// Center key should be passed to a potential onClick
if (!down) {
mWebView.centerKeyPressOnTextField();
@@ -753,12 +744,7 @@ import junit.framework.Assert;
if (event.getAction() != MotionEvent.ACTION_MOVE) {
return false;
}
- // If the Cursor is not on the text input, webview should handle the
- // trackball
- if (!mWebView.nativeCursorMatchesFocus()) {
- return mWebView.onTrackballEvent(event);
- }
- Spannable text = (Spannable) getText();
+ Spannable text = getText();
MovementMethod move = getMovementMethod();
if (move != null && getLayout() != null &&
move.onTrackballEvent(this, text, event)) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f98ad74..4a9e441 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -56,6 +56,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.text.Selection;
@@ -2617,10 +2618,6 @@ public class WebView extends AbsoluteLayout
private int computeRealHorizontalScrollRange() {
if (mDrawHistory) {
return mHistoryWidth;
- } else if (mHorizontalScrollBarMode == SCROLLBAR_ALWAYSOFF
- && !mZoomManager.canZoomOut()) {
- // only honor the scrollbar mode when it is at minimum zoom level
- return computeHorizontalScrollExtent();
} else {
// to avoid rounding error caused unnecessary scrollbar, use floor
return (int) Math.floor(mContentWidth * mZoomManager.getScale());
@@ -2651,10 +2648,6 @@ public class WebView extends AbsoluteLayout
private int computeRealVerticalScrollRange() {
if (mDrawHistory) {
return mHistoryHeight;
- } else if (mVerticalScrollBarMode == SCROLLBAR_ALWAYSOFF
- && !mZoomManager.canZoomOut()) {
- // only honor the scrollbar mode when it is at minimum zoom level
- return computeVerticalScrollExtent();
} else {
// to avoid rounding error caused unnecessary scrollbar, use floor
return (int) Math.floor(mContentHeight * mZoomManager.getScale());
@@ -5329,17 +5322,10 @@ public class WebView extends AbsoluteLayout
+ " numPointers=" + ev.getPointerCount());
}
- int action = ev.getAction();
- float x = ev.getX();
- float y = ev.getY();
- long eventTime = ev.getEventTime();
-
- // mDeferMultitouch is a hack for layout tests, where it is used to
- // force passing multi-touch events to webkit.
- // FIXME: always pass multi-touch events to webkit and remove everything
- // related to mDeferMultitouch.
- if (ev.getPointerCount() > 1 &&
- (mDeferMultitouch || mZoomManager.isZoomScaleFixed())) {
+ // Always pass multi-touch event to WebKit first.
+ // If WebKit doesn't consume it and set preventDefault to true,
+ // WebView's private handler will handle it.
+ if (ev.getPointerCount() > 1) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit");
}
@@ -5347,59 +5333,15 @@ public class WebView extends AbsoluteLayout
return true;
}
- final ScaleGestureDetector detector =
- mZoomManager.getMultiTouchGestureDetector();
-
- if (mZoomManager.supportsMultiTouchZoom() && ev.getPointerCount() > 1) {
- if (!detector.isInProgress() &&
- ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) {
- // Insert a fake pointer down event in order to start
- // the zoom scale detector.
- MotionEvent temp = MotionEvent.obtain(ev);
- // Clear the original event and set it to
- // ACTION_POINTER_DOWN.
- try {
- temp.setAction(temp.getAction() &
- ~MotionEvent.ACTION_MASK |
- MotionEvent.ACTION_POINTER_DOWN);
- detector.onTouchEvent(temp);
- } finally {
- temp.recycle();
- }
- }
-
- detector.onTouchEvent(ev);
+ return handleTouchEventCommon(ev);
+ }
- if (detector.isInProgress()) {
- mLastTouchTime = eventTime;
- cancelLongPress();
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- if (!mZoomManager.supportsPanDuringZoom()) {
- return true;
- }
- mTouchMode = TOUCH_DRAG_MODE;
- if (mVelocityTracker == null) {
- mVelocityTracker = VelocityTracker.obtain();
- }
- }
+ private boolean handleTouchEventCommon(MotionEvent ev) {
+ int action = ev.getAction();
+ float x = ev.getX();
+ float y = ev.getY();
+ long eventTime = ev.getEventTime();
- x = detector.getFocusX();
- y = detector.getFocusY();
- action = ev.getAction() & MotionEvent.ACTION_MASK;
- if (action == MotionEvent.ACTION_POINTER_DOWN) {
- cancelTouch();
- action = MotionEvent.ACTION_DOWN;
- } else if (action == MotionEvent.ACTION_POINTER_UP) {
- // set mLastTouchX/Y to the remaining point
- mLastTouchX = x;
- mLastTouchY = y;
- } else if (action == MotionEvent.ACTION_MOVE) {
- // negative x or y indicate it is on the edge, skip it.
- if (x < 0 || y < 0) {
- return true;
- }
- }
- }
// Due to the touch screen edge effect, a touch closer to the edge
// always snapped to the edge. As getViewWidth() can be different from
@@ -5612,22 +5554,6 @@ public class WebView extends AbsoluteLayout
break;
}
- // Only lock dragging to one axis if we don't have a scale in progress.
- // Scaling implies free-roaming movement. Note this is only ever a question
- // if mZoomManager.supportsPanDuringZoom() is true.
- if (detector != null && !detector.isInProgress()) {
- // if it starts nearly horizontal or vertical, enforce it
- int ax = Math.abs(deltaX);
- int ay = Math.abs(deltaY);
- if (ax > MAX_SLOPE_FOR_DIAG * ay) {
- mSnapScrollMode = SNAP_X;
- mSnapPositive = deltaX > 0;
- } else if (ay > MAX_SLOPE_FOR_DIAG * ax) {
- mSnapScrollMode = SNAP_Y;
- mSnapPositive = deltaY > 0;
- }
- }
-
mTouchMode = TOUCH_DRAG_MODE;
mLastTouchX = x;
mLastTouchY = y;
@@ -5884,13 +5810,82 @@ public class WebView extends AbsoluteLayout
ted.mPoints[c] = new Point(x, y);
}
ted.mMetaState = ev.getMetaState();
- ted.mReprocess = mDeferTouchProcess;
+ ted.mReprocess = true;
+ ted.mMotionEvent = MotionEvent.obtain(ev);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
+ private boolean handleMultiTouchInWebView(MotionEvent ev) {
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
+ + " mTouchMode=" + mTouchMode
+ + " numPointers=" + ev.getPointerCount()
+ + " scrolloffset=(" + mScrollX + "," + mScrollY + ")");
+ }
+
+ final ScaleGestureDetector detector =
+ mZoomManager.getMultiTouchGestureDetector();
+ int action = ev.getAction();
+ float x = ev.getX();
+ float y = ev.getY();
+ long eventTime = ev.getEventTime();
+
+ if (!detector.isInProgress() &&
+ ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) {
+ // Insert a fake pointer down event in order to start
+ // the zoom scale detector.
+ MotionEvent temp = MotionEvent.obtain(ev);
+ // Clear the original event and set it to
+ // ACTION_POINTER_DOWN.
+ try {
+ temp.setAction(temp.getAction() &
+ ~MotionEvent.ACTION_MASK |
+ MotionEvent.ACTION_POINTER_DOWN);
+ detector.onTouchEvent(temp);
+ } finally {
+ temp.recycle();
+ }
+ }
+
+ detector.onTouchEvent(ev);
+
+ if (detector.isInProgress()) {
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "detector is in progress");
+ }
+ mLastTouchTime = eventTime;
+ cancelLongPress();
+ mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
+ if (!mZoomManager.supportsPanDuringZoom()) {
+ return false;
+ }
+ mTouchMode = TOUCH_DRAG_MODE;
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ }
+
+ action = ev.getAction() & MotionEvent.ACTION_MASK;
+ if (action == MotionEvent.ACTION_POINTER_DOWN) {
+ cancelTouch();
+ action = MotionEvent.ACTION_DOWN;
+ } else if (action == MotionEvent.ACTION_POINTER_UP) {
+ // set mLastTouchX/Y to the remaining point
+ mLastTouchX = x;
+ mLastTouchY = y;
+ } else if (action == MotionEvent.ACTION_MOVE) {
+ // negative x or y indicate it is on the edge, skip it.
+ if (x < 0 || y < 0) {
+ return false;
+ }
+ }
+
+ return handleTouchEventCommon(ev);
+ }
+
private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
if (shouldForwardTouchEvent()) {
if (removeEvents) {
@@ -7263,6 +7258,13 @@ public class WebView extends AbsoluteLayout
// prevent default is not called in WebCore, so the
// message needs to be reprocessed in UI
TouchEventData ted = (TouchEventData) msg.obj;
+
+ if (ted.mPoints.length > 1) { // for multi-touch.
+ handleMultiTouchInWebView(ted.mMotionEvent);
+ break;
+ }
+
+ // Following is for single touch.
switch (ted.mAction) {
case MotionEvent.ACTION_DOWN:
mLastDeferTouchX = contentToViewX(ted.mPoints[0].x)
@@ -8088,7 +8090,6 @@ public class WebView extends AbsoluteLayout
private native int nativeCursorFramePointer();
private native Rect nativeCursorNodeBounds();
private native int nativeCursorNodePointer();
- /* package */ native boolean nativeCursorMatchesFocus();
private native boolean nativeCursorIntersects(Rect visibleRect);
private native boolean nativeCursorIsAnchor();
private native boolean nativeCursorIsTextInput();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index a482b74..c874160 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -33,6 +33,7 @@ import android.provider.MediaStore;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.webkit.DeviceMotionService;
@@ -830,6 +831,7 @@ final class WebViewCore {
Point[] mPoints;
int mMetaState;
boolean mReprocess;
+ MotionEvent mMotionEvent;
}
static class GeolocationPermissionsData {
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 7b9def0..e1392ae 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -223,6 +223,7 @@ public class WebViewDatabase {
null);
}
}
+ mDatabase.enableWriteAheadLogging();
// mDatabase should not be null,
// the only case is RequestAPI test has problem to create db
@@ -233,7 +234,7 @@ public class WebViewDatabase {
}
if (mDatabase.getVersion() != DATABASE_VERSION) {
- mDatabase.beginTransaction();
+ mDatabase.beginTransactionNonExclusive();
try {
upgradeDatabase();
mDatabase.setTransactionSuccessful();
@@ -261,6 +262,7 @@ public class WebViewDatabase {
CACHE_DATABASE_FILE, 0, null);
}
}
+ mCacheDatabase.enableWriteAheadLogging();
// mCacheDatabase should not be null,
// the only case is RequestAPI test has problem to create db
@@ -271,7 +273,7 @@ public class WebViewDatabase {
}
if (mCacheDatabase.getVersion() != CACHE_DATABASE_VERSION) {
- mCacheDatabase.beginTransaction();
+ mCacheDatabase.beginTransactionNonExclusive();
try {
upgradeCacheDatabase();
bootstrapCacheDatabase();
@@ -648,7 +650,7 @@ public class WebViewDatabase {
+ "WebViewWorkerThread instead of from "
+ Thread.currentThread().getName());
}
- mCacheDatabase.beginTransaction();
+ mCacheDatabase.beginTransactionNonExclusive();
return true;
}
return false;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index b85670c..bccde8d 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4810,7 +4810,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mFiltered && mPopup != null && mPopup.isShowing()) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0) {
- getKeyDispatcherState().startTracking(event, this);
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
handled = true;
} else if (event.getAction() == KeyEvent.ACTION_UP
&& event.isTracking() && !event.isCanceled()) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index ee037cd..4d8d21f 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -607,10 +607,16 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
// special case for the back key, we do not even try to send it
// to the drop down list but instead, consume it immediately
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
- getKeyDispatcherState().startTracking(event, this);
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
- getKeyDispatcherState().handleUpEvent(event);
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
if (event.isTracking() && !event.isCanceled()) {
dismissDropDown();
return true;
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 3bba816..444a163d 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -915,10 +915,16 @@ public class ListPopupWindow {
// to the drop down list but instead, consume it immediately
final View anchorView = mDropDownAnchorView;
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
- anchorView.getKeyDispatcherState().startTracking(event, this);
+ KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
- anchorView.getKeyDispatcherState().handleUpEvent(event);
+ KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
if (event.isTracking() && !event.isCanceled()) {
dismiss();
return true;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5a5b6f4..79d6a81 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1468,12 +1468,17 @@ public class PopupWindow {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0) {
- getKeyDispatcherState().startTracking(event, this);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP
- && getKeyDispatcherState().isTracking(event) && !event.isCanceled()) {
- dismiss();
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null && state.isTracking(event) && !event.isCanceled()) {
+ dismiss();
+ return true;
+ }
}
return super.dispatchKeyEvent(event);
} else {
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index 9381675..463902f 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -139,6 +139,10 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
mReserveOverflow = reserveOverflow;
}
+ public View getOverflowButton() {
+ return mOverflowButton;
+ }
+
@Override
protected LayoutParams generateDefaultLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index fe41f52..b93fac4 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -68,6 +68,10 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
}
}
+ public void setAnchorView(View anchor) {
+ mAnchorView = new WeakReference<View>(anchor);
+ }
+
public void show() {
if (!tryShow()) {
throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");