summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accounts/ChooseAccountActivity.java120
-rw-r--r--core/java/android/app/FragmentManager.java6
-rw-r--r--core/java/android/app/LoaderManager.java2
-rw-r--r--core/java/android/bluetooth/BluetoothDeviceProfileState.java10
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java20
-rw-r--r--core/java/android/bluetooth/IBluetoothHeadset.aidl2
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/android/view/View.java21
-rw-r--r--core/java/android/view/ViewRoot.java6
-rw-r--r--core/java/android/webkit/WebSettings.java2
-rw-r--r--core/java/android/webkit/WebTextView.java8
-rw-r--r--core/java/android/webkit/WebView.java171
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java2
-rw-r--r--core/java/android/widget/StackView.java8
-rw-r--r--core/java/android/widget/TextView.java59
15 files changed, 312 insertions, 126 deletions
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 0bbb6fc..293df78 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -15,23 +15,39 @@
*/
package android.accounts;
-import android.app.ListActivity;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
import android.widget.ArrayAdapter;
+import android.widget.ImageView;
import android.widget.ListView;
-import android.view.View;
-import android.util.Log;
+import android.widget.TextView;
+import com.android.internal.R;
+
+import java.util.HashMap;
/**
* @hide
*/
-public class ChooseAccountActivity extends ListActivity {
+public class ChooseAccountActivity extends Activity {
+
private static final String TAG = "AccountManager";
+
private Parcelable[] mAccounts = null;
private AccountManagerResponse mAccountManagerResponse = null;
private Bundle mResult;
+ private HashMap<String, AuthenticatorDescription> mTypeToAuthDescription
+ = new HashMap<String, AuthenticatorDescription>();
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -47,16 +63,51 @@ public class ChooseAccountActivity extends ListActivity {
return;
}
- String[] mAccountNames = new String[mAccounts.length];
+ getAuthDescriptions();
+
+ AccountInfo[] mAccountInfos = new AccountInfo[mAccounts.length];
for (int i = 0; i < mAccounts.length; i++) {
- mAccountNames[i] = ((Account) mAccounts[i]).name;
+ mAccountInfos[i] = new AccountInfo(((Account) mAccounts[i]).name,
+ getDrawableForType(((Account) mAccounts[i]).type));
}
- // Use an existing ListAdapter that will map an array
- // of strings to TextViews
- setListAdapter(new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_1, mAccountNames));
- getListView().setTextFilterEnabled(true);
+ setContentView(R.layout.choose_account);
+
+ // Setup the list
+ ListView list = (ListView) findViewById(android.R.id.list);
+ // Use an existing ListAdapter that will map an array of strings to TextViews
+ list.setAdapter(new AccountArrayAdapter(this,
+ android.R.layout.simple_list_item_1, mAccountInfos));
+ list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ list.setTextFilterEnabled(true);
+ list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+ onListItemClick((ListView)parent, v, position, id);
+ }
+ });
+ }
+
+ private void getAuthDescriptions() {
+ for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
+ mTypeToAuthDescription.put(desc.type, desc);
+ }
+ }
+
+ private Drawable getDrawableForType(String accountType) {
+ Drawable icon = null;
+ if(mTypeToAuthDescription.containsKey(accountType)) {
+ try {
+ AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+ Context authContext = createPackageContext(desc.packageName, 0);
+ icon = authContext.getResources().getDrawable(desc.iconId);
+ } catch (PackageManager.NameNotFoundException e) {
+ // Nothing we can do much here, just log
+ if (Log.isLoggable(TAG, Log.WARN)) {
+ Log.w(TAG, "No icon for account type " + accountType);
+ }
+ }
+ }
+ return icon;
}
protected void onListItemClick(ListView l, View v, int position, long id) {
@@ -79,4 +130,51 @@ public class ChooseAccountActivity extends ListActivity {
}
super.finish();
}
+
+ private static class AccountInfo {
+ final String name;
+ final Drawable drawable;
+
+ AccountInfo(String name, Drawable drawable) {
+ this.name = name;
+ this.drawable = drawable;
+ }
+ }
+
+ private static class ViewHolder {
+ ImageView icon;
+ TextView text;
+ }
+
+ private static class AccountArrayAdapter extends ArrayAdapter<AccountInfo> {
+ private LayoutInflater mLayoutInflater;
+ private AccountInfo[] mInfos;
+
+ public AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos) {
+ super(context, textViewResourceId, infos);
+ mInfos = infos;
+ mLayoutInflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ if (convertView == null) {
+ convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
+ holder = new ViewHolder();
+ holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
+ holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ holder.text.setText(mInfos[position].name);
+ holder.icon.setImageDrawable(mInfos[position].drawable);
+
+ return convertView;
+ }
+ }
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index bce240f..e729805 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -332,7 +332,7 @@ final class FragmentManagerState implements Parcelable {
* Container for fragments associated with an activity.
*/
final class FragmentManagerImpl extends FragmentManager {
- static boolean DEBUG = true;
+ static boolean DEBUG = false;
static final String TAG = "FragmentManager";
static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -747,7 +747,7 @@ final class FragmentManagerImpl extends FragmentManager {
f.onActivityCreated(f.mSavedFragmentState);
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onReady()");
+ + " did not call through to super.onActivityCreated()");
}
f.mSavedFragmentState = null;
}
@@ -810,7 +810,7 @@ final class FragmentManagerImpl extends FragmentManager {
f.onDestroyView();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onDestroyedView()");
+ + " did not call through to super.onDestroyView()");
}
if (f.mView != null && f.mContainer != null) {
Animator anim = null;
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index fc5f5fc..431be05 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -186,7 +186,7 @@ public abstract class LoaderManager {
class LoaderManagerImpl extends LoaderManager {
static final String TAG = "LoaderManager";
- static boolean DEBUG = true;
+ static boolean DEBUG = false;
// These are the currently active loaders. A loader is here
// from the time its load is started until it has been explicitly
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 3280d39..6ec347f 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -82,6 +82,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
public static final int TRANSITION_TO_STABLE = 102;
public static final int CONNECT_OTHER_PROFILES = 103;
+ private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs
private static final int CONNECT_OTHER_PROFILES_DELAY = 4000; // 4 secs
private BondedDevice mBondedDevice = new BondedDevice();
@@ -1010,8 +1011,9 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
case CONNECT_HFP_INCOMING:
// Connect A2DP if there is no incoming connection
// If the priority is OFF - don't auto connect.
- // If the priority is AUTO_CONNECT, auto connect code takes care.
- if (mA2dpService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON) {
+ if (mA2dpService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON ||
+ mA2dpService.getPriority(mDevice) ==
+ BluetoothProfile.PRIORITY_AUTO_CONNECT) {
Message msg = new Message();
msg.what = CONNECT_OTHER_PROFILES;
msg.arg1 = CONNECT_A2DP_OUTGOING;
@@ -1023,7 +1025,9 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
// before A2DP, so we should not hit this case. But many devices
// don't follow this.
if (mHeadsetService != null &&
- mHeadsetService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON) {
+ (mHeadsetService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON ||
+ mHeadsetService.getPriority(mDevice) ==
+ BluetoothProfile.PRIORITY_AUTO_CONNECT)) {
Message msg = new Message();
msg.what = CONNECT_OTHER_PROFILES;
msg.arg1 = CONNECT_HFP_OUTGOING;
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index d5b0042..2959fc0 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -670,6 +670,26 @@ public final class BluetoothHeadset implements BluetoothProfile {
return false;
}
+ /**
+ * Send a AT command message to the headset.
+ * @param device Remote Bluetooth Device
+ * @param cmd The String to send.
+ * @hide
+ */
+ public void sendAtCommand(BluetoothDevice device, String command) {
+ if (DBG) log("sendAtCommand()");
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ try {
+ mService.sendAtCommand(device, command);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index e952193..3c6cf77 100644
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -50,4 +50,6 @@ interface IBluetoothHeadset {
boolean startVirtualVoiceCall(in BluetoothDevice device);
boolean stopVirtualVoiceCall(in BluetoothDevice device);
+
+ void sendAtCommand(in BluetoothDevice device, String urc);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6f23215..4f21265 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1801,7 +1801,6 @@ public final class Settings {
SCREEN_BRIGHTNESS,
SCREEN_BRIGHTNESS_MODE,
VIBRATE_ON,
- NOTIFICATIONS_USE_RING_VOLUME,
MODE_RINGER,
MODE_RINGER_STREAMS_AFFECTED,
MUTE_STREAMS_AFFECTED,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 811a633..469bbaa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1813,6 +1813,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
private int mPrevWidth = -1;
private int mPrevHeight = -1;
+ private boolean mLastIsOpaque;
+
/**
* Convenience value to check for float values that are close enough to zero to be considered
* zero.
@@ -5117,7 +5119,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
removeCallbacks(mPendingCheckForLongPress);
}
}
-
+
+ /**
+ * Remove the pending click action
+ */
+ private void removePerformClickCallback() {
+ if (mPerformClick != null) {
+ removeCallbacks(mPerformClick);
+ }
+ }
+
/**
* Remove the prepress detection timer.
*/
@@ -6717,7 +6728,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
public void invalidate() {
invalidate(true);
}
-
+
/**
* This is where the invalidate() work actually happens. A full invalidate()
* causes the drawing cache to be invalidated, but this function can be called with
@@ -6734,8 +6745,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
}
+ boolean opaque = isOpaque();
if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
- (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID)) {
+ (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) ||
+ opaque != mLastIsOpaque) {
+ mLastIsOpaque = opaque;
mPrivateFlags &= ~DRAWN;
if (invalidateCache) {
mPrivateFlags &= ~DRAWING_CACHE_VALID;
@@ -7579,6 +7593,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
removeUnsetPressCallback();
removeLongPressCallback();
+ removePerformClickCallback();
destroyDrawingCache();
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 2c6ec71..ad101f8 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -710,8 +710,10 @@ public final class ViewRoot extends Handler implements ViewParent,
// object is not initialized to its backing store, but soon it
// will be (assuming the window is visible).
attachInfo.mSurface = mSurface;
- attachInfo.mUse32BitDrawingCache = PixelFormat.formatHasAlpha(lp.format) ||
- lp.format == PixelFormat.RGBX_8888;
+ // We used to use the following condition to choose 32 bits drawing caches:
+ // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
+ // However, windows are now always 32 bits by default, so choose 32 bits
+ attachInfo.mUse32BitDrawingCache = true;
attachInfo.mHasWindowFocus = false;
attachInfo.mWindowVisibility = viewVisibility;
attachInfo.mRecomputeGlobalAttributes = false;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 518ba69..0bf0eab 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -571,7 +571,6 @@ public class WebSettings {
* A combination of built in zoom controls enabled
* and on screen zoom controls disabled allows for pinch to zoom
* to work without the on screen controls
- * @hide
*/
public void setDisplayZoomControls(boolean enabled) {
mDisplayZoomControls = enabled;
@@ -580,7 +579,6 @@ public class WebSettings {
/**
* Returns true if the on screen zoom buttons are being used.
- * @hide
*/
public boolean getDisplayZoomControls() {
return mDisplayZoomControls;
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 59a239a..6e1a6fc 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -1087,7 +1087,7 @@ import junit.framework.Assert;
*/
/* package */ void setTextAndKeepSelection(String text) {
mPreChange = text.toString();
- Editable edit = (Editable) getText();
+ Editable edit = getText();
int selStart = Selection.getSelectionStart(edit);
int selEnd = Selection.getSelectionEnd(edit);
mInSetTextAndKeepSelection = true;
@@ -1097,6 +1097,12 @@ import junit.framework.Assert;
if (selEnd > newLength) selEnd = newLength;
Selection.setSelection(edit, selStart, selEnd);
mInSetTextAndKeepSelection = false;
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null && imm.isActive(this)) {
+ // Since the text has changed, do not allow the IME to replace the
+ // existing text as though it were a completion.
+ imm.restartInput(this);
+ }
updateCachedTextfield();
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c1fafa2..3102ee9 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -476,6 +476,7 @@ public class WebView extends AbsoluteLayout
private static final int TOUCH_DRAG_LAYER_MODE = 9;
// Whether to forward the touch events to WebCore
+ // Can only be set by WebKit via JNI.
private boolean mForwardTouchEvents = false;
// Whether to prevent default during touch. The initial value depends on
@@ -5358,26 +5359,26 @@ public class WebView extends AbsoluteLayout
+ " numPointers=" + ev.getPointerCount());
}
- // 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");
- }
- if (!mIsHandlingMultiTouch) {
- mIsHandlingMultiTouch = true;
+ int action = ev.getActionMasked();
+ if (ev.getPointerCount() > 1) { // Multi-touch
+ mIsHandlingMultiTouch = true;
+
+ // If WebKit already showed no interests in this sequence of events,
+ // WebView handles them directly.
+ if (mPreventDefault == PREVENT_DEFAULT_NO && action == MotionEvent.ACTION_MOVE) {
+ handleMultiTouchInWebView(ev);
+ } else {
+ passMultiTouchToWebKit(ev);
}
- passMultiTouchToWebKit(ev);
return true;
- } else {
- // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
- if (mIsHandlingMultiTouch && ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
- return false;
- }
}
- return handleTouchEventCommon(ev, ev.getActionMasked(), Math.round(ev.getX()), Math.round(ev.getY()));
+ // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
+ if (mIsHandlingMultiTouch && action == MotionEvent.ACTION_MOVE) {
+ return false;
+ }
+
+ return handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY()));
}
/*
@@ -7357,75 +7358,85 @@ public class WebView extends AbsoluteLayout
if (mPreventDefault == PREVENT_DEFAULT_YES) {
mTouchHighlightRegion.setEmpty();
}
- } else if (msg.arg2 == 0) {
- // prevent default is not called in WebCore, so the
- // message needs to be reprocessed in UI
+ } else {
TouchEventData ted = (TouchEventData) msg.obj;
- if (ted.mPoints.length > 1) { // for multi-touch.
- handleMultiTouchInWebView(ted.mMotionEvent);
+ if (ted.mPoints.length > 1) { // multi-touch
+ if (ted.mAction == MotionEvent.ACTION_POINTER_UP) {
+ mIsHandlingMultiTouch = false;
+ }
+ if (msg.arg2 == 0) {
+ mPreventDefault = PREVENT_DEFAULT_NO;
+ handleMultiTouchInWebView(ted.mMotionEvent);
+ } else {
+ mPreventDefault = PREVENT_DEFAULT_YES;
+ }
break;
}
- // Following is for single touch.
- switch (ted.mAction) {
- case MotionEvent.ACTION_DOWN:
- mLastDeferTouchX = contentToViewX(ted.mPoints[0].x)
- - mScrollX;
- mLastDeferTouchY = contentToViewY(ted.mPoints[0].y)
- - mScrollY;
- mDeferTouchMode = TOUCH_INIT_MODE;
- break;
- case MotionEvent.ACTION_MOVE: {
- // no snapping in defer process
- int x = contentToViewX(ted.mPoints[0].x) - mScrollX;
- int y = contentToViewY(ted.mPoints[0].y) - mScrollY;
- if (mDeferTouchMode != TOUCH_DRAG_MODE) {
- mDeferTouchMode = TOUCH_DRAG_MODE;
- mLastDeferTouchX = x;
- mLastDeferTouchY = y;
- startScrollingLayer(x, y);
- startDrag();
+ // prevent default is not called in WebCore, so the
+ // message needs to be reprocessed in UI
+ if (msg.arg2 == 0) {
+ // Following is for single touch.
+ switch (ted.mAction) {
+ case MotionEvent.ACTION_DOWN:
+ mLastDeferTouchX = contentToViewX(ted.mPoints[0].x)
+ - mScrollX;
+ mLastDeferTouchY = contentToViewY(ted.mPoints[0].y)
+ - mScrollY;
+ mDeferTouchMode = TOUCH_INIT_MODE;
+ break;
+ case MotionEvent.ACTION_MOVE: {
+ // no snapping in defer process
+ int x = contentToViewX(ted.mPoints[0].x) - mScrollX;
+ int y = contentToViewY(ted.mPoints[0].y) - mScrollY;
+ if (mDeferTouchMode != TOUCH_DRAG_MODE) {
+ mDeferTouchMode = TOUCH_DRAG_MODE;
+ mLastDeferTouchX = x;
+ mLastDeferTouchY = y;
+ startScrollingLayer(x, y);
+ startDrag();
+ }
+ int deltaX = pinLocX((int) (mScrollX
+ + mLastDeferTouchX - x))
+ - mScrollX;
+ int deltaY = pinLocY((int) (mScrollY
+ + mLastDeferTouchY - y))
+ - mScrollY;
+ doDrag(deltaX, deltaY);
+ if (deltaX != 0) mLastDeferTouchX = x;
+ if (deltaY != 0) mLastDeferTouchY = y;
+ break;
}
- int deltaX = pinLocX((int) (mScrollX
- + mLastDeferTouchX - x))
- - mScrollX;
- int deltaY = pinLocY((int) (mScrollY
- + mLastDeferTouchY - y))
- - mScrollY;
- doDrag(deltaX, deltaY);
- if (deltaX != 0) mLastDeferTouchX = x;
- if (deltaY != 0) mLastDeferTouchY = y;
- break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ if (mDeferTouchMode == TOUCH_DRAG_MODE) {
+ // no fling in defer process
+ mScroller.springBack(mScrollX, mScrollY, 0,
+ computeMaxScrollX(), 0,
+ computeMaxScrollY());
+ invalidate();
+ WebViewCore.resumePriority();
+ WebViewCore.resumeUpdatePicture(mWebViewCore);
+ }
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
+ case WebViewCore.ACTION_DOUBLETAP:
+ // doDoubleTap() needs mLastTouchX/Y as anchor
+ mLastTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX;
+ mLastTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY;
+ mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
+ case WebViewCore.ACTION_LONGPRESS:
+ HitTestResult hitTest = getHitTestResult();
+ if (hitTest != null && hitTest.mType
+ != HitTestResult.UNKNOWN_TYPE) {
+ performLongClick();
+ }
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
}
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (mDeferTouchMode == TOUCH_DRAG_MODE) {
- // no fling in defer process
- mScroller.springBack(mScrollX, mScrollY, 0,
- computeMaxScrollX(), 0,
- computeMaxScrollY());
- invalidate();
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_DOUBLETAP:
- // doDoubleTap() needs mLastTouchX/Y as anchor
- mLastTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX;
- mLastTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY;
- mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_LONGPRESS:
- HitTestResult hitTest = getHitTestResult();
- if (hitTest != null && hitTest.mType
- != HitTestResult.UNKNOWN_TYPE) {
- performLongClick();
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
}
}
break;
@@ -8174,8 +8185,8 @@ public class WebView extends AbsoluteLayout
* @hide This is only used by the webkit layout test.
*/
public void setDeferMultiTouch(boolean value) {
- mDeferMultitouch = value;
- Log.v(LOGTAG, "set mDeferMultitouch to " + value);
+ mDeferMultitouch = value;
+ Log.v(LOGTAG, "set mDeferMultitouch to " + value);
}
/**
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 6eb06ad..e34a204 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -696,6 +696,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
mWhichChild = 0;
showOnly(mWhichChild, true);
+ } else if (mOldItemCount != getCount()) {
+ showOnly(mWhichChild, true);
}
refreshChildren();
requestLayout();
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 9ec4b74..03c073c 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -454,9 +454,13 @@ public class StackView extends AdapterViewAnimator {
canvas.getClipBounds(stackInvalidateRect);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
- LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
+ final View child = getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if ((lp.horizontalOffset == 0 && lp.verticalOffset == 0) ||
+ child.getAlpha() == 0f || child.getVisibility() != VISIBLE) {
+ lp.resetInvalidateRect();
+ }
stackInvalidateRect.union(lp.getInvalidateRect());
- lp.resetInvalidateRect();
}
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fad0a4f..aac57ed 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4791,8 +4791,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return super.onKeyUp(keyCode, event);
}
- hideControllers();
-
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
mDPadCenterIsDown = false;
@@ -7126,6 +7124,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+ // After super.onFocusChanged so that this TextView is registered and can ask for the IME
+ // Showing the IME while focus is moved using the D-Pad is a bad idea, however this does
+ // not happen in that case (using the arrows on a bluetooth keyboard).
+ if (focused) {
+ onTouchFinished(null);
+ }
}
private int getLastTapPosition() {
@@ -7268,6 +7273,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return superResult;
}
+ final boolean touchIsFinished = action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent &&
+ isFocused();
+
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
@@ -7283,8 +7291,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
- if (mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable &&
- action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent && isFocused()) {
+ if (mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable && touchIsFinished) {
// The LinkMovementMethod which should handle taps on links has not been installed
// to support text selection. We reproduce its behavior here to open links.
ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
@@ -7306,26 +7313,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mSelectionModifierCursorController.updatePosition();
}
}
- if (action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent && isFocused()) {
- InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (touchIsFinished) {
CommitSelectionReceiver csr = null;
if (getSelectionStart() != oldSelStart || getSelectionEnd() != oldSelEnd ||
didTouchFocusSelect()) {
csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd);
}
- if (!mTextIsSelectable) {
- // Show the IME, except when selecting in read-only text.
- handled |= imm.showSoftInput(this, 0, csr) && (csr != null);
- }
-
- stopSelectionActionMode();
- boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected;
- if (hasInsertionController() && !selectAllGotFocus) {
- getInsertionController().show();
- }
+ handled = onTouchFinished(csr);
}
}
@@ -7337,6 +7333,35 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return superResult;
}
+ /** Shows the IME if applicable, ends selection mode and displays the selection controller.
+ *
+ * This method is called at the end of a touch event, when the finger is lifted up.
+ * It is also called when the TextField gains focus indirectly through a dispatched event from
+ * one of its parents. We want to have the same behavior in that case.
+ *
+ * @param csr A (possibly null) callback called if the IME has been displayed
+ * @return true if the event was properly sent to the csr
+ */
+ private boolean onTouchFinished(CommitSelectionReceiver csr) {
+ boolean handled = false;
+
+ // Show the IME, except when selecting in read-only text.
+ if (!mTextIsSelectable) {
+ final InputMethodManager imm = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ handled = imm.showSoftInput(this, 0, csr) && (csr != null);
+ }
+
+ stopSelectionActionMode();
+ boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected;
+ if (hasInsertionController() && !selectAllGotFocus) {
+ getInsertionController().show();
+ }
+
+ return handled;
+ }
+
private void prepareCursorControllers() {
boolean windowSupportsHandles = false;