summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/16.txt2
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/Activity.java11
-rw-r--r--core/java/android/app/ActivityThread.java11
-rw-r--r--core/java/android/app/Fragment.java5
-rw-r--r--core/java/android/app/FragmentManager.java4
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java7
-rw-r--r--core/java/android/content/Intent.java89
-rw-r--r--core/java/android/preference/MultiSelectListPreference.java5
-rw-r--r--core/java/android/provider/CalendarContract.java11
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java65
-rw-r--r--core/java/android/view/View.java13
-rw-r--r--core/java/android/view/ViewRootImpl.java102
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java62
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfoCache.java2
-rw-r--r--core/java/android/webkit/WebViewClassic.java40
-rw-r--r--core/java/android/webkit/WebViewCore.java29
-rw-r--r--core/java/android/webkit/WebViewInputDispatcher.java17
-rw-r--r--core/java/android/webkit/ZoomManager.java6
-rw-r--r--core/java/android/widget/AbsListView.java5
-rw-r--r--core/java/android/widget/ActivityChooserModel.java10
-rw-r--r--core/java/android/widget/ActivityChooserView.java46
-rw-r--r--core/java/android/widget/Gallery.java30
-rw-r--r--core/java/android/widget/HorizontalScrollView.java5
-rw-r--r--core/java/android/widget/NumberPicker.java274
-rw-r--r--core/java/android/widget/ScrollView.java5
-rw-r--r--core/java/android/widget/ShareActionProvider.java3
-rw-r--r--core/java/android/widget/SpellChecker.java18
-rw-r--r--core/java/android/widget/StackView.java30
-rw-r--r--core/java/android/widget/TextView.java2
-rw-r--r--core/java/com/android/internal/app/PlatLogoActivity.java62
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp38
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h5
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp19
-rw-r--r--core/res/res/layout/time_picker_holo.xml1
-rw-r--r--core/res/res/raw/accessibility_gestures.binbin13005 -> 38381 bytes
-rw-r--r--core/res/res/values-da/strings.xml10
-rw-r--r--core/res/res/values-de/strings.xml4
-rw-r--r--core/res/res/values-in/strings.xml12
-rw-r--r--core/res/res/values-sw600dp/dimens.xml6
-rw-r--r--core/res/res/values-sw720dp/dimens.xml6
-rw-r--r--core/res/res/values-w500dp/bools.xml19
-rw-r--r--core/res/res/values/bools.xml1
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java7
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java2
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java6
-rw-r--r--core/tests/utillib/src/android/test/BandwidthTestCase.java25
-rw-r--r--docs/html/guide/topics/resources/providing-resources.jd16
-rw-r--r--libs/hwui/DisplayListRenderer.cpp43
-rw-r--r--libs/hwui/DisplayListRenderer.h37
-rw-r--r--libs/hwui/OpenGLRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.h2
-rw-r--r--libs/hwui/ResourceCache.cpp4
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml4
-rw-r--r--packages/SystemUI/res/layout/system_bar_notification_panel.xml2
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-in/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-xhdpi/dimens.xml27
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java67
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java5
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java6
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityInputFilter.java5
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java13
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java37
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java13
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java126
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java1
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert_relaxed.java41
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/convert_relaxed.rs2
76 files changed, 1169 insertions, 450 deletions
diff --git a/api/16.txt b/api/16.txt
index 18a4b7b..1a694a8 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -485,6 +485,7 @@ package android {
field public static final int focusable = 16842970; // 0x10100da
field public static final int focusableInTouchMode = 16842971; // 0x10100db
field public static final int focusedMonthDateColor = 16843587; // 0x1010343
+ field public static final int fontFamily = 16843692; // 0x10103ac
field public static final int footerDividersEnabled = 16843311; // 0x101022f
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
@@ -5822,6 +5823,7 @@ package android.content {
field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
+ field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
diff --git a/api/current.txt b/api/current.txt
index 8402f31..1a694a8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5823,6 +5823,7 @@ package android.content {
field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
+ field public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 8192; // 0x2000
field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ac55abe..69ee434 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2713,7 +2713,16 @@ public class Activity extends ContextThemeWrapper
onCreateNavigateUpTaskStack(b);
onPrepareNavigateUpTaskStack(b);
b.startActivities();
- finishAffinity();
+
+ // We can't finishAffinity if we have a result.
+ // Fall back and simply finish the current activity instead.
+ if (mResultCode != RESULT_CANCELED || mResultData != null) {
+ // Tell the developer what's going on to avoid hair-pulling.
+ Log.i(TAG, "onNavigateUp only finishing topmost activity to return a result");
+ finish();
+ } else {
+ finishAffinity();
+ }
} else {
navigateUpTo(upIntent);
}
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..718a917 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -808,13 +808,22 @@ public class Intent implements Parcelable, Cloneable {
* always present to the user a list of the things they can do, with a
* nice title given by the caller such as "Send this photo with:".
* <p>
+ * If you need to grant URI permissions through a chooser, you must specify
+ * the permissions to be granted on the ACTION_CHOOSER Intent
+ * <em>in addition</em> to the EXTRA_INTENT inside. This means using
+ * {@link #setClipData} to specify the URIs to be granted as well as
+ * {@link #FLAG_GRANT_READ_URI_PERMISSION} and/or
+ * {@link #FLAG_GRANT_WRITE_URI_PERMISSION} as appropriate.
+ * <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>
+ * 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";
@@ -822,6 +831,14 @@ public class Intent implements Parcelable, Cloneable {
/**
* Convenience function for creating a {@link #ACTION_CHOOSER} Intent.
*
+ * <p>Builds a new {@link #ACTION_CHOOSER} Intent that wraps the given
+ * target intent, also optionally supplying a title. If the target
+ * intent has specified {@link #FLAG_GRANT_READ_URI_PERMISSION} or
+ * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, then these flags will also be
+ * set in the returned chooser intent, with its ClipData set appropriately:
+ * either a direct reflection of {@link #getClipData()} if that is non-null,
+ * or a new ClipData build from {@link #getData()}.
+ *
* @param target The Intent that the user will be selecting an activity
* to perform.
* @param title Optional title that will be displayed in the chooser.
@@ -835,8 +852,31 @@ public class Intent implements Parcelable, Cloneable {
if (title != null) {
intent.putExtra(EXTRA_TITLE, title);
}
+
+ // Migrate any clip data and flags from target.
+ int permFlags = target.getFlags()
+ & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
+ if (permFlags != 0) {
+ ClipData targetClipData = target.getClipData();
+ if (targetClipData == null && target.getData() != null) {
+ ClipData.Item item = new ClipData.Item(target.getData());
+ String[] mimeTypes;
+ if (target.getType() != null) {
+ mimeTypes = new String[] { target.getType() };
+ } else {
+ mimeTypes = new String[] { };
+ }
+ targetClipData = new ClipData(null, mimeTypes, item);
+ }
+ if (targetClipData != null) {
+ intent.setClipData(targetClipData);
+ intent.addFlags(permFlags);
+ }
+ }
+
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
@@ -3063,6 +3103,17 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int FLAG_ACTIVITY_TASK_ON_HOME = 0X00004000;
/**
+ * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
+ * upon starting the activity the system will also clear any system dialogs that
+ * are currently shown. This is intended primarily for any actions that are
+ * associated with buttons in a notification: tapping on the button to launch
+ * the activity needs to also dismiss the notification window (which is one
+ * of the system dialogs); setting this flag on the Intent associated with that
+ * action will ensure that and other system dialogs are dismissed so that the
+ * user arrives in the new activity.
+ */
+ public static final int FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS = 0X00002000;
+ /**
* If set, when sending a broadcast only registered receivers will be
* called -- no BroadcastReceiver components will be launched.
*/
@@ -6587,19 +6638,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 +6677,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 +6694,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 +6716,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/preference/MultiSelectListPreference.java b/core/java/android/preference/MultiSelectListPreference.java
index 2e8d551..553ce80 100644
--- a/core/java/android/preference/MultiSelectListPreference.java
+++ b/core/java/android/preference/MultiSelectListPreference.java
@@ -125,8 +125,9 @@ public class MultiSelectListPreference extends DialogPreference {
* @param values The values to set for the key.
*/
public void setValues(Set<String> values) {
- mValues = values;
-
+ mValues.clear();
+ mValues.addAll(values);
+
persistStringSet(values);
}
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 09bf42b..1ef0916 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -105,6 +105,17 @@ public final class CalendarContract {
* and it should call {@link Activity#setResult(int)} with
* {@link Activity#RESULT_OK} or {@link Activity#RESULT_CANCELED} to
* acknowledge whether the action was handled or not.
+ *
+ * The custom app should have an intent-filter like the following
+ * <pre>
+ * {@code
+ * <intent-filter>
+ * <action android:name="android.provider.calendar.action.HANDLE_CUSTOM_EVENT" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <data android:mimeType="vnd.android.cursor.item/event" />
+ * </intent-filter>
+ * }
+ * </pre>
* <p>
* Input: {@link Intent#getData} has the event URI. The extra
* {@link #EXTRA_EVENT_BEGIN_TIME} has the start time of the instance. The
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index e1f1db2..6dc31dd 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -29,7 +29,6 @@ import android.util.Poolable;
import android.util.PoolableManager;
import android.util.Pools;
import android.util.SparseLongArray;
-import android.view.ViewGroup.ChildListForAccessibility;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -491,20 +490,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 {
@@ -615,6 +622,8 @@ final class AccessibilityInteractionController {
private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 50;
+ private final ArrayList<View> mTempViewList = new ArrayList<View>();
+
public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags,
List<AccessibilityNodeInfo> outInfos) {
AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
@@ -655,8 +664,6 @@ final class AccessibilityInteractionController {
while (parent instanceof View
&& outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
View parentView = (View) parent;
- final long parentNodeId = AccessibilityNodeInfo.makeNodeId(
- parentView.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo();
if (info != null) {
outInfos.add(info);
@@ -670,19 +677,21 @@ final class AccessibilityInteractionController {
ViewParent parent = current.getParentForAccessibility();
if (parent instanceof ViewGroup) {
ViewGroup parentGroup = (ViewGroup) parent;
- ChildListForAccessibility children = ChildListForAccessibility.obtain(parentGroup,
- false);
+ ArrayList<View> children = mTempViewList;
+ children.clear();
try {
- final int childCount = children.getChildCount();
+ parentGroup.addChildrenForAccessibility(children);
+ final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
return;
}
- View child = children.getChildAt(i);
+ View child = children.get(i);
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
&& isShown(child)) {
AccessibilityNodeInfo info = null;
- AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+ AccessibilityNodeProvider provider =
+ child.getAccessibilityNodeProvider();
if (provider == null) {
info = child.createAccessibilityNodeInfo();
} else {
@@ -695,7 +704,7 @@ final class AccessibilityInteractionController {
}
}
} finally {
- children.recycle();
+ children.clear();
}
}
}
@@ -708,14 +717,16 @@ final class AccessibilityInteractionController {
ViewGroup rootGroup = (ViewGroup) root;
HashMap<View, AccessibilityNodeInfo> addedChildren =
new HashMap<View, AccessibilityNodeInfo>();
- ChildListForAccessibility children = ChildListForAccessibility.obtain(rootGroup, false);
+ ArrayList<View> children = mTempViewList;
+ children.clear();
try {
- final int childCount = children.getChildCount();
+ root.addChildrenForAccessibility(children);
+ final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
return;
}
- View child = children.getChildAt(i);
+ View child = children.get(i);
if (isShown(child)) {
AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
if (provider == null) {
@@ -735,7 +746,7 @@ final class AccessibilityInteractionController {
}
}
} finally {
- children.recycle();
+ children.clear();
}
if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) {
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..bcd336d 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();
- }
}
}
@@ -2184,6 +2183,18 @@ public final class ViewRootImpl implements ViewParent,
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
boolean scalingRequired, Rect dirty) {
+ // If we get here with a disabled & requested hardware renderer, something went
+ // wrong (an invalidate posted right before we destroyed the hardware surface
+ // for instance) so we should just bail out. Locking the surface with software
+ // rendering at this point would lock it forever and prevent hardware renderer
+ // from doing its job when it comes back.
+ if (attachInfo.mHardwareRenderer != null && !attachInfo.mHardwareRenderer.isEnabled() &&
+ attachInfo.mHardwareRenderer.isRequested()) {
+ mFullRedrawNeeded = true;
+ scheduleTraversals();
+ return false;
+ }
+
// Draw with software renderer.
Canvas canvas;
try {
@@ -2543,11 +2554,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 +2684,8 @@ public final class ViewRootImpl implements ViewParent,
destroyHardwareRenderer();
+ setAccessibilityFocusedHost(null);
+
mView = null;
mAttachInfo.mRootView = null;
mAttachInfo.mSurface = null;
@@ -4608,6 +4661,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/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index bd341d0..20b5f17 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -19,6 +19,7 @@ package android.view.accessibility;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.os.Process;
@@ -27,10 +28,14 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
+import android.util.SparseLongArray;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -74,6 +79,8 @@ public final class AccessibilityInteractionClient
private static final boolean DEBUG = false;
+ private static final boolean CHECK_INTEGRITY = true;
+
private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
private static final Object sStaticLock = new Object();
@@ -491,6 +498,9 @@ public final class AccessibilityInteractionClient
result = Collections.emptyList();
}
clearResultLocked();
+ if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) {
+ checkFindAccessibilityNodeInfoResultIntegrity(result);
+ }
return result;
}
}
@@ -696,4 +706,56 @@ public final class AccessibilityInteractionClient
sConnectionCache.remove(connectionId);
}
}
+
+ /**
+ * Checks whether the infos are a fully connected tree with no duplicates.
+ *
+ * @param infos The result list to check.
+ */
+ private void checkFindAccessibilityNodeInfoResultIntegrity(List<AccessibilityNodeInfo> infos) {
+ if (infos.size() == 0) {
+ return;
+ }
+ // Find the root node.
+ AccessibilityNodeInfo root = infos.get(0);
+ final int infoCount = infos.size();
+ for (int i = 1; i < infoCount; i++) {
+ for (int j = i; j < infoCount; j++) {
+ AccessibilityNodeInfo candidate = infos.get(j);
+ if (root.getParentNodeId() == candidate.getSourceNodeId()) {
+ root = candidate;
+ break;
+ }
+ }
+ }
+ if (root == null) {
+ Log.e(LOG_TAG, "No root.");
+ }
+ // Check for duplicates.
+ HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>();
+ Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
+ fringe.add(root);
+ while (!fringe.isEmpty()) {
+ AccessibilityNodeInfo current = fringe.poll();
+ if (!seen.add(current)) {
+ Log.e(LOG_TAG, "Duplicate node.");
+ return;
+ }
+ SparseLongArray childIds = current.getChildNodeIds();
+ final int childCount = childIds.size();
+ for (int i = 0; i < childCount; i++) {
+ final long childId = childIds.valueAt(i);
+ for (int j = 0; j < infoCount; j++) {
+ AccessibilityNodeInfo child = infos.get(j);
+ if (child.getSourceNodeId() == childId) {
+ fringe.add(child);
+ }
+ }
+ }
+ }
+ final int disconnectedCount = infos.size() - seen.size();
+ if (disconnectedCount > 0) {
+ Log.e(LOG_TAG, disconnectedCount + " Disconnected nodes.");
+ }
+ }
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 52b7772..14954be 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -244,7 +244,7 @@ public class AccessibilityNodeInfoCache {
/**
* We are enforcing the invariant for a single accessibility focus.
*
- * @param currentInputFocusId The current input focused node.
+ * @param currentAccessibilityFocusId The current input focused node.
*/
private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) {
final int cacheSize = mCacheImpl.size();
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index f4796d5..f1f3db2 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1716,6 +1716,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mZoomManager.updateDefaultZoomDensity(density);
}
+ /* package */ int getScaledNavSlop() {
+ return viewToContentDimension(mNavSlop);
+ }
+
/* package */ boolean onSavePassword(String schemePlusHost, String username,
String password, final Message resumeMsg) {
boolean rVal = false;
@@ -2939,6 +2943,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// premature data from webkit, ignore
if ((w | h) == 0) {
+ invalidate();
return;
}
@@ -2951,10 +2956,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// updated when we get out of that mode.
if (!mDrawHistory) {
// repin our scroll, taking into account the new content size
- if (updateScrollCoordinates(pinLocX(getScrollX()),
- pinLocY(getScrollY()))) {
- invalidate();
- }
+ updateScrollCoordinates(pinLocX(getScrollX()), pinLocY(getScrollY()));
if (!mScroller.isFinished()) {
// We are in the middle of a scroll. Repin the final scroll
// position.
@@ -2962,6 +2964,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mScroller.setFinalY(pinLocY(mScroller.getFinalY()));
}
}
+ invalidate();
}
contentSizeChanged(updateLayout);
}
@@ -4339,10 +4342,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void removeTouchHighlight() {
- if (mWebViewCore != null) {
- mWebViewCore.removeMessages(EventHub.HIT_TEST);
- }
- mPrivateHandler.removeMessages(HIT_TEST_RESULT);
setTouchHighlightRects(null);
}
@@ -5817,7 +5816,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
switch (action) {
case MotionEvent.ACTION_DOWN: {
mConfirmMove = false;
- mInitialHitTestResult = null;
if (!mEditTextScroller.isFinished()) {
mEditTextScroller.abortAnimation();
}
@@ -5839,23 +5837,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
} else { // the normal case
mTouchMode = TOUCH_INIT_MODE;
- // TODO: Have WebViewInputDispatch handle this
- TouchHighlightData data = new TouchHighlightData();
- data.mX = contentX;
- data.mY = contentY;
- data.mNativeLayerRect = new Rect();
- if (mNativeClass != 0) {
- data.mNativeLayer = nativeScrollableLayer(mNativeClass,
- contentX, contentY, data.mNativeLayerRect, null);
- } else {
- data.mNativeLayer = 0;
- }
- data.mSlop = viewToContentDimension(mNavSlop);
- removeTouchHighlight();
- if (!mBlockWebkitViewMessages && mWebViewCore != null) {
- mWebViewCore.sendMessageAtFrontOfQueue(
- EventHub.HIT_TEST, data);
- }
if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION,
(eventTime - mLastTouchUpTime), eventTime);
@@ -7956,7 +7937,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
// update the zoom information based on the new picture
- mZoomManager.onNewPicture(draw);
+ if (mZoomManager.onNewPicture(draw))
+ invalidate();
if (isPictureAfterFirstLayout) {
mViewManager.postReadyToDrawAll();
@@ -7986,7 +7968,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..76cd1c9 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;
@@ -1143,8 +1143,6 @@ public final class WebViewCore {
static final int ADD_PACKAGE_NAME = 185;
static final int REMOVE_PACKAGE_NAME = 186;
- static final int HIT_TEST = 187;
-
// accessibility support
static final int MODIFY_SELECTION = 190;
@@ -1648,18 +1646,6 @@ public final class WebViewCore {
(Set<String>) msg.obj);
break;
- case HIT_TEST:
- TouchHighlightData d = (TouchHighlightData) msg.obj;
- if (d.mNativeLayer != 0) {
- nativeScrollLayer(mNativeClass,
- d.mNativeLayer, d.mNativeLayerRect);
- }
- WebKitHitTest hit = performHitTest(d.mX, d.mY, d.mSlop, true);
- mWebViewClassic.mPrivateHandler.obtainMessage(
- WebViewClassic.HIT_TEST_RESULT, hit)
- .sendToTarget();
- break;
-
case SET_USE_MOCK_DEVICE_ORIENTATION:
setUseMockDeviceOrientation();
break;
@@ -1718,12 +1704,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:
@@ -1788,6 +1778,15 @@ public final class WebViewCore {
return false;
}
switch (eventType) {
+ case WebViewInputDispatcher.EVENT_TYPE_HIT_TEST:
+ int x = Math.round(event.getX());
+ int y = Math.round(event.getY());
+ WebKitHitTest hit = performHitTest(x, y,
+ mWebViewClassic.getScaledNavSlop(), true);
+ mWebViewClassic.mPrivateHandler.obtainMessage(
+ WebViewClassic.HIT_TEST_RESULT, hit).sendToTarget();
+ return false;
+
case WebViewInputDispatcher.EVENT_TYPE_CLICK:
return nativeMouseClick(mNativeClass);
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
index 9328d8c..9eeb311 100644
--- a/core/java/android/webkit/WebViewInputDispatcher.java
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -204,6 +204,11 @@ final class WebViewInputDispatcher {
public static final int EVENT_TYPE_DOUBLE_TAP = 5;
/**
+ * Event type: Indicates that a hit test should be performed
+ */
+ public static final int EVENT_TYPE_HIT_TEST = 6;
+
+ /**
* Flag: This event is private to this queue. Do not forward it.
*/
public static final int FLAG_PRIVATE = 1 << 0;
@@ -499,13 +504,17 @@ final class WebViewInputDispatcher {
}
private void enqueueDoubleTapLocked(MotionEvent event) {
- unscheduleClickLocked();
- hideTapCandidateLocked();
MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_DOUBLE_TAP, 0,
mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
enqueueEventLocked(d);
- mIsDoubleTapCandidate = false;
+ }
+
+ private void enqueueHitTestLocked(MotionEvent event) {
+ MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
+ DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_HIT_TEST, 0,
+ mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
+ enqueueEventLocked(d);
}
private void checkForSlopLocked(MotionEvent event) {
@@ -545,6 +554,7 @@ final class WebViewInputDispatcher {
mInitialDownX = event.getX();
mInitialDownY = event.getY();
scheduleShowTapHighlightLocked();
+ enqueueHitTestLocked(event);
} else if (action == MotionEvent.ACTION_UP) {
unscheduleLongPressLocked();
if (isClickCandidateLocked(event)) {
@@ -824,6 +834,7 @@ final class WebViewInputDispatcher {
case EVENT_TYPE_CLICK:
case EVENT_TYPE_HOVER:
case EVENT_TYPE_SCROLL:
+ case EVENT_TYPE_HIT_TEST:
return false;
case EVENT_TYPE_TOUCH:
return !mPostSendTouchEventsToWebKit
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 2247678..1da59e4 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -1008,8 +1008,10 @@ class ZoomManager {
/**
* Updates zoom values when Webkit produces a new picture. This method
* should only be called from the UI thread's message handler.
+ *
+ * @return True if zoom value has changed
*/
- public void onNewPicture(WebViewCore.DrawData drawData) {
+ public boolean onNewPicture(WebViewCore.DrawData drawData) {
final int viewWidth = mWebView.getViewWidth();
final boolean zoomOverviewWidthChanged = setupZoomOverviewWidth(drawData, viewWidth);
final float newZoomOverviewScale = getZoomOverviewScale();
@@ -1056,6 +1058,8 @@ class ZoomManager {
// so next new picture could be forced into overview mode if it's true.
mInitialZoomOverview = mInZoomOverview;
}
+
+ return scaleHasDiff;
}
/**
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..515f0c4 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,10 +2481,16 @@ 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);
- info.setParent((View) getParent());
+ if (hasVirtualIncrementButton()) {
+ info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT);
+ }
+
+ info.setParent((View) getParentForAccessibility());
info.setEnabled(NumberPicker.this.isEnabled());
info.setScrollable(true);
Rect boundsInParent = mTempRect;
@@ -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/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 7ca02e1..74ea038 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -132,8 +132,6 @@ public class SpellChecker implements SpellCheckerSessionListener {
// Restore SpellCheckSpans in pool
for (int i = 0; i < mLength; i++) {
- // Resets id and progress to invalidate spell check span
- mSpellCheckSpans[i].setSpellCheckInProgress(false);
mIds[i] = -1;
}
mLength = 0;
@@ -200,15 +198,16 @@ public class SpellChecker implements SpellCheckerSessionListener {
private void addSpellCheckSpan(Editable editable, int start, int end) {
final int index = nextSpellCheckSpanIndex();
- editable.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ SpellCheckSpan spellCheckSpan = mSpellCheckSpans[index];
+ editable.setSpan(spellCheckSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ spellCheckSpan.setSpellCheckInProgress(false);
mIds[index] = mSpanSequenceCounter++;
}
- public void removeSpellCheckSpan(SpellCheckSpan spellCheckSpan) {
+ public void onSpellCheckSpanRemoved(SpellCheckSpan spellCheckSpan) {
+ // Recycle any removed SpellCheckSpan (from this code or during text edition)
for (int i = 0; i < mLength; i++) {
if (mSpellCheckSpans[i] == spellCheckSpan) {
- // Resets id and progress to invalidate spell check span
- mSpellCheckSpans[i].setSpellCheckInProgress(false);
mIds[i] = -1;
return;
}
@@ -387,6 +386,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
final SpellCheckSpan spellCheckSpan =
onGetSuggestionsInternal(results[i], USE_SPAN_RANGE, USE_SPAN_RANGE);
if (spellCheckSpan != null) {
+ // onSpellCheckSpanRemoved will recycle this span in the pool
editable.removeSpan(spellCheckSpan);
}
}
@@ -414,11 +414,12 @@ public class SpellChecker implements SpellCheckerSessionListener {
suggestionsInfo, offset, length);
if (spellCheckSpan == null && scs != null) {
// the spellCheckSpan is shared by all the "SuggestionsInfo"s in the same
- // SentenceSuggestionsInfo
+ // SentenceSuggestionsInfo. Removal is deferred after this loop.
spellCheckSpan = scs;
}
}
if (spellCheckSpan != null) {
+ // onSpellCheckSpanRemoved will recycle this span in the pool
editable.removeSpan(spellCheckSpan);
}
}
@@ -633,7 +634,8 @@ public class SpellChecker implements SpellCheckerSessionListener {
}
break;
}
- removeSpellCheckSpan(spellCheckSpan);
+ // This spellCheckSpan is replaced by the one we are creating
+ editable.removeSpan(spellCheckSpan);
spellCheckStart = Math.min(spanStart, spellCheckStart);
spellCheckEnd = Math.max(spanEnd, spellCheckEnd);
}
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/android/widget/TextView.java b/core/java/android/widget/TextView.java
index abf2eb2..fc56e11 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7240,7 +7240,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mEditor != null && mEditor.mSpellChecker != null && newStart < 0 &&
what instanceof SpellCheckSpan) {
- mEditor.mSpellChecker.removeSpellCheckSpan((SpellCheckSpan) what);
+ mEditor.mSpellChecker.onSpellCheckSpanRemoved((SpellCheckSpan) what);
}
}
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/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 673c38d..c85b09c 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -332,15 +332,7 @@ uint32_t TextLayoutValue::getElapsedTime() {
}
TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) {
- mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal);
- mArabicTypeface = NULL;
- mHebrewRegularTypeface = NULL;
- mHebrewBoldTypeface = NULL;
- mBengaliTypeface = NULL;
- mThaiTypeface = NULL;
- mDevanagariRegularTypeface = NULL;
- mTamilRegularTypeface = NULL;
- mTamilBoldTypeface = NULL;
+ init();
mFontRec.klass = &harfbuzzSkiaClass;
mFontRec.userData = 0;
@@ -359,7 +351,19 @@ TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) {
mShaperItem.font->userData = &mShapingPaint;
}
-TextLayoutShaper::~TextLayoutShaper() {
+void TextLayoutShaper::init() {
+ mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal);
+ mArabicTypeface = NULL;
+ mHebrewRegularTypeface = NULL;
+ mHebrewBoldTypeface = NULL;
+ mBengaliTypeface = NULL;
+ mThaiTypeface = NULL;
+ mDevanagariRegularTypeface = NULL;
+ mTamilRegularTypeface = NULL;
+ mTamilBoldTypeface = NULL;
+}
+
+void TextLayoutShaper::unrefTypefaces() {
SkSafeUnref(mDefaultTypeface);
SkSafeUnref(mArabicTypeface);
SkSafeUnref(mHebrewRegularTypeface);
@@ -369,6 +373,10 @@ TextLayoutShaper::~TextLayoutShaper() {
SkSafeUnref(mDevanagariRegularTypeface);
SkSafeUnref(mTamilRegularTypeface);
SkSafeUnref(mTamilBoldTypeface);
+}
+
+TextLayoutShaper::~TextLayoutShaper() {
+ unrefTypefaces();
deleteShaperItemGlyphArrays();
}
@@ -983,6 +991,12 @@ HB_Face TextLayoutShaper::getCachedHBFace(SkTypeface* typeface) {
return face;
}
+void TextLayoutShaper::purgeCaches() {
+ mCachedHBFaces.clear();
+ unrefTypefaces();
+ init();
+}
+
TextLayoutEngine::TextLayoutEngine() {
mShaper = new TextLayoutShaper();
#if USE_TEXT_LAYOUT_CACHE
@@ -1018,6 +1032,10 @@ sp<TextLayoutValue> TextLayoutEngine::getValue(const SkPaint* paint, const jchar
void TextLayoutEngine::purgeCaches() {
#if USE_TEXT_LAYOUT_CACHE
mTextLayoutCache->clear();
+ mShaper->purgeCaches();
+#if DEBUG_GLYPHS
+ ALOGD("Purged TextLayoutEngine caches");
+#endif
#endif
}
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 027e888..cb15a2a 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -169,6 +169,8 @@ public:
void computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags);
+ void purgeCaches();
+
private:
/**
* Harfbuzz shaper item
@@ -218,6 +220,9 @@ private:
*/
UnicodeString mBuffer;
+ void init();
+ void unrefTypefaces();
+
SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
SkUnichar unichar, HB_Script script);
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
index f7e6615..96fa1ec 100644
--- a/core/res/res/raw/accessibility_gestures.bin
+++ b/core/res/res/raw/accessibility_gestures.bin
Binary files differ
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 25cfb7f..4ec0197 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -185,10 +185,10 @@
<string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Bruge funktioner, der hurtigt kan dræne batteriet."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direkte adgang til kalender og begivenheder."</string>
- <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Læs brugerordbog"</string>
- <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Læs ord i brugerordbogen."</string>
- <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Skriv brugerordbog"</string>
- <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Føj ord til brugerordbogen."</string>
+ <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Læse brugerordbog"</string>
+ <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Læse ord i brugerordbogen."</string>
+ <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Skrive brugerordbog"</string>
+ <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Føje ord til brugerordbogen."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bogmærker og historik"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte adgang til bogmærker og browserhistorik."</string>
<string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
@@ -561,7 +561,7 @@
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Tillader, at appen læser USB-lagerets indhold, herunder billeder og mediefiler."</string>
<string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Tillader, at appen læser SD-kortets indhold, som kan omfatte billeder og mediefiler."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ændre eller slette indhold på USB-lager"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"skift eller slet indholdet på dit SD-kort"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ændre eller slette indholdet på dit SD-kort"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Lader appen skrive til USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillader, at appen kan skrive til SD-kortet."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3d51570..4ca2b86 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1091,7 +1091,7 @@
<string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Bei der Verwendung Ihres USB-Speichers als USB-Massenspeicher ist ein Problem aufgetreten."</string>
<string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Bei der Verwendung Ihrer SD-Karte als USB-Massenspeicher ist ein Problem aufgetreten."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-Verbindung"</string>
- <string name="usb_storage_notification_message" msgid="939822783828183763">"Zum Kopieren von Dateien auf den/von dem Computer berühren"</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Zum Kopieren von Dateien berühren"</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB-Speicher deaktivieren"</string>
<string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Zum Deaktivieren des USB-Speichers berühren"</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB-Speicher in Verwendung"</string>
@@ -1114,7 +1114,7 @@
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Alle Daten auf Ihrer Karte gehen verloren."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging tippen"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren von USB-Debugging berühren"</string>
<string name="select_input_method" msgid="4653387336791222978">"Eingabemethode wählen"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 616b9be..5bca912 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -185,12 +185,9 @@
<string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Menggunakan fitur yang dapat menguras baterai dengan cepat."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="5777534316982184416">"Akses langsung ke kalender dan acara."</string>
- <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
- <skip />
- <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
- <skip />
- <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
- <skip />
+ <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Membaca Kamus Pengguna"</string>
+ <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Membaca kata dalam kamus pengguna."</string>
+ <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Menulis Kamus Pengguna"</string>
<string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Menambahkan kata ke kamus pengguna."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmark dan Riwayat"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke bookmark dan riwayat browser."</string>
@@ -564,8 +561,7 @@
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Izinkan aplikasi membaca konten penyimpanan USB, yang mungkin mencakup foto dan media."</string>
<string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Izinkan aplikasi membaca konten kartu SD, yang mungkin mencakup foto dan media."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ubah/hapus konten pympanan USB"</string>
- <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
- <skip />
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"mengubah atau menghapus konten kartu SD Anda"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Mengizinkan apl menulis ke penyimpanan USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string>
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/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index f7b0cd0..f01562c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -244,8 +244,13 @@ public class ConnectivityManagerTestActivity extends Activity {
mContext = this;
mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null);
- initializeNetworkStates();
+ if (mWifiManager.isWifiApEnabled()) {
+ // if soft AP is enabled, disable it
+ mWifiManager.setWifiApEnabled(null, false);
+ log("Disable soft ap");
+ }
+ initializeNetworkStates();
log("Clear Wifi before we start the test.");
removeConfiguredNetworksAndDisableWifi();
mWifiRegexs = mCM.getTetherableWifiRegexs();
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 7e136be..60595fb 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -103,7 +103,7 @@ public class WifiApStress
assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
// Wait for wifi ap state to be ENABLED
assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ 2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
// Wait for wifi tethering result
assertEquals(ConnectivityManagerTestActivity.SUCCESS,
mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 649ec3e..39e2cf2 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -83,6 +83,7 @@ public class WifiStressTest
@Override
public void setUp() throws Exception {
super.setUp();
+
mAct = getActivity();
mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
mReconnectIterations = mRunner.mReconnectIterations;
@@ -97,11 +98,6 @@ public class WifiStressTest
mOutputWriter = new BufferedWriter(new FileWriter(new File(
Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
mAct.turnScreenOn();
- if (mAct.mWifiManager.isWifiApEnabled()) {
- // if soft AP is enabled, disable it
- assertTrue(mAct.mWifiManager.setWifiApEnabled(null, false));
- Log.v(TAG, "disable soft ap");
- }
if (!mAct.mWifiManager.isWifiEnabled()) {
log("Enable wi-fi before stress tests.");
if (!mAct.enableWifi()) {
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/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b33a097..847681b 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -528,20 +528,22 @@ how this affects your application during runtime.</p>
which indicates the current device orientation.</p>
</td>
</tr>
- <tr id="DockQualifier">
- <td>Dock mode</td>
+ <tr id="UiModeQualifier">
+ <td>UI mode</td>
<td>
<code>car</code><br/>
- <code>desk</code>
+ <code>desk</code><br/>
+ <code>television</code>
</td>
<td>
<ul class="nolist">
- <li>{@code car}: Device is in a car dock</li>
- <li>{@code desk}: Device is in a desk dock</li>
+ <li>{@code car}: Device is displaying in a car dock</li>
+ <li>{@code desk}: Device is displaying in a desk dock</li>
+ <li>{@code television}: Device is displaying on a television</li>
</ul>
- <p><em>Added in API level 8.</em></p>
+ <p><em>Added in API level 8, television added in API 13.</em></p>
<p>This can change during the life of your application if the user places the device in a
-dock. You can enable or disable this mode using {@link
+dock. You can enable or disable some of these modes using {@link
android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
information about how this affects your application during runtime.</p>
</td>
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/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index bc144bb..4cff67b 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -48,7 +48,7 @@
android:id="@+id/latestItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- systemui:rowHeight="@dimen/notification_height"
+ systemui:rowHeight="@dimen/notification_row_min_height"
/>
</ScrollView>
@@ -68,4 +68,4 @@
</com.android.systemui.statusbar.phone.CloseDragHandle>
-</FrameLayout><!-- end of sliding panel --> \ No newline at end of file
+</FrameLayout><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel.xml b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
index 42af147..5579505 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
@@ -77,7 +77,7 @@
android:clickable="true"
android:focusable="true"
android:descendantFocusability="afterDescendants"
- systemui:rowHeight="@dimen/notification_height"
+ systemui:rowHeight="@dimen/notification_row_min_height"
/>
</ScrollView>
</LinearLayout>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 46adfd7..aae070a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -26,7 +26,7 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"सूची से निकालें"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"एप्‍लिकेशन जानकारी"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"कोई हाल ही के एप्लिकेशन नहीं"</string>
- <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन ख़ारिज करें"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन खारिज करें"</string>
<plurals name="status_bar_accessibility_recent_apps">
<item quantity="one" msgid="5854176083865845541">"1 हाल ही का एप्लिकेशन"</item>
<item quantity="other" msgid="1040784359794890744">"%d हाल ही के एप्लिकेशन"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a117252..a69fc23 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -141,8 +141,7 @@
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan tirai layar"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info aplikasi"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan mati"</string>
- <!-- no translation found for notifications_off_text (2529001315769385273) -->
- <skip />
+ <string name="notifications_off_text" msgid="2529001315769385273">"Ketuk di sini untuk menyalakan pemberitahuan lagi."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Layar dikunci dalam orientasi lanskap."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Layar dikunci dalam orientasi potret."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3277fb6..7a7d08f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -38,7 +38,7 @@
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
- <string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string>
+ <string name="battery_low_why" msgid="7279169609518386372">"Подробнее"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим полета"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 5026d6d..1fa3b21 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -141,7 +141,7 @@
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Vklop ohranjevalnika zaslona"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Podatki o aplikaciji"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Obvestila so izklopljena"</string>
- <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da spet vklopite obvestila."</string>
+ <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da ponovno vklopite obvestila."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaklenjen v ležeči usmerjenosti."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaklenjen v pokončni usmerjenosti."</string>
diff --git a/packages/SystemUI/res/values-xhdpi/dimens.xml b/packages/SystemUI/res/values-xhdpi/dimens.xml
deleted file mode 100644
index 303841a..0000000
--- a/packages/SystemUI/res/values-xhdpi/dimens.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2011, 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>
- <!-- thickness (height) of each notification row, including any separators or padding -->
- <!-- note: this is the same value as in values/dimens.xml; the value is overridden in
- values-hdpi/dimens.xml and so we need to re-assert the general value here -->
- <dimen name="notification_height">68dp</dimen>
-
- <!-- thickness (height) of dividers between each notification row -->
- <!-- same as in values/dimens.xml; see note at notification_height -->
- <dimen name="notification_divider_height">2dp</dimen>
-</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8293d99..4f3e787 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -142,7 +142,7 @@
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Izaziso zivaliwe"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Thepha lapha ukuvula futhi izaziso."</string>
- <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzanzakalela."</string>
+ <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Isikrini sikhiyelwe ngomumo we-landscape."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Isikrini sikhiyelwe ngomumo we-portrait."</string>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f548166..9042045 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -49,18 +49,21 @@
reducing false presses on navbar buttons; approx 2mm -->
<dimen name="navigation_bar_deadzone_size">12dp</dimen>
- <!-- thickness (height) of each 1U notification row plus glow, padding, etc -->
- <dimen name="notification_height">72dp</dimen>
-
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
- <!-- Height of a small notification in the status bar plus glow, padding, etc -->
- <dimen name="notification_min_height">72dp</dimen>
+ <!-- Height of a small notification in the status bar -->
+ <dimen name="notification_min_height">64dp</dimen>
<!-- Height of a large notification in the status bar -->
<dimen name="notification_max_height">256dp</dimen>
+ <!-- Height of a small notification in the status bar plus glow, padding, etc -->
+ <dimen name="notification_row_min_height">72dp</dimen>
+
+ <!-- Height of a large notification in the status bar plus glow, padding, etc -->
+ <dimen name="notification_row_max_height">260dp</dimen>
+
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">18dip</dimen>
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/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 71d26b5..4b223dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -478,7 +478,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
int rowHeight =
- mContext.getResources().getDimensionPixelSize(R.dimen.notification_height);
+ mContext.getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
int minHeight =
mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
int maxHeight =
@@ -498,7 +498,6 @@ public abstract class BaseStatusBar extends SystemUI implements
// for blaming (see SwipeHelper.setLongPressListener)
row.setTag(sbn.pkg);
- ViewGroup.LayoutParams lp = row.getLayoutParams();
workAroundBadLayerDrawableOpacity(row);
View vetoButton = updateNotificationVetoButton(row, sbn);
vetoButton.setContentDescription(mContext.getString(
@@ -510,13 +509,6 @@ public abstract class BaseStatusBar extends SystemUI implements
ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
ViewGroup adaptive = (ViewGroup)row.findViewById(R.id.adaptive);
- // Ensure that R.id.content is properly set to 64dp high if 1U
- lp = content.getLayoutParams();
- if (large == null) {
- lp.height = minHeight;
- }
- content.setLayoutParams(lp);
-
content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
PendingIntent contentIntent = sbn.notification.contentIntent;
@@ -528,6 +520,7 @@ public abstract class BaseStatusBar extends SystemUI implements
content.setOnClickListener(null);
}
+ // TODO(cwren) normalize variable names with those in updateNotification
View expandedOneU = null;
View expandedLarge = null;
Exception exception = null;
@@ -556,7 +549,7 @@ public abstract class BaseStatusBar extends SystemUI implements
SizeAdaptiveLayout.LayoutParams params =
new SizeAdaptiveLayout.LayoutParams(expandedLarge.getLayoutParams());
params.minHeight = minHeight+1;
- params.maxHeight = SizeAdaptiveLayout.LayoutParams.UNBOUNDED;
+ params.maxHeight = maxHeight;
adaptive.addView(expandedLarge, params);
}
row.setDrawingCacheEnabled(true);
@@ -723,20 +716,18 @@ public abstract class BaseStatusBar extends SystemUI implements
}
protected boolean expandView(NotificationData.Entry entry, boolean expand) {
- if (entry.expandable()) {
- int rowHeight =
- mContext.getResources().getDimensionPixelSize(R.dimen.notification_height);
- ViewGroup.LayoutParams lp = entry.row.getLayoutParams();
- if (expand) {
- lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
- } else {
- lp.height = rowHeight;
- }
- entry.row.setLayoutParams(lp);
- return expand;
+ int rowHeight =
+ mContext.getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
+ ViewGroup.LayoutParams lp = entry.row.getLayoutParams();
+ if (entry.expandable() && expand) {
+ if (DEBUG) Slog.d(TAG, "setting expanded row height to WRAP_CONTENT");
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
} else {
- return false;
+ if (DEBUG) Slog.d(TAG, "setting collapsed row height to " + rowHeight);
+ lp.height = rowHeight;
}
+ entry.row.setLayoutParams(lp);
+ return expand;
}
protected void updateExpansionStates() {
@@ -781,32 +772,41 @@ public abstract class BaseStatusBar extends SystemUI implements
final StatusBarNotification oldNotification = oldEntry.notification;
// XXX: modify when we do something more intelligent with the two content views
- final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null)
- ? oldNotification.notification.bigContentView
- : oldNotification.notification.contentView;
- final RemoteViews contentView = (notification.notification.bigContentView != null)
- ? notification.notification.bigContentView
- : notification.notification.contentView;
+ final RemoteViews oldContentView = oldNotification.notification.contentView;
+ final RemoteViews contentView = notification.notification.contentView;
+ final RemoteViews oldBigContentView = oldNotification.notification.bigContentView;
+ final RemoteViews bigContentView = notification.notification.bigContentView;
if (DEBUG) {
Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
+ " ongoing=" + oldNotification.isOngoing()
+ " expanded=" + oldEntry.expanded
+ " contentView=" + oldContentView
+ + " bigContentView=" + oldBigContentView
+ " rowParent=" + oldEntry.row.getParent());
Slog.d(TAG, "new notification: when=" + notification.notification.when
+ " ongoing=" + oldNotification.isOngoing()
- + " contentView=" + contentView);
+ + " contentView=" + contentView
+ + " bigContentView=" + bigContentView);
}
// Can we just reapply the RemoteViews in place? If when didn't change, the order
// didn't change.
+
+ // 1U is never null
boolean contentsUnchanged = oldEntry.expanded != null
- && contentView != null && oldContentView != null
&& contentView.getPackage() != null
&& oldContentView.getPackage() != null
&& oldContentView.getPackage().equals(contentView.getPackage())
&& oldContentView.getLayoutId() == contentView.getLayoutId();
+ // large view may be null
+ boolean bigContentsUnchanged =
+ (oldEntry.getLargeView() == null && bigContentView == null)
+ || ((oldEntry.getLargeView() != null && bigContentView != null)
+ && bigContentView.getPackage() != null
+ && oldBigContentView.getPackage() != null
+ && oldBigContentView.getPackage().equals(bigContentView.getPackage())
+ && oldBigContentView.getLayoutId() == bigContentView.getLayoutId());
ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.score == oldNotification.score;
@@ -816,12 +816,15 @@ public abstract class BaseStatusBar extends SystemUI implements
&& !TextUtils.equals(notification.notification.tickerText,
oldEntry.notification.notification.tickerText);
boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
- if (contentsUnchanged && (orderUnchanged || isTopAnyway)) {
+ if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
oldEntry.notification = notification;
try {
// Reapply the RemoteViews
- contentView.reapply(mContext, oldEntry.content);
+ contentView.reapply(mContext, oldEntry.expanded);
+ if (bigContentView != null && oldEntry.getLargeView() != null) {
+ bigContentView.reapply(mContext, oldEntry.getLargeView());
+ }
// update the contentIntent
final PendingIntent contentIntent = notification.notification.contentIntent;
if (contentIntent != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 0fe7a0a..f41d99c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -101,8 +101,8 @@ public class NotificationRowLayout
float densityScale = getResources().getDisplayMetrics().density;
float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
- int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
- int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+ int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
+ int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
mExpandHelper = new ExpandHelper(mContext, this, minHeight, maxHeight);
}
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/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 54ef724..76016f4 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3510,31 +3510,36 @@ public final class ActivityManagerService extends ActivityManagerNative
public void closeSystemDialogs(String reason) {
enforceNotIsolatedCaller("closeSystemDialogs");
+
+ final int uid = Binder.getCallingUid();
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (this) {
+ closeSystemDialogsLocked(uid, reason);
+ }
+ Binder.restoreCallingIdentity(origId);
+ }
+
+ void closeSystemDialogsLocked(int callingUid, String reason) {
Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
if (reason != null) {
intent.putExtra("reason", reason);
}
+ mWindowManager.closeSystemDialogs(reason);
- final int uid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
- synchronized (this) {
- mWindowManager.closeSystemDialogs(reason);
-
- for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
- ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
- if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
- r.stack.finishActivityLocked(r, i,
- Activity.RESULT_CANCELED, null, "close-sys");
- }
+ for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
+ ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+ if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+ r.stack.finishActivityLocked(r, i,
+ Activity.RESULT_CANCELED, null, "close-sys");
}
-
- broadcastIntentLocked(null, null, intent, null,
- null, 0, null, null, null, false, false, -1, uid, 0 /* TODO: Verify */);
}
- Binder.restoreCallingIdentity(origId);
+
+ broadcastIntentLocked(null, null, intent, null,
+ null, 0, null, null, null, false, false, -1,
+ callingUid, 0 /* TODO: Verify */);
}
-
+
public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
throws RemoteException {
enforceNotIsolatedCaller("getProcessMemoryInfo");
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index b9f63cf..5b15e50 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -52,6 +52,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserId;
@@ -2532,6 +2533,10 @@ final class ActivityStack {
mDismissKeyguardOnNextActivity = false;
mService.mWindowManager.dismissKeyguard();
}
+ if (err >= ActivityManager.START_SUCCESS &&
+ (launchFlags&Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS) != 0) {
+ mService.closeSystemDialogsLocked(Process.myUid(), "launch");
+ }
return err;
}
@@ -2619,6 +2624,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 +2663,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 +2842,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 +3552,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/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index cba92f3..5516dea 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -935,6 +935,59 @@ class WindowStateAnimator {
mDtDy = mWin.mGlobalScale;
}
+ void updateSurfaceWindowCrop(final boolean recoveringMemory) {
+ final WindowState w = mWin;
+
+ // Need to recompute a new system decor rect each time.
+ if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+ // Currently can't do this cropping for scaled windows. We'll
+ // just keep the crop rect the same as the source surface.
+ w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
+ } else if (w.mLayer >= mService.mSystemDecorLayer) {
+ // Above the decor layer is easy, just use the entire window.
+ w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
+ w.mCompatFrame.height());
+ } else {
+ final Rect decorRect = mService.mSystemDecorRect;
+ // Compute the offset of the window in relation to the decor rect.
+ final int offX = w.mXOffset + w.mFrame.left;
+ final int offY = w.mYOffset + w.mFrame.top;
+ // Initialize the decor rect to the entire frame.
+ w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
+ // Intersect with the decor rect, offsetted by window position.
+ w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
+ decorRect.right-offX, decorRect.bottom-offY);
+ // If size compatibility is being applied to the window, the
+ // surface is scaled relative to the screen. Also apply this
+ // scaling to the crop rect. We aren't using the standard rect
+ // scale function because we want to round things to make the crop
+ // always round to a larger rect to ensure we don't crop too
+ // much and hide part of the window that should be seen.
+ if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
+ final float scale = w.mInvGlobalScale;
+ w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
+ w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
+ w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
+ w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
+ }
+ }
+
+ if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
+ w.mLastSystemDecorRect.set(w.mSystemDecorRect);
+ try {
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+ "CROP " + w.mSystemDecorRect.toShortString(), null);
+ mSurface.setWindowCrop(w.mSystemDecorRect);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error setting crop surface of " + w
+ + " crop=" + w.mSystemDecorRect.toShortString(), e);
+ if (!recoveringMemory) {
+ mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
+ }
+ }
+ }
+ }
+
void setSurfaceBoundaries(final boolean recoveringMemory) {
final WindowState w = mWin;
int width, height;
@@ -1003,54 +1056,7 @@ class WindowStateAnimator {
}
}
- // Need to recompute a new system decor rect each time.
- if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
- // Currently can't do this cropping for scaled windows. We'll
- // just keep the crop rect the same as the source surface.
- w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
- } else if (w.mLayer >= mService.mSystemDecorLayer) {
- // Above the decor layer is easy, just use the entire window.
- w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(),
- w.mCompatFrame.height());
- } else {
- final Rect decorRect = mService.mSystemDecorRect;
- // Compute the offset of the window in relation to the decor rect.
- final int offX = w.mXOffset + w.mFrame.left;
- final int offY = w.mYOffset + w.mFrame.top;
- // Initialize the decor rect to the entire frame.
- w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height());
- // Intersect with the decor rect, offsetted by window position.
- w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY,
- decorRect.right-offX, decorRect.bottom-offY);
- // If size compatibility is being applied to the window, the
- // surface is scaled relative to the screen. Also apply this
- // scaling to the crop rect. We aren't using the standard rect
- // scale function because we want to round things to make the crop
- // always round to a larger rect to ensure we don't crop too
- // much and hide part of the window that should be seen.
- if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
- final float scale = w.mInvGlobalScale;
- w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
- w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
- w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
- w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
- }
- }
-
- if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
- w.mLastSystemDecorRect.set(w.mSystemDecorRect);
- try {
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
- "CROP " + w.mSystemDecorRect.toShortString(), null);
- mSurface.setWindowCrop(w.mSystemDecorRect);
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error setting crop surface of " + w
- + " crop=" + w.mSystemDecorRect.toShortString(), e);
- if (!recoveringMemory) {
- mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
- }
- }
- }
+ updateSurfaceWindowCrop(recoveringMemory);
}
public void prepareSurfaceLocked(final boolean recoveringMemory) {
@@ -1181,17 +1187,31 @@ class WindowStateAnimator {
}
void setWallpaperOffset(int left, int top) {
+ mSurfaceX = left;
+ mSurfaceY = top;
+ if (mAnimating) {
+ // If this window (or its app token) is animating, then the position
+ // of the surface will be re-computed on the next animation frame.
+ // We can't poke it directly here because it depends on whatever
+ // transformation is being applied by the animation.
+ return;
+ }
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION setWallpaperOffset");
Surface.openTransaction();
try {
- mSurfaceX = left;
- mSurfaceY = top;
- mSurface.setPosition(left, top);
- mSurface.setWindowCrop(null);
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
+ "POS " + left + ", " + top, null);
+ mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
+ updateSurfaceWindowCrop(false);
} catch (RuntimeException e) {
Slog.w(TAG, "Error positioning surface of " + mWin
+ " pos=(" + left + "," + top + ")", e);
+ } finally {
+ Surface.closeTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION setWallpaperOffset");
}
- Surface.closeTransaction();
}
// This must be called while inside a transaction.
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