diff options
43 files changed, 753 insertions, 195 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5085b1e..b29035d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2090,8 +2090,15 @@ public final class ActivityThread { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); // We need to keep around the original state, in case - // we need to be created again. - r.state = oldState; + // we need to be created again. But we only do this + // for pre-Honeycomb apps, which always save their state + // when pausing, so we can not have them save their state + // when restarting from a paused state. For HC and later, + // we want to (and can) let the state be saved as the normal + // part of stopping the activity. + if (r.isPreHoneycomb()) { + r.state = oldState; + } if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index d3ba497..5e6b090 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -28,6 +28,7 @@ import android.os.Parcelable; import android.util.AndroidRuntimeException; import android.util.AttributeSet; import android.util.DebugUtils; +import android.util.Log; import android.util.SparseArray; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -108,7 +109,9 @@ final class FragmentState implements Parcelable { mInstance.mRetainInstance = mRetainInstance; mInstance.mDetached = mDetached; mInstance.mFragmentManager = activity.mFragments; - + if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, + "Instantiated fragment " + mInstance); + return mInstance; } diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 7e1daa4..6058bdc 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1074,6 +1074,7 @@ final class FragmentManagerImpl extends FragmentManager { f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1)); mActive.set(f.mIndex, f); } + if (DEBUG) Log.v(TAG, "Allocated fragment index " + f); } void makeInactive(Fragment f) { @@ -1081,7 +1082,7 @@ final class FragmentManagerImpl extends FragmentManager { return; } - if (DEBUG) Log.v(TAG, "Freeing fragment index " + f.mIndex); + if (DEBUG) Log.v(TAG, "Freeing fragment index " + f); mActive.set(f.mIndex, null); if (mAvailIndices == null) { mAvailIndices = new ArrayList<Integer>(); @@ -1493,6 +1494,7 @@ final class FragmentManagerImpl extends FragmentManager { fragments.add(f); f.mRetaining = true; f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; + if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f); } } } diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 01b68d4..ed95ae5 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -38,6 +38,7 @@ import android.util.SparseArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.BaseAdapter; @@ -523,6 +524,12 @@ public class AppWidgetHostView extends FrameLayout { return tv; } + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(AppWidgetHostView.class.getName()); + } + private static class ParcelableSparseArray extends SparseArray<Parcelable> implements Parcelable { public int describeContents() { return 0; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index c791e47..da09a18 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -810,11 +810,17 @@ public class Intent implements Parcelable, Cloneable { * <p> * As a convenience, an Intent of this form can be created with the * {@link #createChooser} function. - * <p>Input: No data should be specified. get*Extra must have + * <p> + * If the target {@link #EXTRA_INTENT} contains {@link ClipData}, you should + * also copy it to this intent along with relevant flags, such as + * {@link #FLAG_GRANT_READ_URI_PERMISSION}. + * <p> + * Input: No data should be specified. get*Extra must have * a {@link #EXTRA_INTENT} field containing the Intent being executed, * and can optionally have a {@link #EXTRA_TITLE} field containing the * title text to display in the chooser. - * <p>Output: Depends on the protocol of {@link #EXTRA_INTENT}. + * <p> + * Output: Depends on the protocol of {@link #EXTRA_INTENT}. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_CHOOSER = "android.intent.action.CHOOSER"; @@ -835,8 +841,17 @@ public class Intent implements Parcelable, Cloneable { if (title != null) { intent.putExtra(EXTRA_TITLE, title); } + + // Migrate any clip data and flags from target. + final ClipData targetClipData = target.getClipData(); + if (targetClipData != null) { + intent.setClipData(targetClipData); + intent.addFlags(target.getFlags() + & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION)); + } return intent; } + /** * Activity Action: Allow the user to select a particular kind of data and * return it. This is different than {@link #ACTION_PICK} in that here we @@ -6587,19 +6602,35 @@ public class Intent implements Parcelable, Cloneable { /** * Migrate any {@link #EXTRA_STREAM} in {@link #ACTION_SEND} and - * {@link #ACTION_SEND_MULTIPLE} to {@link ClipData}. + * {@link #ACTION_SEND_MULTIPLE} to {@link ClipData}. Also inspects nested + * intents in {@link #ACTION_CHOOSER}. * + * @return Whether any contents were migrated. * @hide */ - public void migrateExtraStreamToClipData() { + public boolean migrateExtraStreamToClipData() { // Refuse to touch if extras already parcelled - if (mExtras != null && mExtras.isParcelled()) return; + if (mExtras != null && mExtras.isParcelled()) return false; // Bail when someone already gave us ClipData - if (getClipData() != null) return; + if (getClipData() != null) return false; final String action = getAction(); - if (ACTION_SEND.equals(action)) { + if (ACTION_CHOOSER.equals(action)) { + // Inspect target intent to see if we need to migrate + final Intent target = getParcelableExtra(EXTRA_INTENT); + if (target.migrateExtraStreamToClipData()) { + // Since we migrated in child, we need to promote ClipData and + // flags to ourselves to grant. + setClipData(target.getClipData()); + addFlags(target.getFlags() + & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION)); + return true; + } else { + return false; + } + + } else if (ACTION_SEND.equals(action)) { try { final Uri stream = getParcelableExtra(EXTRA_STREAM); final CharSequence text = getCharSequenceExtra(EXTRA_TEXT); @@ -6610,6 +6641,7 @@ public class Intent implements Parcelable, Cloneable { new ClipData.Item(text, htmlText, null, stream)); setClipData(clipData); addFlags(FLAG_GRANT_READ_URI_PERMISSION); + return true; } } catch (ClassCastException e) { } @@ -6626,14 +6658,14 @@ public class Intent implements Parcelable, Cloneable { if (texts != null) { if (num >= 0 && num != texts.size()) { // Wha...! F- you. - return; + return false; } num = texts.size(); } if (htmlTexts != null) { if (num >= 0 && num != htmlTexts.size()) { // Wha...! F- you. - return; + return false; } num = htmlTexts.size(); } @@ -6648,10 +6680,13 @@ public class Intent implements Parcelable, Cloneable { setClipData(clipData); addFlags(FLAG_GRANT_READ_URI_PERMISSION); + return true; } } catch (ClassCastException e) { } } + + return false; } private static ClipData.Item makeClipItem(ArrayList<Uri> streams, ArrayList<CharSequence> texts, diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index e1f1db2..16f9a18 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -491,20 +491,28 @@ final class AccessibilityInteractionController { if ((direction & View.FOCUS_ACCESSIBILITY) == View.FOCUS_ACCESSIBILITY) { AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider(); if (provider != null) { - next = provider.accessibilityFocusSearch(direction, - virtualDescendantId); - } else if (virtualDescendantId == View.NO_ID) { - View nextView = root.focusSearch(direction); - if (nextView != null) { - // If the focus search reached a node with a provider - // we delegate to the provider to find the next one. - provider = nextView.getAccessibilityNodeProvider(); - if (provider != null) { - next = provider.accessibilityFocusSearch(direction, - virtualDescendantId); - } else { - next = nextView.createAccessibilityNodeInfo(); - } + next = provider.accessibilityFocusSearch(direction, virtualDescendantId); + if (next != null) { + return; + } + } + View nextView = root.focusSearch(direction); + while (nextView != null) { + // If the focus search reached a node with a provider + // we delegate to the provider to find the next one. + // If the provider does not return a virtual view to + // take accessibility focus we try the next view found + // by the focus search algorithm. + provider = nextView.getAccessibilityNodeProvider(); + if (provider != null) { + next = provider.accessibilityFocusSearch(direction, View.NO_ID); + if (next != null) { + break; + } + nextView = nextView.focusSearch(direction); + } else { + next = nextView.createAccessibilityNodeInfo(); + break; } } } else { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 14523d3..a4fcd41 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6027,7 +6027,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return; } if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) { - if (canTakeAccessibilityFocusFromHover()) { + if (canTakeAccessibilityFocusFromHover() || getAccessibilityNodeProvider() != null) { views.add(this); return; } @@ -6156,12 +6156,15 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @hide */ public void clearAccessibilityFocus() { - if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) { - mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED; - ViewRootImpl viewRootImpl = getViewRootImpl(); - if (viewRootImpl != null) { + ViewRootImpl viewRootImpl = getViewRootImpl(); + if (viewRootImpl != null) { + View focusHost = viewRootImpl.getAccessibilityFocusedHost(); + if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) { viewRootImpl.setAccessibilityFocusedHost(null); } + } + if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) { + mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED; invalidate(); sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); notifyAccessibilityStateChanged(); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f86e036..41cd887 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -488,7 +488,9 @@ public final class ViewRootImpl implements ViewParent, mFallbackEventHandler.setView(view); mWindowAttributes.copyFrom(attrs); attrs = mWindowAttributes; - + + setAccessibilityFocusedHost(null); + if (view instanceof RootViewSurfaceTaker) { mSurfaceHolderCallback = ((RootViewSurfaceTaker)view).willYouTakeTheSurface(); @@ -556,6 +558,7 @@ public final class ViewRootImpl implements ViewParent, mInputChannel = null; mFallbackEventHandler.setView(null); unscheduleTraversals(); + setAccessibilityFocusedHost(null); throw new RuntimeException("Adding window failed", e); } finally { if (restore) { @@ -575,6 +578,7 @@ public final class ViewRootImpl implements ViewParent, mAdded = false; mFallbackEventHandler.setView(null); unscheduleTraversals(); + setAccessibilityFocusedHost(null); switch (res) { case WindowManagerImpl.ADD_BAD_APP_TOKEN: case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN: @@ -635,8 +639,6 @@ public final class ViewRootImpl implements ViewParent, if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } - - setAccessibilityFocusedHost(null); } } } @@ -1853,18 +1855,15 @@ public final class ViewRootImpl implements ViewParent, performDraw(); } } else { - // End any pending transitions on this non-visible window - if (mPendingTransitions != null && mPendingTransitions.size() > 0) { + if (viewVisibility == View.VISIBLE) { + // Try again + scheduleTraversals(); + } else if (mPendingTransitions != null && mPendingTransitions.size() > 0) { for (int i = 0; i < mPendingTransitions.size(); ++i) { mPendingTransitions.get(i).endChangingAnimations(); } mPendingTransitions.clear(); } - - if (viewVisibility == View.VISIBLE) { - // Try again - scheduleTraversals(); - } } } @@ -2543,11 +2542,51 @@ public final class ViewRootImpl implements ViewParent, } void setAccessibilityFocusedHost(View host) { - if (mAccessibilityFocusedHost != null && mAccessibilityFocusedVirtualView == null) { + // If we have a virtual view with accessibility focus we need + // to clear the focus and invalidate the virtual view bounds. + if (mAccessibilityFocusedVirtualView != null) { + + AccessibilityNodeInfo focusNode = mAccessibilityFocusedVirtualView; + View focusHost = mAccessibilityFocusedHost; + focusHost.clearAccessibilityFocusNoCallbacks(); + + // Wipe the state of the current accessibility focus since + // the call into the provider to clear accessibility focus + // will fire an accessibility event which will end up calling + // this method and we want to have clean state when this + // invocation happens. + mAccessibilityFocusedHost = null; + mAccessibilityFocusedVirtualView = null; + + AccessibilityNodeProvider provider = focusHost.getAccessibilityNodeProvider(); + if (provider != null) { + // Invalidate the area of the cleared accessibility focus. + focusNode.getBoundsInParent(mTempRect); + focusHost.invalidate(mTempRect); + // Clear accessibility focus in the virtual node. + final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId( + focusNode.getSourceNodeId()); + provider.performAction(virtualNodeId, + AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null); + } + } + if (mAccessibilityFocusedHost != null) { + // Clear accessibility focus in the view. mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks(); } + + // Set the new focus host. mAccessibilityFocusedHost = host; - mAccessibilityFocusedVirtualView = null; + + // If the host has a provide find the virtual descendant that has focus. + if (mAccessibilityFocusedHost != null) { + AccessibilityNodeProvider provider = + mAccessibilityFocusedHost.getAccessibilityNodeProvider(); + if (provider != null) { + mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID); + return; + } + } } public void requestChildFocus(View child, View focused) { @@ -2633,6 +2672,8 @@ public final class ViewRootImpl implements ViewParent, destroyHardwareRenderer(); + setAccessibilityFocusedHost(null); + mView = null; mAttachInfo.mRootView = null; mAttachInfo.mSurface = null; @@ -4608,6 +4649,31 @@ public final class ViewRootImpl implements ViewParent, if (mView == null) { return false; } + // Watch for accessibility focus change events from virtual nodes + // to keep track of accessibility focus being on a virtual node. + final int eventType = event.getEventType(); + switch (eventType) { + case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { + final long sourceId = event.getSourceNodeId(); + // If the event is not from a virtual node we are not interested. + final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId); + if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) { + break; + } + final int realViewId = AccessibilityNodeInfo.getAccessibilityViewId(sourceId); + View focusHost = mView.findViewByAccessibilityId(realViewId); + setAccessibilityFocusedHost(focusHost); + } break; + case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: { + final long sourceId = event.getSourceNodeId(); + // If the event is not from a virtual node we are not interested. + final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId); + if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) { + break; + } + setAccessibilityFocusedHost(null); + } break; + } mAccessibilityManager.sendAccessibilityEvent(event); return true; } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 8e529b9..ce67718 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -7986,7 +7986,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } nativeSetTextSelection(mNativeClass, data.mSelectTextPtr); - if (data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR) { + if ((data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR) + || (!mSelectingText + && data.mSelectionReason != TextSelectionData.REASON_SELECT_WORD)) { selectionDone(); mShowTextSelectionExtra = true; invalidate(); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 4adfd6a..7aa9a0b 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -22,7 +22,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.graphics.Point; import android.graphics.Rect; -import android.graphics.Region; import android.media.MediaFile; import android.net.ProxyProperties; import android.net.Uri; @@ -864,6 +863,7 @@ public final class WebViewCore { static class TextSelectionData { static final int REASON_UNKNOWN = 0; static final int REASON_ACCESSIBILITY_INJECTOR = 1; + static final int REASON_SELECT_WORD = 2; public TextSelectionData(int start, int end, int selectTextPtr) { mStart = start; mEnd = end; @@ -1718,12 +1718,16 @@ public final class WebViewCore { break; } case SELECT_WORD_AT: { + mTextSelectionChangeReason + = TextSelectionData.REASON_SELECT_WORD; int x = msg.arg1; int y = msg.arg2; if (!nativeSelectWordAt(mNativeClass, x, y)) { mWebViewClassic.mPrivateHandler.obtainMessage(WebViewClassic.SHOW_CARET_HANDLE) .sendToTarget(); } + mTextSelectionChangeReason + = TextSelectionData.REASON_UNKNOWN; break; } case SELECT_ALL: diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index ab9d370..04c8cdc 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1480,6 +1480,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { if (getLastVisiblePosition() < getCount() - 1) { @@ -1496,7 +1499,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } return false; } - return super.performAccessibilityAction(action, arguments); + return false; } /** diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java index c6104bc..fe6c4f5 100644 --- a/core/java/android/widget/ActivityChooserModel.java +++ b/core/java/android/widget/ActivityChooserModel.java @@ -765,16 +765,6 @@ public class ActivityChooserModel extends DataSetObservable { } /** - * Gets whether the given observer is already registered. - * - * @param observer The observer. - * @return True if already registered. - */ - public boolean isRegisteredObserver(DataSetObserver observer) { - return mObservers.contains(observer); - } - - /** * Represents a record in the history. */ public final static class HistoricalRecord { diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 0c0bb1e..be6b4e2 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -20,10 +20,8 @@ import com.android.internal.R; import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.DataSetObserver; @@ -176,11 +174,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod private int mDefaultActionButtonContentDescription; /** - * Whether this view has a default activity affordance. - */ - private boolean mHasDefaultActivity; - - /** * Create a new instance. * * @param context The application environment. @@ -252,8 +245,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod Resources resources = context.getResources(); mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2, resources.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth)); - - updateHasDefaultActivity(); } /** @@ -267,21 +258,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } } - @Override - protected void onConfigurationChanged(Configuration newConfig) { - Configuration oldConfig = mContext.getResources().getConfiguration(); - final int changed = oldConfig.diff(newConfig); - if ((changed & ActivityInfo.CONFIG_SCREEN_SIZE) != 0 - || (changed & ActivityInfo.CONFIG_ORIENTATION) != 0) { - updateHasDefaultActivity(); - } - } - - private void updateHasDefaultActivity() { - mHasDefaultActivity = mContext.getResources().getBoolean( - R.bool.activity_chooser_view_has_default_activity); - } - /** * Sets the background for the button that expands the activity * overflow list. @@ -407,8 +383,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod protected void onAttachedToWindow() { super.onAttachedToWindow(); ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null - && !dataModel.isRegisteredObserver(mModelDataSetOberver)) { + if (dataModel != null) { dataModel.registerObserver(mModelDataSetOberver); } mIsAttachedToWindow = true; @@ -418,8 +393,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod protected void onDetachedFromWindow() { super.onDetachedFromWindow(); ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null - && dataModel.isRegisteredObserver(mModelDataSetOberver)) { + if (dataModel != null) { dataModel.unregisterObserver(mModelDataSetOberver); } ViewTreeObserver viewTreeObserver = getViewTreeObserver(); @@ -522,7 +496,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod // Default activity button. final int activityCount = mAdapter.getActivityCount(); final int historySize = mAdapter.getHistorySize(); - if (mHasDefaultActivity && activityCount > 0 && historySize > 0) { + if (activityCount > 0 && historySize > 0) { mDefaultActivityButton.setVisibility(VISIBLE); ResolveInfo activity = mAdapter.getDefaultActivity(); PackageManager packageManager = mContext.getPackageManager(); @@ -538,9 +512,9 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } // Activity chooser content. if (mDefaultActivityButton.getVisibility() == VISIBLE) { - mActivityChooserContent.setBackground(mActivityChooserContentBackground); + mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground); } else { - mActivityChooserContent.setBackground(null); + mActivityChooserContent.setBackgroundDrawable(null); } } @@ -603,7 +577,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod // OnLongClickListener#onLongClick @Override public boolean onLongClick(View view) { - if (mHasDefaultActivity && view == mDefaultActivityButton) { + if (view == mDefaultActivityButton) { if (mAdapter.getCount() > 0) { mIsSelectingDefaultActivity = true; showPopupUnchecked(mInitialActivityCount); @@ -656,16 +630,14 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod public void setDataModel(ActivityChooserModel dataModel) { ActivityChooserModel oldDataModel = mAdapter.getDataModel(); - if (oldDataModel != null) { + if (oldDataModel != null && isShown()) { oldDataModel.unregisterObserver(mModelDataSetOberver); } mDataModel = dataModel; - if (dataModel != null) { + if (dataModel != null && isShown()) { dataModel.registerObserver(mModelDataSetOberver); - notifyDataSetChanged(); - } else { - notifyDataSetInvalidated(); } + notifyDataSetChanged(); } @Override diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index 03fdc39..b2c8164 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -20,6 +20,7 @@ import android.annotation.Widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; +import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.ContextMenu.ContextMenuInfo; @@ -1367,6 +1368,35 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(Gallery.class.getName()); + info.setScrollable(mItemCount > 1); + if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (mItemCount > 0 && mSelectedPosition > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + } + + @Override + public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } + switch (action) { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) { + final int currentChildIndex = mSelectedPosition - mFirstPosition; + return scrollToChild(currentChildIndex + 1); + } + } return false; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (mItemCount > 0 && mSelectedPosition > 0) { + final int currentChildIndex = mSelectedPosition - mFirstPosition; + return scrollToChild(currentChildIndex - 1); + } + } return false; + } + return false; } /** diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index ffabd1d..f889cb7 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -739,6 +739,9 @@ public class HorizontalScrollView extends FrameLayout { @Override public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { final int viewportWidth = getWidth() - mPaddingLeft - mPaddingRight; @@ -757,7 +760,7 @@ public class HorizontalScrollView extends FrameLayout { } } return false; } - return super.performAccessibilityAction(action, arguments); + return false; } @Override diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 7c809b3..b825e1b 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -950,6 +950,8 @@ public class NumberPicker extends LinearLayout { provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); mLastHoveredChildVirtualViewId = hoveredVirtualViewId; + provider.performAction(hoveredVirtualViewId, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); } break; case MotionEvent.ACTION_HOVER_MOVE: { if (mLastHoveredChildVirtualViewId != hoveredVirtualViewId @@ -960,6 +962,8 @@ public class NumberPicker extends LinearLayout { provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); mLastHoveredChildVirtualViewId = hoveredVirtualViewId; + provider.performAction(hoveredVirtualViewId, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); } } break; case MotionEvent.ACTION_HOVER_EXIT: { @@ -1413,9 +1417,16 @@ public class NumberPicker extends LinearLayout { } @Override - public void sendAccessibilityEvent(int eventType) { - // Do not send accessibility events - we want the user to - // perceive this widget as several controls rather as a whole. + public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { + // We do not want the real descendant to be considered focus search + // since it is managed by the accessibility node provider. + if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) { + if (canTakeAccessibilityFocusFromHover() || getAccessibilityNodeProvider() != null) { + views.add(this); + return; + } + } + super.addFocusables(views, direction, focusableMode); } @Override @@ -2072,7 +2083,12 @@ public class NumberPicker extends LinearLayout { } } + /** + * Class for managing virtual view tree rooted at this picker. + */ class AccessibilityNodeProviderImpl extends AccessibilityNodeProvider { + private static final int UNDEFINED = Integer.MIN_VALUE; + private static final int VIRTUAL_VIEW_ID_INCREMENT = 1; private static final int VIRTUAL_VIEW_ID_INPUT = 2; @@ -2083,6 +2099,8 @@ public class NumberPicker extends LinearLayout { private final int[] mTempArray = new int[2]; + private int mAccessibilityFocusedView = UNDEFINED; + @Override public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { switch (virtualViewId) { @@ -2137,6 +2155,37 @@ public class NumberPicker extends LinearLayout { @Override public boolean performAction(int virtualViewId, int action, Bundle arguments) { switch (virtualViewId) { + case View.NO_ID: { + switch (action) { + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + requestAccessibilityFocus(); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + clearAccessibilityFocus(); + return true; + } + return false; + } + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (getWrapSelectorWheel() || getValue() < getMaxValue()) { + changeValueByOne(true); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (getWrapSelectorWheel() || getValue() > getMinValue()) { + changeValueByOne(false); + return true; + } + } return false; + } + } break; case VIRTUAL_VIEW_ID_INPUT: { switch (action) { case AccessibilityNodeInfo.ACTION_FOCUS: { @@ -2149,25 +2198,182 @@ public class NumberPicker extends LinearLayout { mInputText.clearFocus(); return true; } - } break; + return false; + } + case AccessibilityNodeInfo.ACTION_CLICK: { + showSoftInput(); + return true; + } + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + mInputText.invalidate(); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + mInputText.invalidate(); + return true; + } + } return false; + default: { + return mInputText.performAccessibilityAction(action, arguments); + } } - } break; + } return false; + case VIRTUAL_VIEW_ID_INCREMENT: { + switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: { + NumberPicker.this.changeValueByOne(true); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + } return true; + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + invalidate(0, mBottomSelectionDividerBottom, mRight, mBottom); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + invalidate(0, mBottomSelectionDividerBottom, mRight, mBottom); + return true; + } + } return false; + } + } return false; + case VIRTUAL_VIEW_ID_DECREMENT: { + switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: { + final boolean increment = (virtualViewId == VIRTUAL_VIEW_ID_INCREMENT); + NumberPicker.this.changeValueByOne(increment); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + } return true; + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + invalidate(0, 0, mRight, mTopSelectionDividerTop); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + invalidate(0, 0, mRight, mTopSelectionDividerTop); + return true; + } + } return false; + } + } return false; } return super.performAction(virtualViewId, action, arguments); } + @Override + public AccessibilityNodeInfo findAccessibilityFocus(int virtualViewId) { + return createAccessibilityNodeInfo(mAccessibilityFocusedView); + } + + @Override + public AccessibilityNodeInfo accessibilityFocusSearch(int direction, int virtualViewId) { + switch (direction) { + case View.ACCESSIBILITY_FOCUS_DOWN: + case View.ACCESSIBILITY_FOCUS_FORWARD: { + switch (mAccessibilityFocusedView) { + case UNDEFINED: { + return createAccessibilityNodeInfo(View.NO_ID); + } + case View.NO_ID: { + if (hasVirtualDecrementButton()) { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_DECREMENT); + } + } + //$FALL-THROUGH$ + case VIRTUAL_VIEW_ID_DECREMENT: { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT); + } + case VIRTUAL_VIEW_ID_INPUT: { + if (hasVirtualIncrementButton()) { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INCREMENT); + } + } + //$FALL-THROUGH$ + case VIRTUAL_VIEW_ID_INCREMENT: { + View nextFocus = NumberPicker.this.focusSearch(direction); + if (nextFocus != null) { + return nextFocus.createAccessibilityNodeInfo(); + } + return null; + } + } + } break; + case View.ACCESSIBILITY_FOCUS_UP: + case View.ACCESSIBILITY_FOCUS_BACKWARD: { + switch (mAccessibilityFocusedView) { + case UNDEFINED: { + return createAccessibilityNodeInfo(View.NO_ID); + } + case View.NO_ID: { + if (hasVirtualIncrementButton()) { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INCREMENT); + } + } + //$FALL-THROUGH$ + case VIRTUAL_VIEW_ID_INCREMENT: { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT); + } + case VIRTUAL_VIEW_ID_INPUT: { + if (hasVirtualDecrementButton()) { + return createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_DECREMENT); + } + } + //$FALL-THROUGH$ + case VIRTUAL_VIEW_ID_DECREMENT: { + View nextFocus = NumberPicker.this.focusSearch(direction); + if (nextFocus != null) { + return nextFocus.createAccessibilityNodeInfo(); + } + return null; + } + } + } break; + } + return null; + } + public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) { switch (virtualViewId) { case VIRTUAL_VIEW_ID_DECREMENT: { - sendAccessibilityEventForVirtualButton(virtualViewId, eventType, - getVirtualDecrementButtonText()); + if (hasVirtualDecrementButton()) { + sendAccessibilityEventForVirtualButton(virtualViewId, eventType, + getVirtualDecrementButtonText()); + } } break; case VIRTUAL_VIEW_ID_INPUT: { sendAccessibilityEventForVirtualText(eventType); } break; case VIRTUAL_VIEW_ID_INCREMENT: { - sendAccessibilityEventForVirtualButton(virtualViewId, eventType, - getVirtualIncrementButtonText()); + if (hasVirtualIncrementButton()) { + sendAccessibilityEventForVirtualButton(virtualViewId, eventType, + getVirtualIncrementButtonText()); + } } break; } } @@ -2227,8 +2433,13 @@ public class NumberPicker extends LinearLayout { private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText() { AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo(); - info.setLongClickable(true); info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); + if (mAccessibilityFocusedView != VIRTUAL_VIEW_ID_INPUT) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == VIRTUAL_VIEW_ID_INPUT) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } return info; } @@ -2252,6 +2463,15 @@ public class NumberPicker extends LinearLayout { getLocationOnScreen(locationOnScreen); boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]); info.setBoundsInScreen(boundsInScreen); + + if (mAccessibilityFocusedView != virtualViewId) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == virtualViewId) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } + info.addAction(AccessibilityNodeInfo.ACTION_CLICK); + return info; } @@ -2261,9 +2481,15 @@ public class NumberPicker extends LinearLayout { info.setClassName(NumberPicker.class.getName()); info.setPackageName(mContext.getPackageName()); info.setSource(NumberPicker.this); - info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_DECREMENT); + + if (hasVirtualDecrementButton()) { + info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_DECREMENT); + } info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); - info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT); + if (hasVirtualIncrementButton()) { + info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT); + } + info.setParent((View) getParent()); info.setEnabled(NumberPicker.this.isEnabled()); info.setScrollable(true); @@ -2276,9 +2502,31 @@ public class NumberPicker extends LinearLayout { getLocationOnScreen(locationOnScreen); boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]); info.setBoundsInScreen(boundsInScreen); + + if (mAccessibilityFocusedView != View.NO_ID) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == View.NO_ID) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } + if (getWrapSelectorWheel() || getValue() < getMaxValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (getWrapSelectorWheel() || getValue() > getMinValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + return info; } + private boolean hasVirtualDecrementButton() { + return getWrapSelectorWheel() || getValue() > getMinValue(); + } + + private boolean hasVirtualIncrementButton() { + return getWrapSelectorWheel() || getValue() < getMaxValue(); + } + private String getVirtualDecrementButtonText() { int value = mValue - 1; if (mWrapSelectorWheel) { diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index b398ce4..a499743 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -742,6 +742,9 @@ public class ScrollView extends FrameLayout { @Override public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop; @@ -760,7 +763,7 @@ public class ScrollView extends FrameLayout { } } return false; } - return super.performAccessibilityAction(action, arguments); + return false; } @Override diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java index 21840ca..4045497 100644 --- a/core/java/android/widget/ShareActionProvider.java +++ b/core/java/android/widget/ShareActionProvider.java @@ -44,7 +44,6 @@ import com.android.internal.R; * <code> * // In Activity#onCreateOptionsMenu * public boolean onCreateOptionsMenu(Menu menu) { - * getManuInflater().inflate(R.menu.my_menu, menu); * // Get the menu item. * MenuItem menuItem = menu.findItem(R.id.my_menu_item); * // Get the provider and hold onto it to set/change the share intent. @@ -246,7 +245,7 @@ public class ShareActionProvider extends ActionProvider { * call {@link android.app.Activity#invalidateOptionsMenu()} to recreate the * action view. You should <strong>not</strong> call * {@link android.app.Activity#invalidateOptionsMenu()} from - * {@link android.app.Activity#onCreateOptionsMenu(Menu)}. + * {@link android.app.Activity#onCreateOptionsMenu(Menu)}." * <p> * <code> * private void doShare(Intent intent) { diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 22df3bc..dd0915b 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -32,6 +32,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.TableMaskFilter; +import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.InputDevice; @@ -1228,6 +1229,35 @@ public class StackView extends AdapterViewAnimator { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(StackView.class.getName()); + info.setScrollable(getChildCount() > 1); + if (getDisplayedChild() < getChildCount() - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (getDisplayedChild() > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + } + + @Override + public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } + switch (action) { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (getDisplayedChild() < getChildCount() - 1) { + showNext(); + return true; + } + } return false; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (getDisplayedChild() > 0) { + showPrevious(); + return true; + } + } return false; + } + return false; } class LayoutParams extends ViewGroup.LayoutParams { diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java index 89f2187..e9db9d9 100644 --- a/core/java/com/android/internal/app/PlatLogoActivity.java +++ b/core/java/com/android/internal/app/PlatLogoActivity.java @@ -19,13 +19,17 @@ package com.android.internal.app; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; +import android.graphics.Typeface; +import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.Vibrator; -import android.view.MotionEvent; +import android.util.DisplayMetrics; +import android.view.Gravity; import android.view.View; -import android.view.ViewConfiguration; +import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; import android.widget.Toast; public class PlatLogoActivity extends Activity { @@ -34,15 +38,65 @@ public class PlatLogoActivity extends Activity { int mCount; final Handler mHandler = new Handler(); + private View makeView() { + DisplayMetrics metrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(metrics); + + LinearLayout view = new LinearLayout(this); + view.setOrientation(LinearLayout.VERTICAL); + view.setLayoutParams( + new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + final int p = (int)(8 * metrics.density); + view.setPadding(p, p, p, p); + + Typeface light = Typeface.create("sans-serif-light", Typeface.NORMAL); + Typeface normal = Typeface.create("sans-serif", Typeface.BOLD); + + final float size = 14 * metrics.density; + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER_HORIZONTAL; + lp.bottomMargin = (int) (-4*metrics.density); + + TextView tv = new TextView(this); + if (light != null) tv.setTypeface(light); + tv.setTextSize(1.25f*size); + tv.setTextColor(0xFFFFFFFF); + tv.setShadowLayer(4*metrics.density, 0, 2*metrics.density, 0x66000000); + tv.setText("Android " + Build.VERSION.RELEASE); + view.addView(tv, lp); + + tv = new TextView(this); + if (normal != null) tv.setTypeface(normal); + tv.setTextSize(size); + tv.setTextColor(0xFFFFFFFF); + tv.setShadowLayer(4*metrics.density, 0, 2*metrics.density, 0x66000000); + tv.setText("JELLY BEAN"); + view.addView(tv, lp); + + return view; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mToast = Toast.makeText(this, "Android X.X: Jelly Bean", Toast.LENGTH_SHORT); + mToast = Toast.makeText(this, "", Toast.LENGTH_LONG); + mToast.setView(makeView()); + + DisplayMetrics metrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(metrics); mContent = new ImageView(this); mContent.setImageResource(com.android.internal.R.drawable.platlogo); mContent.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + + final int p = (int)(32 * metrics.density); + mContent.setPadding(p, p, p, p); mContent.setOnClickListener(new View.OnClickListener() { @Override diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index d8ec656..e3d11f2 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -357,19 +357,26 @@ static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject claz static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jintArray colors, jint offset, jint stride, jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, SkPaint* paint) { - SkBitmap bitmap; - SkBitmap::Config config = hasAlpha ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config; - bitmap.setConfig(config, width, height); + SkBitmap* bitmap = new SkBitmap; + bitmap->setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config, + width, height); - if (!bitmap.allocPixels()) { + if (!bitmap->allocPixels()) { + delete bitmap; return; } - if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, bitmap)) { + if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) { + delete bitmap; return; } - renderer->drawBitmapData(&bitmap, left, top, paint); + renderer->drawBitmapData(bitmap, left, top, paint); + + // If the renderer is a deferred renderer it will own the bitmap + if (!renderer->isDeferred()) { + delete bitmap; + } } static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml index 91e66bc..7b91022 100644 --- a/core/res/res/layout/time_picker_holo.xml +++ b/core/res/res/layout/time_picker_holo.xml @@ -44,6 +44,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" + android:importantForAccessibility="no" /> <!-- minute --> diff --git a/core/res/res/raw/accessibility_gestures.bin b/core/res/res/raw/accessibility_gestures.bin Binary files differindex f7e6615..96fa1ec 100644 --- a/core/res/res/raw/accessibility_gestures.bin +++ b/core/res/res/raw/accessibility_gestures.bin diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml index c5727ea..d26666e 100644 --- a/core/res/res/values-sw600dp/dimens.xml +++ b/core/res/res/values-sw600dp/dimens.xml @@ -51,12 +51,6 @@ <!-- Size of status line font in LockScreen. --> <dimen name="keyguard_pattern_unlock_status_line_font_size">14sp</dimen> - <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. --> - <dimen name="default_app_widget_padding_left">12dp</dimen> - <dimen name="default_app_widget_padding_top">4dp</dimen> - <dimen name="default_app_widget_padding_right">12dp</dimen> - <dimen name="default_app_widget_padding_bottom">20dp</dimen> - <!-- Minimum width for an action button in the menu area of an action bar --> <dimen name="action_button_min_width">64dip</dimen> diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml index 34c7ea3..fc336ae 100644 --- a/core/res/res/values-sw720dp/dimens.xml +++ b/core/res/res/values-sw720dp/dimens.xml @@ -50,6 +50,12 @@ <dimen name="preference_screen_header_padding_side">0dip</dimen> <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay --> + <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. --> + <dimen name="default_app_widget_padding_left">12dp</dimen> + <dimen name="default_app_widget_padding_top">4dp</dimen> + <dimen name="default_app_widget_padding_right">12dp</dimen> + <dimen name="default_app_widget_padding_bottom">20dp</dimen> + <!-- Preference fragment padding, sides --> <dimen name="preference_fragment_padding_side">32dp</dimen> <!-- Padding to the left of the preference panel breadcrumb --> diff --git a/core/res/res/values-w500dp/bools.xml b/core/res/res/values-w500dp/bools.xml deleted file mode 100644 index f53fd39..0000000 --- a/core/res/res/values-w500dp/bools.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources> - <bool name="activity_chooser_view_has_default_activity">true</bool> -</resources>
\ No newline at end of file diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml index 6910ebe..f9762b1 100644 --- a/core/res/res/values/bools.xml +++ b/core/res/res/values/bools.xml @@ -22,5 +22,4 @@ <bool name="show_ongoing_ime_switcher">true</bool> <bool name="action_bar_expanded_action_views_exclusive">true</bool> <bool name="target_honeycomb_needs_options_menu">true</bool> - <bool name="activity_chooser_view_has_default_activity">false</bool> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 48038dd..a24e345 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1380,7 +1380,6 @@ <java-symbol type="bool" name="config_wifi_dual_band_support" /> <java-symbol type="bool" name="config_wimaxEnabled" /> <java-symbol type="bool" name="show_ongoing_ime_switcher" /> - <java-symbol type="bool" name="activity_chooser_view_has_default_activity" /> <java-symbol type="color" name="config_defaultNotificationColor" /> <java-symbol type="drawable" name="ic_notification_ime_default" /> <java-symbol type="drawable" name="stat_notify_car_mode" /> diff --git a/core/tests/utillib/src/android/test/BandwidthTestCase.java b/core/tests/utillib/src/android/test/BandwidthTestCase.java index 4f95f77..c03d9b3 100644 --- a/core/tests/utillib/src/android/test/BandwidthTestCase.java +++ b/core/tests/utillib/src/android/test/BandwidthTestCase.java @@ -18,6 +18,7 @@ package android.test; import android.net.NetworkStats; import android.net.TrafficStats; import android.os.Bundle; +import android.util.Log; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -29,6 +30,7 @@ import java.lang.reflect.Modifier; * as an {@link InstrumentationTestCase} */ public class BandwidthTestCase extends InstrumentationTestCase { + private static final String TAG = "BandwidthTestCase"; private static final String REPORT_KEY_PACKETS_SENT = "txPackets"; private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets"; private static final String REPORT_KEY_BYTES_SENT = "txBytes"; @@ -86,11 +88,26 @@ public class BandwidthTestCase extends InstrumentationTestCase { } } else if (method.isAnnotationPresent(BandwidthTest.class) || testClass.isAnnotationPresent(BandwidthTest.class)) { - TrafficStats.startDataProfiling(null); + /** + * If bandwidth profiling fails for whatever reason the test + * should be allow to execute to its completion. + * Typically bandwidth profiling would fail when a lower level + * component is missing, such as the kernel module, for a newly + * introduced hardware. + */ + try{ + TrafficStats.startDataProfiling(null); + } catch(IllegalStateException isx){ + Log.w(TAG, "Failed to start bandwidth profiling"); + } runMethod(method, 1, false); - NetworkStats stats = TrafficStats.stopDataProfiling(null); - NetworkStats.Entry entry = stats.getTotal(null); - getInstrumentation().sendStatus(2, getBandwidthStats(entry)); + try{ + NetworkStats stats = TrafficStats.stopDataProfiling(null); + NetworkStats.Entry entry = stats.getTotal(null); + getInstrumentation().sendStatus(2, getBandwidthStats(entry)); + } catch (IllegalStateException isx){ + Log.w(TAG, "Failed to collect bandwidth stats"); + } } else { runMethod(method, runCount, isRepetitive); } diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index d2a6a7a..a5f653a 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -162,6 +162,13 @@ void DisplayList::clearResources() { } mBitmapResources.clear(); + for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { + SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); + caches.resourceCache.decrementRefcount(bitmap); + caches.resourceCache.destructor(bitmap); + } + mOwnedBitmapResources.clear(); + for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); } @@ -217,44 +224,51 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde Caches& caches = Caches::getInstance(); - const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources(); + const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources(); for (size_t i = 0; i < bitmapResources.size(); i++) { SkBitmap* resource = bitmapResources.itemAt(i); mBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); } - const Vector<SkiaColorFilter*> &filterResources = recorder.getFilterResources(); + const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources(); + for (size_t i = 0; i < ownedBitmapResources.size(); i++) { + SkBitmap* resource = ownedBitmapResources.itemAt(i); + mOwnedBitmapResources.add(resource); + caches.resourceCache.incrementRefcount(resource); + } + + const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources(); for (size_t i = 0; i < filterResources.size(); i++) { SkiaColorFilter* resource = filterResources.itemAt(i); mFilterResources.add(resource); caches.resourceCache.incrementRefcount(resource); } - const Vector<SkiaShader*> &shaders = recorder.getShaders(); + const Vector<SkiaShader*>& shaders = recorder.getShaders(); for (size_t i = 0; i < shaders.size(); i++) { SkiaShader* resource = shaders.itemAt(i); mShaders.add(resource); caches.resourceCache.incrementRefcount(resource); } - const Vector<SkPaint*> &paints = recorder.getPaints(); + const Vector<SkPaint*>& paints = recorder.getPaints(); for (size_t i = 0; i < paints.size(); i++) { mPaints.add(paints.itemAt(i)); } - const Vector<SkPath*> &paths = recorder.getPaths(); + const Vector<SkPath*>& paths = recorder.getPaths(); for (size_t i = 0; i < paths.size(); i++) { mPaths.add(paths.itemAt(i)); } - const SortedVector<SkPath*> &sourcePaths = recorder.getSourcePaths(); + const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); for (size_t i = 0; i < sourcePaths.size(); i++) { mSourcePaths.add(sourcePaths.itemAt(i)); caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i)); } - const Vector<SkMatrix*> &matrices = recorder.getMatrices(); + const Vector<SkMatrix*>& matrices = recorder.getMatrices(); for (size_t i = 0; i < matrices.size(); i++) { mMatrices.add(matrices.itemAt(i)); } @@ -1036,10 +1050,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, x, y, paint); - if (bitmap) { - renderer.drawBitmap(bitmap, x, y, paint); - delete bitmap; - } + renderer.drawBitmap(bitmap, x, y, paint); } break; case DrawBitmapMesh: { @@ -1295,6 +1306,12 @@ void DisplayListRenderer::reset() { } mBitmapResources.clear(); + for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { + SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); + caches.resourceCache.decrementRefcount(bitmap); + } + mOwnedBitmapResources.clear(); + for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); } @@ -1336,6 +1353,10 @@ DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { return displayList; } +bool DisplayListRenderer::isDeferred() { + return true; +} + void DisplayListRenderer::setViewport(int width, int height) { mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2f74f5b..93b065d 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -398,7 +398,6 @@ public: private: void init(); - void initProperties(); void clearResources(); @@ -424,16 +423,7 @@ private: } SkBitmap* getBitmapData() { - SkBitmap* bitmap = new SkBitmap; - bitmap->setConfig((SkBitmap::Config) getInt(), getInt(), getInt()); - if (!bitmap->allocPixels()) { - delete bitmap; - return NULL; - } - - bitmap->setPixels((void*) mReader.skip(bitmap->height() * bitmap->rowBytes())); - - return bitmap; + return (SkBitmap*) getInt(); } SkiaShader* getShader() { @@ -497,6 +487,7 @@ private: } Vector<SkBitmap*> mBitmapResources; + Vector<SkBitmap*> mOwnedBitmapResources; Vector<SkiaColorFilter*> mFilterResources; Vector<SkPaint*> mPaints; @@ -552,6 +543,8 @@ public: ANDROID_API DisplayList* getDisplayList(DisplayList* displayList); + virtual bool isDeferred(); + virtual void setViewport(int width, int height); virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); virtual void finish(); @@ -634,6 +627,10 @@ public: return mBitmapResources; } + const Vector<SkBitmap*>& getOwnedBitmapResources() const { + return mOwnedBitmapResources; + } + const Vector<SkiaColorFilter*>& getFilterResources() const { return mFilterResources; } @@ -719,17 +716,6 @@ private: mWriter.write(values, count * sizeof(int32_t)); } - void addBitmapData(SkBitmap* bitmap) { - mWriter.writeInt(bitmap->config()); - mWriter.writeInt(bitmap->width()); - mWriter.writeInt(bitmap->height()); - - SkAutoLockPixels alp(*bitmap); - void* src = bitmap->getPixels(); - - mWriter.write(src, bitmap->rowBytes() * bitmap->height()); - } - void addUInts(const uint32_t* values, int8_t count) { mWriter.writeInt(count); mWriter.write(values, count * sizeof(uint32_t)); @@ -825,6 +811,12 @@ private: Caches::getInstance().resourceCache.incrementRefcount(bitmap); } + void addBitmapData(SkBitmap* bitmap) { + addInt((int) bitmap); + mOwnedBitmapResources.add(bitmap); + Caches::getInstance().resourceCache.incrementRefcount(bitmap); + } + inline void addShader(SkiaShader* shader) { if (!shader) { addInt((int) NULL); @@ -851,6 +843,7 @@ private: } Vector<SkBitmap*> mBitmapResources; + Vector<SkBitmap*> mOwnedBitmapResources; Vector<SkiaColorFilter*> mFilterResources; Vector<SkPaint*> mPaints; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7f242c3..50f5d57 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -144,6 +144,10 @@ uint32_t OpenGLRenderer::getStencilSize() { return STENCIL_BUFFER_SIZE; } +bool OpenGLRenderer::isDeferred() { + return false; +} + void OpenGLRenderer::setViewport(int width, int height) { mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 0ea0db7..ab324ff 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -63,6 +63,8 @@ public: ANDROID_API OpenGLRenderer(); virtual ~OpenGLRenderer(); + virtual bool isDeferred(); + virtual void setViewport(int width, int height); ANDROID_API void prepare(bool opaque); diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 9ffad88..cf5f822 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -59,11 +59,11 @@ void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { SkSafeRef(bitmapResource->pixelRef()); SkSafeRef(bitmapResource->getColorTable()); - incrementRefcount((void*)bitmapResource, kBitmap); + incrementRefcount((void*) bitmapResource, kBitmap); } void ResourceCache::incrementRefcount(SkPath* pathResource) { - incrementRefcount((void*)pathResource, kPath); + incrementRefcount((void*) pathResource, kPath); } void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java index 9e273d4..3502b62 100644 --- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java +++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java @@ -41,7 +41,7 @@ import java.util.HashMap; */ public class RingtonePlayer extends SystemUI { private static final String TAG = "RingtonePlayer"; - private static final boolean LOGD = true; + private static final boolean LOGD = false; // TODO: support Uri switching under same IBinder diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java index 06cd69e..203f9db 100644 --- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java @@ -113,10 +113,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen mPasswordEntry.setOnEditorActionListener(this); mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false); - mKeyboardHelper.setEnableHaptics( - Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0) - != 0); + mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled()); boolean imeOrDeleteButtonVisible = false; if (mIsAlpha) { // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index cc7050a..9629f0a 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -79,6 +79,7 @@ import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; import android.view.ViewManager; +import android.view.ViewParent; import android.view.ViewStub; import android.view.Window; import android.view.WindowManager; @@ -582,7 +583,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { st.decorView.setWindowBackground(getContext().getResources().getDrawable( backgroundResId)); - + ViewParent shownPanelParent = st.shownPanelView.getParent(); + if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) { + ((ViewGroup) shownPanelParent).removeView(st.shownPanelView); + } st.decorView.addView(st.shownPanelView, lp); /* diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java index 889fbe4..3fbac38 100644 --- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -20,6 +20,7 @@ import com.android.server.accessibility.TouchExplorer.GestureListener; import com.android.server.input.InputFilter; import android.content.Context; +import android.os.PowerManager; import android.util.Slog; import android.view.InputDevice; import android.view.InputEvent; @@ -37,6 +38,8 @@ public class AccessibilityInputFilter extends InputFilter { private final Context mContext; + private final PowerManager mPm; + private final GestureListener mGestureListener; /** @@ -74,6 +77,7 @@ public class AccessibilityInputFilter extends InputFilter { super(context.getMainLooper()); mContext = context; mGestureListener = gestureListener; + mPm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); } @Override @@ -108,6 +112,7 @@ public class AccessibilityInputFilter extends InputFilter { mTouchExplorer.clear(motionEvent, policyFlags); } if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) != 0) { + mPm.userActivity(event.getEventTime(), false); mTouchExplorer.onMotionEvent(motionEvent, policyFlags); } else { mTouchExplorer.clear(motionEvent, policyFlags); diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 28ce1df..1937bad 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -25,6 +25,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; import android.app.PendingIntent; +import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -1343,7 +1344,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub sendDownAndUpKeyEvents(KeyEvent.KEYCODE_APP_SWITCH); } return true; case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: { - // TODO: Implement when 6346026 is fixed. + expandStatusBar(); } return true; } return false; @@ -1413,6 +1414,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Binder.restoreCallingIdentity(token); } + private void expandStatusBar() { + final long token = Binder.clearCallingIdentity(); + + StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService( + android.app.Service.STATUS_BAR_SERVICE); + statusBarManager.expand(); + + Binder.restoreCallingIdentity(token); + } + private IAccessibilityInteractionConnection getConnectionLocked(int windowId) { if (DEBUG) { Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index b9f63cf..e6f4d918 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2619,6 +2619,7 @@ final class ActivityStack { } boolean addingToTask = false; + boolean movedHome = false; TaskRecord reuseTask = null; if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) @@ -2657,6 +2658,7 @@ final class ActivityStack { if (callerAtFront) { // We really do want to push this one into the // user's face, right now. + movedHome = true; moveHomeToFrontFromLaunchLocked(launchFlags); moveTaskToFrontLocked(taskTop.task, r, options); } @@ -2835,7 +2837,9 @@ final class ActivityStack { r.setTask(reuseTask, reuseTask, true); } newTask = true; - moveHomeToFrontFromLaunchLocked(launchFlags); + if (!movedHome) { + moveHomeToFrontFromLaunchLocked(launchFlags); + } } else if (sourceRecord != null) { if (!addingToTask && @@ -3543,7 +3547,7 @@ final class ActivityStack { } ActivityRecord r = mHistory.get(index); - while (index > 0) { + while (index >= 0) { ActivityRecord cur = mHistory.get(index); if (cur.task != r.task) { break; diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index 9321cb3..d0f3e62 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -72,6 +72,7 @@ public class RSTestCore { unitTests.add(new UT_clamp(this, mRes, mCtx)); unitTests.add(new UT_clamp_relaxed(this, mRes, mCtx)); unitTests.add(new UT_convert(this, mRes, mCtx)); + unitTests.add(new UT_convert_relaxed(this, mRes, mCtx)); unitTests.add(new UT_rsdebug(this, mRes, mCtx)); unitTests.add(new UT_rstime(this, mRes, mCtx)); unitTests.add(new UT_rstypes(this, mRes, mCtx)); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert_relaxed.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert_relaxed.java new file mode 100644 index 0000000..728806c --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert_relaxed.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_convert_relaxed extends UnitTest { + private Resources mRes; + + protected UT_convert_relaxed(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Convert (Relaxed)", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_convert_relaxed s = + new ScriptC_convert_relaxed(pRS, mRes, R.raw.convert_relaxed); + pRS.setMessageHandler(mRsMessage); + s.invoke_convert_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/convert_relaxed.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert_relaxed.rs new file mode 100644 index 0000000..81abb9b --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert_relaxed.rs @@ -0,0 +1,2 @@ +#include "convert.rs" +#pragma rs_fp_relaxed |
