diff options
Diffstat (limited to 'core/java')
20 files changed, 135 insertions, 98 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 5cde65c..03e0c0f 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -247,7 +247,6 @@ public class AccountManagerService } public void systemReady() { - initUser(UserHandle.USER_OWNER); } private UserManager getUserManager() { diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index aba8710..8cbf5b1 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.UUID; import android.net.LocalSocket; import java.nio.ByteOrder; import java.nio.ByteBuffer; @@ -140,7 +141,9 @@ public final class BluetoothSocket implements Closeable { throw new IOException("Invalid RFCOMM channel: " + port); } } - mUuid = uuid; + if(uuid != null) + mUuid = uuid; + else mUuid = new ParcelUuid(new UUID(0, 0)); mType = type; mAuth = auth; mEncrypt = encrypt; diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 1e4ad76..bb0c686 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -21,7 +21,6 @@ import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.accounts.AccountManagerService; import android.app.ActivityManager; -import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -56,6 +55,7 @@ import android.text.format.Time; import android.util.EventLog; import android.util.Log; import android.util.Pair; +import android.util.Slog; import com.android.internal.R; import com.android.internal.util.IndentingPrintWriter; @@ -154,7 +154,9 @@ public class SyncManager { private AlarmManager mAlarmService = null; private SyncStorageEngine mSyncStorageEngine; - final public SyncQueue mSyncQueue; + + // @GuardedBy("mSyncQueue") + private final SyncQueue mSyncQueue; protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList(); @@ -310,13 +312,10 @@ public class SyncManager { if (userId == UserHandle.USER_NULL) return; if (Intent.ACTION_USER_REMOVED.equals(action)) { - Log.i(TAG, "User removed: u" + userId); onUserRemoved(userId); } else if (Intent.ACTION_USER_STARTING.equals(action)) { - Log.i(TAG, "User starting: u" + userId); onUserStarting(userId); } else if (Intent.ACTION_USER_STOPPING.equals(action)) { - Log.i(TAG, "User stopping: u" + userId); onUserStopping(userId); } } @@ -337,6 +336,10 @@ public class SyncManager { } } + /** + * Should only be created after {@link ContentService#systemReady()} so that + * {@link PackageManager} is ready to query. + */ public SyncManager(Context context, boolean factoryTest) { // Initialize the SyncStorageEngine first, before registering observers // and creating threads and so on; it may fail if the disk is full. @@ -440,9 +443,6 @@ public class SyncManager { UserHandle.ALL, new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), null, null); - - // do this synchronously to ensure we have the accounts before this call returns - onUserStarting(UserHandle.USER_OWNER); } // Pick a random second in a day to seed all periodic syncs @@ -902,7 +902,9 @@ public class SyncManager { updateRunningAccounts(); - mSyncQueue.addPendingOperations(userId); + synchronized (mSyncQueue) { + mSyncQueue.addPendingOperations(userId); + } // Schedule sync for any accounts under started user final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId); @@ -1957,10 +1959,10 @@ public class SyncManager { synchronized (mSyncQueue) { if (isLoggable) { Log.v(TAG, "build the operation array, syncQueue size is " - + mSyncQueue.mOperationsMap.size()); + + mSyncQueue.getOperations().size()); } - Iterator<SyncOperation> operationIterator = - mSyncQueue.mOperationsMap.values().iterator(); + final Iterator<SyncOperation> operationIterator = mSyncQueue.getOperations() + .iterator(); final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); @@ -2153,7 +2155,7 @@ public class SyncManager { runSyncFinishedOrCanceledLocked(null, toReschedule); scheduleSyncOperation(toReschedule.mSyncOperation); } - synchronized (mSyncQueue){ + synchronized (mSyncQueue) { mSyncQueue.remove(candidate); } dispatchSyncOperation(candidate); diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java index 395658c..c9a325e 100644 --- a/core/java/android/content/SyncQueue.java +++ b/core/java/android/content/SyncQueue.java @@ -27,11 +27,14 @@ import android.util.Pair; import com.google.android.collect.Maps; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** + * Queue of pending sync operations. Not inherently thread safe, external + * callers are responsible for locking. * * @hide */ @@ -43,13 +46,11 @@ public class SyncQueue { // A Map of SyncOperations operationKey -> SyncOperation that is designed for // quick lookup of an enqueued SyncOperation. - public final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); + private final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) { mSyncStorageEngine = syncStorageEngine; mSyncAdapters = syncAdapters; - - addPendingOperations(UserHandle.USER_OWNER); } public void addPendingOperations(int userId) { @@ -198,6 +199,10 @@ public class SyncQueue { } } + public Collection<SyncOperation> getOperations() { + return mOperationsMap.values(); + } + public void dump(StringBuilder sb) { final long now = SystemClock.elapsedRealtime(); sb.append("SyncQueue: ").append(mOperationsMap.size()).append(" operation(s)\n"); diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index de97481..10e7bff 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -609,23 +609,25 @@ public class SyncStorageEngine extends Handler { public void clearAllBackoffs(SyncQueue syncQueue) { boolean changed = false; synchronized (mAuthorities) { - for (AccountInfo accountInfo : mAccounts.values()) { - for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { - if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE - || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "clearAllBackoffs:" - + " authority:" + authorityInfo.authority - + " account:" + accountInfo.accountAndUser.account.name - + " user:" + accountInfo.accountAndUser.userId - + " backoffTime was: " + authorityInfo.backoffTime - + " backoffDelay was: " + authorityInfo.backoffDelay); + synchronized (syncQueue) { + for (AccountInfo accountInfo : mAccounts.values()) { + for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { + if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE + || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "clearAllBackoffs:" + + " authority:" + authorityInfo.authority + + " account:" + accountInfo.accountAndUser.account.name + + " user:" + accountInfo.accountAndUser.userId + + " backoffTime was: " + authorityInfo.backoffTime + + " backoffDelay was: " + authorityInfo.backoffDelay); + } + authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; + authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; + syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, + accountInfo.accountAndUser.userId, authorityInfo.authority, 0); + changed = true; } - authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; - authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; - syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, - accountInfo.accountAndUser.userId, authorityInfo.authority, 0); - changed = true; } } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index a0283d3..32cc7fd 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -554,6 +554,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { manageSpaceActivityName = orig.manageSpaceActivityName; descriptionRes = orig.descriptionRes; uiOptions = orig.uiOptions; + backupAgentName = orig.backupAgentName; } diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 0b91786..6def4a1 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -264,7 +264,8 @@ public abstract class RegisteredServicesCache<V> { if (user.services == null) { generateServicesMap(userId); } - return Collections.unmodifiableCollection(user.services.values()); + return Collections.unmodifiableCollection( + new ArrayList<ServiceInfo<V>>(user.services.values())); } } diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 69e1de9..ce5f163 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -110,7 +110,7 @@ import java.util.concurrent.atomic.AtomicInteger; * <h2>The 4 steps</h2> * <p>When an asynchronous task is executed, the task goes through 4 steps:</p> * <ol> - * <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task + * <li>{@link #onPreExecute()}, invoked on the UI thread before the task * is executed. This step is normally used to setup the task, for instance by * showing a progress bar in the user interface.</li> * <li>{@link #doInBackground}, invoked on the background thread diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index de4dd88..affeb90 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -283,6 +283,8 @@ public class SearchManagerService extends ISearchManager.Stub { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); synchronized (mSearchables) { for (int i = 0; i < mSearchables.size(); i++) { diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index c72b714..4820c5e 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -612,18 +612,23 @@ public class DreamService extends Service implements Window.Callback { View.SYSTEM_UI_FLAG_LOW_PROFILE); getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); } catch (Throwable t) { - Slog.w("Crashed adding window view", t); + Slog.w(TAG, "Crashed adding window view", t); safelyFinish(); return; } // start it up - try { - onDreamingStarted(); - } catch (Throwable t) { - Slog.w("Crashed in onDreamingStarted()", t); - safelyFinish(); - } + mHandler.post(new Runnable() { + @Override + public void run() { + try { + onDreamingStarted(); + } catch (Throwable t) { + Slog.w(TAG, "Crashed in onDreamingStarted()", t); + safelyFinish(); + } + } + }); } private void safelyFinish() { diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 37e0a36..ec1695e 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -925,8 +925,17 @@ public abstract class HardwareRenderer { sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value); Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]); + sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value); + Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]); + + sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value); + Log.d(LOG_TAG, " SAMPLES = " + value[0]); + sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value); Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0])); + + sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value); + Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0])); } GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException { @@ -1433,6 +1442,7 @@ public abstract class HardwareRenderer { EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, + EGL_CONFIG_CAVEAT, EGL_NONE, // TODO: Find a better way to choose the stencil size EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | diff --git a/core/java/android/view/IDisplayContentChangeListener.aidl b/core/java/android/view/IDisplayContentChangeListener.aidl index 8f23ff6..ef7edea 100644 --- a/core/java/android/view/IDisplayContentChangeListener.aidl +++ b/core/java/android/view/IDisplayContentChangeListener.aidl @@ -28,5 +28,6 @@ import android.graphics.Rect; oneway interface IDisplayContentChangeListener { void onWindowTransition(int displayId, int transition, in WindowInfo info); void onRectangleOnScreenRequested(int displayId, in Rect rectangle, boolean immediate); + void onWindowLayersChanged(int displayId); void onRotationChanged(int rotation); } diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 07bb8f9..7ef6939 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -245,6 +245,7 @@ public class Surface implements Parcelable { private static native void nativeOpenTransaction(); private static native void nativeCloseTransaction(); + private static native void nativeSetAnimationTransaction(); private native void nativeSetLayer(int zorder); private native void nativeSetPosition(float x, float y); @@ -525,6 +526,11 @@ public class Surface implements Parcelable { nativeCloseTransaction(); } + /** flag the transaction as an animation @hide */ + public static void setAnimationTransaction() { + nativeSetAnimationTransaction(); + } + /** @hide */ public void setLayer(int zorder) { nativeSetLayer(zorder); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 946965b..b4ba871 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4906,7 +4906,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @param outRect The output location */ - private void getBoundsOnScreen(Rect outRect) { + void getBoundsOnScreen(Rect outRect) { if (mAttachInfo == null) { return; } @@ -8661,7 +8661,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Return the visible drawing bounds of your view. Fills in the output * rectangle with the values from getScrollX(), getScrollY(), - * getWidth(), and getHeight(). + * getWidth(), and getHeight(). These bounds do not account for any + * transformation properties currently set on the view, such as + * {@link #setScaleX(float)} or {@link #setRotation(float)}. * * @param outRect The (scrolled) drawing bounds of the view. */ @@ -10515,9 +10517,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <p>Causes the Runnable to be added to the message queue. * The runnable will be run on the user interface thread.</p> * - * <p>This method can be invoked from outside of the UI thread - * only when this View is attached to a window.</p> - * * @param action The Runnable that will be executed. * * @return Returns true if the Runnable was successfully placed in to the @@ -10542,9 +10541,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * after the specified amount of time elapses. * The runnable will be run on the user interface thread.</p> * - * <p>This method can be invoked from outside of the UI thread - * only when this View is attached to a window.</p> - * * @param action The Runnable that will be executed. * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. @@ -10573,9 +10569,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <p>Causes the Runnable to execute on the next animation time step. * The runnable will be run on the user interface thread.</p> * - * <p>This method can be invoked from outside of the UI thread - * only when this View is attached to a window.</p> - * * @param action The Runnable that will be executed. * * @see #postOnAnimationDelayed @@ -10597,9 +10590,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * after the specified amount of time elapses. * The runnable will be run on the user interface thread.</p> * - * <p>This method can be invoked from outside of the UI thread - * only when this View is attached to a window.</p> - * * @param action The Runnable that will be executed. * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. @@ -10621,9 +10611,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * <p>Removes the specified Runnable from the message queue.</p> * - * <p>This method can be invoked from outside of the UI thread - * only when this View is attached to a window.</p> - * * @param action The Runnable to remove from the message handling queue * * @return true if this view could ask the Handler to remove the Runnable, diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 9ce7df9..b95e1bd 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3383,7 +3383,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } if (child.isLayoutDirectionInherited()) { - child.resetResolvedLayoutDirection(); + child.resetRtlProperties(); child.resolveRtlPropertiesIfNeeded(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 0475283..67452ec 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -29,12 +29,14 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.Drawable; import android.media.AudioManager; @@ -885,11 +887,13 @@ public final class ViewRootImpl implements ViewParent, // Intersect with the bounds of the window to skip // updates that lie outside of the visible region final float appScale = mAttachInfo.mApplicationScale; - localDirty.intersect(0, 0, - (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f)); - - if (!mWillDrawSoon) { - scheduleTraversals(); + if (localDirty.intersect(0, 0, + (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f))) { + if (!mWillDrawSoon) { + scheduleTraversals(); + } + } else { + localDirty.setEmpty(); } return null; @@ -1182,6 +1186,7 @@ public final class ViewRootImpl implements ViewParent, viewVisibilityChanged = false; mLastConfiguration.setTo(host.getResources().getConfiguration()); mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; + host.setLayoutDirection(mLastConfiguration.getLayoutDirection()); host.dispatchAttachedToWindow(attachInfo, 0); mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets); host.fitSystemWindows(mFitSystemWindowsInsets); @@ -2319,24 +2324,14 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityFocusedHost.getAccessibilityNodeProvider(); Rect bounds = mView.mAttachInfo.mTmpInvalRect; if (provider == null) { - mAccessibilityFocusedHost.getDrawingRect(bounds); - if (mView instanceof ViewGroup) { - ViewGroup viewGroup = (ViewGroup) mView; - try { - viewGroup.offsetDescendantRectToMyCoords(mAccessibilityFocusedHost, bounds); - } catch (IllegalArgumentException iae) { - Log.e(TAG, "Temporary detached view that was neither removed not reattached: " - + mAccessibilityFocusedHost); - return; - } - } + mAccessibilityFocusedHost.getBoundsOnScreen(bounds); } else { if (mAccessibilityFocusedVirtualView == null) { return; } mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds); - bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); } + bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); drawable.setBounds(bounds); drawable.draw(canvas); } @@ -2684,7 +2679,12 @@ public final class ViewRootImpl implements ViewParent, // the one in them which may be newer. config = mView.getResources().getConfiguration(); if (force || mLastConfiguration.diff(config) != 0) { + final int lastLayoutDirection = mLastConfiguration.getLayoutDirection(); + final int currentLayoutDirection = config.getLayoutDirection(); mLastConfiguration.setTo(config); + if (lastLayoutDirection != currentLayoutDirection) { + mView.setLayoutDirection(currentLayoutDirection); + } mView.dispatchConfigurationChanged(config); } } diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 646fe7e..3b5e75b 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -241,6 +241,7 @@ public abstract class AbsSeekBar extends ProgressBar { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); updateThumbPos(w, h); } @@ -555,4 +556,23 @@ public abstract class AbsSeekBar extends ProgressBar { } return false; } + + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + + int max = getMax(); + float scale = max > 0 ? (float) getProgress() / (float) max : 0; + + Drawable thumb = mThumb; + if (thumb != null) { + setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE); + /* + * Since we draw translated, the drawable's bounds that it signals + * for invalidation won't be the actual bounds we want invalidated, + * so just invalidate this whole view. + */ + invalidate(); + } + } } diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 75d1471..f0eb94f 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -1093,7 +1093,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED); mPopup.setListItemExpandMax(EXPAND_MAX); } - mPopup.setLayoutDirection(getLayoutDirection()); mPopup.show(); mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS); } diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 1c81d11..3d6b69e 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -1021,8 +1021,6 @@ public class ListPopupWindow { mDropDownList.setOnItemSelectedListener(mItemSelectedListener); } - mDropDownList.setLayoutDirection(mLayoutDirection); - dropDownView = mDropDownList; View hintView = mPromptView; @@ -1132,21 +1130,6 @@ public class ListPopupWindow { } /** - * Set the layout direction for this popup. Should be a resolved direction as the - * popup as no capacity to do the resolution on his own. - * - * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR}, - * {@link View#LAYOUT_DIRECTION_RTL}, - * - */ - public void setLayoutDirection(int layoutDirection) { - mLayoutDirection = layoutDirection; - if (mDropDownList != null) { - mDropDownList.setLayoutDirection(mLayoutDirection); - } - } - - /** * <p>Wrapper class for a ListView. This wrapper can hijack the focus to * make sure the list uses the appropriate drawables and states when * displayed on screen within a drop down. The focus is never actually diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b3c679c..8e5ff40 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -367,6 +367,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private boolean mSingleLine; private int mDesiredHeightAtMeasure = -1; private boolean mIncludePad = true; + private int mDeferScroll = -1; // tmp primitives, so we don't alloc them on each draw private Rect mTempRect; @@ -6317,6 +6318,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); + if (mDeferScroll >= 0) { + int curs = mDeferScroll; + mDeferScroll = -1; + bringPointIntoView(Math.min(curs, mText.length())); + } if (changed && mEditor != null) mEditor.invalidateTextDisplayList(); } @@ -6399,6 +6405,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * This has to be called after layout. Returns true if anything changed. */ public boolean bringPointIntoView(int offset) { + if (isLayoutRequested()) { + mDeferScroll = offset; + return false; + } boolean changed = false; Layout layout = isShowingHint() ? mHintLayout: mLayout; @@ -7108,13 +7118,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener registerForPreDraw(); } + checkForResize(); + if (curs >= 0) { mHighlightPathBogus = true; if (mEditor != null) mEditor.makeBlink(); bringPointIntoView(curs); } - - checkForResize(); } /** @@ -7161,6 +7171,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (oldStart >= 0 || newStart >= 0) { invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart); + checkForResize(); registerForPreDraw(); if (mEditor != null) mEditor.makeBlink(); } |
