Merge "Make sure IME focus is synced to View focus" into nyc-dev
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index b331be7..5ba1e9d 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2315,22 +2315,24 @@
}
/**
- * Get a view and have it show the data associated with the specified
- * position. This is called when we have already discovered that the view is
- * not available for reuse in the recycle bin. The only choices left are
+ * Gets a view and have it show the data associated with the specified
+ * position. This is called when we have already discovered that the view
+ * is not available for reuse in the recycle bin. The only choices left are
* converting an old view or making a new one.
*
- * @param position The position to display
- * @param isScrap Array of at least 1 boolean, the first entry will become true if
- * the returned view was taken from the "temporary detached" scrap heap, false if
- * otherwise.
+ * @param position the position to display
+ * @param outMetadata an array of at least 1 boolean where the first entry
+ * will be set {@code true} if the view is currently
+ * attached to the window, {@code false} otherwise (e.g.
+ * newly-inflated or remained scrap for multiple layout
+ * passes)
*
* @return A view displaying the data associated with the specified position
*/
- View obtainView(int position, boolean[] isScrap) {
+ View obtainView(int position, boolean[] outMetadata) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView");
- isScrap[0] = false;
+ outMetadata[0] = false;
// Check whether we have a transient state view. Attempt to re-bind the
// data and discard the view if we fail.
@@ -2349,7 +2351,7 @@
}
}
- isScrap[0] = true;
+ outMetadata[0] = true;
// Finish the temporary detach started in addScrapView().
transientView.dispatchFinishTemporaryDetach();
@@ -2362,19 +2364,11 @@
if (child != scrapView) {
// Failed to re-bind the data, return scrap to the heap.
mRecycler.addScrapView(scrapView, position);
- } else {
- if (child.isTemporarilyDetached()) {
- isScrap[0] = true;
+ } else if (child.isTemporarilyDetached()) {
+ outMetadata[0] = true;
- // Finish the temporary detach started in addScrapView().
- child.dispatchFinishTemporaryDetach();
- } else {
- // we set isScrap to "true" only if the view is temporarily detached.
- // if the view is fully detached, it is as good as a view created by the
- // adapter
- isScrap[0] = false;
- }
-
+ // Finish the temporary detach started in addScrapView().
+ child.dispatchFinishTemporaryDetach();
}
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 6d7313d..b95aa52 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1407,72 +1407,73 @@
/**
- * Obtain the view and add it to our list of children. The view can be made
- * fresh, converted from an unused view, or used as is if it was in the
- * recycle bin.
+ * Obtains the view and adds it to our list of children. The view can be
+ * made fresh, converted from an unused view, or used as is if it was in
+ * the recycle bin.
*
- * @param position Logical position in the list
- * @param y Top or bottom edge of the view to add
- * @param flow if true, align top edge to y. If false, align bottom edge to
- * y.
- * @param childrenLeft Left edge where children should be positioned
- * @param selected Is this position selected?
- * @param where to add new item in the list
+ * @param position logical position in the list
+ * @param y top or bottom edge of the view to add
+ * @param flow {@code true} to align top edge to y, {@code false} to align
+ * bottom edge to y
+ * @param childrenLeft left edge where children should be positioned
+ * @param selected {@code true} if the position is selected, {@code false}
+ * otherwise
+ * @param where position at which to add new item in the list
* @return View that was added
*/
private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,
boolean selected, int where) {
- View child;
-
if (!mDataChanged) {
// Try to use an existing view for this position
- child = mRecycler.getActiveView(position);
- if (child != null) {
+ final View activeView = mRecycler.getActiveView(position);
+ if (activeView != null) {
// Found it -- we're using an existing child
// This just needs to be positioned
- setupChild(child, position, y, flow, childrenLeft, selected, true, where);
- return child;
+ setupChild(activeView, position, y, flow, childrenLeft, selected, true, where);
+ return activeView;
}
}
// Make a new view for this position, or convert an unused view if
- // possible
- child = obtainView(position, mIsScrap);
+ // possible.
+ final View child = obtainView(position, mIsScrap);
- // This needs to be positioned and measured
+ // This needs to be positioned and measured.
setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0], where);
return child;
}
/**
- * Add a view as a child and make sure it is measured (if necessary) and
+ * Adds a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
- * @param child The view to add
- * @param position The position of the view
- * @param y The y position relative to which this view will be positioned
- * @param flow if true, align top edge to y. If false, align bottom edge
- * to y.
- * @param childrenLeft Left edge where children should be positioned
- * @param selected Is this position selected?
- * @param recycled Has this view been pulled from the recycle bin? If so it
- * does not need to be remeasured.
- * @param where Where to add the item in the list
+ * @param child the view to add
+ * @param position the position of this child
+ * @param y the y position relative to which this view will be positioned
+ * @param flowDown {@code true} to align top edge to y, {@code false} to
+ * align bottom edge to y
+ * @param childrenLeft left edge where children should be positioned
+ * @param selected {@code true} if the position is selected, {@code false}
+ * otherwise
+ * @param isAttachedToWindow {@code true} if the view is already attached
+ * to the window, e.g. whether it was reused, or
+ * {@code false} otherwise
+ * @param where position at which to add new item in the list
*
*/
- private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
- boolean selected, boolean recycled, int where) {
+ private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
+ boolean selected, boolean isAttachedToWindow, int where) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupGridItem");
boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
- final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
- mMotionPosition == position;
+ final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL
+ && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
-
- boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
+ final boolean needToMeasure = !isAttachedToWindow || updateChildSelected
+ || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
// some up...
@@ -1483,13 +1484,9 @@
p.viewType = mAdapter.getItemViewType(position);
p.isEnabled = mAdapter.isEnabled(position);
- if (recycled && !p.forceAdd) {
- attachViewToParent(child, where, p);
- } else {
- p.forceAdd = false;
- addViewInLayout(child, where, p, true);
- }
-
+ // Set up view state before attaching the view, since we may need to
+ // rely on the jumpDrawablesToCurrentState() call that occurs as part
+ // of view attachment.
if (updateChildSelected) {
child.setSelected(isSelected);
if (isSelected) {
@@ -1510,6 +1507,21 @@
}
}
+ if (isAttachedToWindow && !p.forceAdd) {
+ attachViewToParent(child, where, p);
+
+ // If the view isn't attached, or if it's attached but for a different
+ // position, then jump the drawables.
+ if (!isAttachedToWindow
+ || (((AbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
+ } else {
+ p.forceAdd = false;
+ addViewInLayout(child, where, p, true);
+ }
+
if (needToMeasure) {
int childHeightSpec = ViewGroup.getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height);
@@ -1525,7 +1537,7 @@
final int h = child.getMeasuredHeight();
int childLeft;
- final int childTop = flow ? y : y - h;
+ final int childTop = flowDown ? y : y - h;
final int layoutDirection = getLayoutDirection();
final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
@@ -1553,15 +1565,10 @@
child.offsetTopAndBottom(childTop - child.getTop());
}
- if (mCachingStarted) {
+ if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
- if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
- != position) {
- child.jumpDrawablesToCurrentState();
- }
-
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 0e04e30..b8b7c55 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1939,72 +1939,73 @@
}
/**
- * Obtain the view and add it to our list of children. The view can be made
- * fresh, converted from an unused view, or used as is if it was in the
- * recycle bin.
+ * Obtains the view and adds it to our list of children. The view can be
+ * made fresh, converted from an unused view, or used as is if it was in
+ * the recycle bin.
*
- * @param position Logical position in the list
- * @param y Top or bottom edge of the view to add
- * @param flow If flow is true, align top edge to y. If false, align bottom
- * edge to y.
- * @param childrenLeft Left edge where children should be positioned
- * @param selected Is this position selected?
- * @return View that was added
+ * @param position logical position in the list
+ * @param y top or bottom edge of the view to add
+ * @param flow {@code true} to align top edge to y, {@code false} to align
+ * bottom edge to y
+ * @param childrenLeft left edge where children should be positioned
+ * @param selected {@code true} if the position is selected, {@code false}
+ * otherwise
+ * @return the view that was added
*/
private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,
boolean selected) {
- View child;
-
-
if (!mDataChanged) {
- // Try to use an existing view for this position
- child = mRecycler.getActiveView(position);
- if (child != null) {
- // Found it -- we're using an existing child
- // This just needs to be positioned
- setupChild(child, position, y, flow, childrenLeft, selected, true);
-
- return child;
+ // Try to use an existing view for this position.
+ final View activeView = mRecycler.getActiveView(position);
+ if (activeView != null) {
+ // Found it. We're reusing an existing child, so it just needs
+ // to be positioned like a scrap view.
+ setupChild(activeView, position, y, flow, childrenLeft, selected, true);
+ return activeView;
}
}
- // Make a new view for this position, or convert an unused view if possible
- child = obtainView(position, mIsScrap);
+ // Make a new view for this position, or convert an unused view if
+ // possible.
+ final View child = obtainView(position, mIsScrap);
- // This needs to be positioned and measured
+ // This needs to be positioned and measured.
setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]);
return child;
}
/**
- * Add a view as a child and make sure it is measured (if necessary) and
+ * Adds a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
- * @param child The view to add
- * @param position The position of this child
- * @param y The y position relative to which this view will be positioned
- * @param flowDown If true, align top edge to y. If false, align bottom
- * edge to y.
- * @param childrenLeft Left edge where children should be positioned
- * @param selected Is this position selected?
- * @param recycled Has this view been pulled from the recycle bin? If so it
- * does not need to be remeasured.
+ * @param child the view to add
+ * @param position the position of this child
+ * @param y the y position relative to which this view will be positioned
+ * @param flowDown {@code true} to align top edge to y, {@code false} to
+ * align bottom edge to y
+ * @param childrenLeft left edge where children should be positioned
+ * @param selected {@code true} if the position is selected, {@code false}
+ * otherwise
+ * @param isAttachedToWindow {@code true} if the view is already attached
+ * to the window, e.g. whether it was reused, or
+ * {@code false} otherwise
*/
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
- boolean selected, boolean recycled) {
+ boolean selected, boolean isAttachedToWindow) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupListItem");
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
- final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
- mMotionPosition == position;
+ final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL
+ && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
- final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
+ final boolean needToMeasure = !isAttachedToWindow || updateChildSelected
+ || child.isLayoutRequested();
- // Respect layout params that are already in the view. Otherwise make some up...
- // noinspection unchecked
+ // Respect layout params that are already in the view. Otherwise make
+ // some up...
AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
@@ -2012,17 +2013,9 @@
p.viewType = mAdapter.getItemViewType(position);
p.isEnabled = mAdapter.isEnabled(position);
- if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter
- && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
- attachViewToParent(child, flowDown ? -1 : 0, p);
- } else {
- p.forceAdd = false;
- if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
- p.recycledHeaderFooter = true;
- }
- addViewInLayout(child, flowDown ? -1 : 0, p, true);
- }
-
+ // Set up view state before attaching the view, since we may need to
+ // rely on the jumpDrawablesToCurrentState() call that occurs as part
+ // of view attachment.
if (updateChildSelected) {
child.setSelected(isSelected);
}
@@ -2040,6 +2033,25 @@
}
}
+ if ((isAttachedToWindow && !p.forceAdd) || (p.recycledHeaderFooter
+ && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
+ attachViewToParent(child, flowDown ? -1 : 0, p);
+
+ // If the view was previously attached for a different position,
+ // then manually jump the drawables.
+ if (isAttachedToWindow
+ && (((AbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
+ } else {
+ p.forceAdd = false;
+ if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+ p.recycledHeaderFooter = true;
+ }
+ addViewInLayout(child, flowDown ? -1 : 0, p, true);
+ }
+
if (needToMeasure) {
final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
@@ -2073,11 +2085,6 @@
child.setDrawingCacheEnabled(true);
}
- if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
- != position) {
- child.jumpDrawablesToCurrentState();
- }
-
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 31ab26f..831c646 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -26,6 +26,7 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.util.DisplayMetrics;
import com.android.internal.R;
import com.android.internal.util.Preconditions;
@@ -209,11 +210,9 @@
}
private boolean isContentRectWithinBounds() {
- mScreenRect.set(
- 0,
- 0,
- mContext.getResources().getDisplayMetrics().widthPixels,
- mContext.getResources().getDisplayMetrics().heightPixels);
+ DisplayMetrics metrics = mContext.getApplicationContext()
+ .getResources().getDisplayMetrics();
+ mScreenRect.set(0, 0, metrics.widthPixels, metrics.heightPixels);
return intersectsClosed(mContentRectOnScreen, mScreenRect)
&& intersectsClosed(mContentRectOnScreen, mViewRectOnScreen);
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 8b9d503..e84cc27 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -245,7 +245,7 @@
final float y = ev.getY();
mInitialTouchX = x;
mInitialTouchY = mLastTouchY = y;
- mOpenOnClick = isListChildUnderClipped(x, y) && mCollapsibleHeight > 0;
+ mOpenOnClick = isListChildUnderClipped(x, y) && mCollapseOffset > 0;
}
break;
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 6d33de6..178505c 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -20,6 +20,7 @@
android:id="@+id/parentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:gravity="start|top"
android:orientation="vertical">
<include layout="@layout/alert_dialog_title_material" />
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 312553a..3f59b02 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1732,9 +1732,10 @@
Alarm a = alarms.get(j);
if (a.alarmClock != null) {
final int userId = UserHandle.getUserId(a.uid);
+ AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId);
if (DEBUG_ALARM_CLOCK) {
- Log.v(TAG, "Found AlarmClockInfo at " +
+ Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at " +
formatNextAlarm(getContext(), a.alarmClock, userId) +
" for user " + userId);
}
@@ -1742,6 +1743,10 @@
// Alarms and batches are sorted by time, no need to compare times here.
if (nextForUser.get(userId) == null) {
nextForUser.put(userId, a.alarmClock);
+ } else if (a.alarmClock.equals(current)
+ && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) {
+ // same/earlier time and it's the one we cited before, so stick with it
+ nextForUser.put(userId, current);
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 4ead64b..5859d34 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3542,14 +3542,24 @@
final ActivityState prevState = r.state;
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
r.state = ActivityState.FINISHING;
+ final boolean finishingActivityInNonFocusedStack
+ = r.task.stack != mStackSupervisor.getFocusedStack()
+ && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
if (mode == FINISH_IMMEDIATELY
|| (prevState == ActivityState.PAUSED
&& (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
+ || finishingActivityInNonFocusedStack
|| prevState == ActivityState.STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
+
+ if (finishingActivityInNonFocusedStack) {
+ // Finishing activity that was in paused state and it was in not currently focused
+ // stack, need to make something visible in its place.
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ }
if (activityRemoved) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 36207c4..06e5ea2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1049,7 +1049,7 @@
return r;
}
- // Return to the home stack.
+ // Look in other non-focused and non-home stacks.
final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 5b9d139..27d1671 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -68,7 +68,7 @@
private static final int MAX_BROADCAST_TIME = 10*1000;
private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
private static final int MAX_RADIO_WAIT_TIME = 12*1000;
- private static final int MAX_UNCRYPT_WAIT_TIME = 15*60*1000;
+ private static final int MAX_UNCRYPT_WAIT_TIME = 30*60*1000;
// constants for progress bar. the values are roughly estimated based on timeout.
private static final int BROADCAST_STOP_PERCENT = 2;
private static final int ACTIVITY_MANAGER_STOP_PERCENT = 4;