summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-03-11 15:16:13 -0700
committerDianne Hackborn <hackbod@google.com>2015-03-12 17:07:51 -0700
commita83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d (patch)
tree2b0f1d1e65920fdbf7e3b7867070ee32776f246e /core
parentd6ee06a0c86d9d1556bb4b15c9aaea538e415e38 (diff)
downloadframeworks_base-a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d.zip
frameworks_base-a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d.tar.gz
frameworks_base-a83ce1dd2ad3a6b71e90ff4845afc1299fe17b9d.tar.bz2
More work on collecting assist data.
Optimize parceling of AssistData (which is now renamed to AssistStructure) by pooling duplicated class name strings. Change text associated with a view node to a CharSequence, so styling information comes along. Include global text attributes -- size, colors, etc. Introduce a new AssistContent structure, which allows us to propagate information about the intent and data the activity is looking at. This further allows us to propagate permission grants, so the assistant can dig in to that data. The default implementation propagates the base intent of an activity, so if for example you bring up the assistant while doing a share the assistant itself has the same information and access that was given to the share activity (so it could for example share it in another way if it wanted to). Did some optimization of loading PersistableBundle from xml, to avoid duplicating hash maps and such. Changed how we dispatch ACTION_ASSIST to no longer include the more detailed AssistStructure (and new AssistContent) data when launching; now the example code that intercepts that needs to be sure to ask for assist data when it starts its session. This is more like it will finally be, and allows us to get to the UI more quickly. Change-Id: I88420a55761bf48d34ce3013e81bd96a0e087637
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/Activity.java28
-rw-r--r--core/java/android/app/ActivityManager.java6
-rw-r--r--core/java/android/app/ActivityThread.java11
-rw-r--r--core/java/android/app/AssistContent.aidl19
-rw-r--r--core/java/android/app/AssistContent.java124
-rw-r--r--core/java/android/app/AssistStructure.aidl19
-rw-r--r--core/java/android/app/AssistStructure.java (renamed from core/java/android/app/AssistData.java)169
-rw-r--r--core/java/android/app/ISearchManager.aidl2
-rw-r--r--core/java/android/app/SearchManager.java6
-rw-r--r--core/java/android/content/Intent.java17
-rw-r--r--core/java/android/os/BaseBundle.java3
-rw-r--r--core/java/android/os/Bundle.java23
-rw-r--r--core/java/android/os/PersistableBundle.java40
-rw-r--r--core/java/android/os/PooledStringReader.java50
-rw-r--r--core/java/android/os/PooledStringWriter.java76
-rw-r--r--core/java/android/view/PhoneWindow.java2
-rw-r--r--core/java/android/view/View.java8
-rw-r--r--core/java/android/view/ViewAssistStructure.java (renamed from core/java/android/view/ViewAssistData.java)9
-rw-r--r--core/java/android/widget/Switch.java13
-rw-r--r--core/java/android/widget/TextView.java11
-rw-r--r--core/java/com/android/internal/util/XmlUtils.java58
21 files changed, 593 insertions, 101 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9f8befe..02f33b4 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1547,17 +1547,35 @@ public class Activity extends ContextThemeWrapper
* {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
* application. You can override this method to place into the bundle anything
* you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
- * of the assist Intent. The default implementation automatically generates a
- * {@link AssistData} from your activity and places it in to the Bundle; if you
- * don't want your UI reported to the assistant, don't call this default
- * implementation.
+ * of the assist Intent.
*
* <p>This function will be called after any global assist callbacks that had
* been registered with {@link Application#registerOnProvideAssistDataListener
* Application.registerOnProvideAssistDataListener}.
*/
public void onProvideAssistData(Bundle data) {
- data.putParcelable(AssistData.ASSIST_KEY, new AssistData(this));
+ }
+
+ /**
+ * This is called when the user is requesting an assist, to provide references
+ * to content related to the current activity. Before being called, the
+ * {@code outContent} Intent is filled with the base Intent of the activity (the Intent
+ * returned by {@link #getIntent()}). The Intent's extras are stripped of any types
+ * that are not valid for {@link PersistableBundle} or non-framework Parcelables, and
+ * the flags {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION} and
+ * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} are cleared from the Intent.
+ *
+ * <p>Custom implementation may adjust the content intent to better reflect the top-level
+ * context of the activity, and fill in its ClipData with additional content of
+ * interest that the user is currently viewing. For example, an image gallery application
+ * that has launched in to an activity allowing the user to swipe through pictures should
+ * modify the intent to reference the current image they are looking it; such an
+ * application when showing a list of pictures should add a ClipData that has
+ * references to all of the pictures currently visible on screen.</p>
+ *
+ * @param outContent The assist content to return.
+ */
+ public void onProvideAssistContent(AssistContent outContent) {
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c525ef2..29b024ac 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -309,6 +309,12 @@ public class ActivityManager {
/** @hide Process is being cached for later use and is empty. */
public static final int PROCESS_STATE_CACHED_EMPTY = 13;
+ /** @hide requestType for assist context: only basic information. */
+ public static final int ASSIST_CONTEXT_BASIC = 0;
+
+ /** @hide requestType for assist context: generate full AssistStructure. */
+ public static final int ASSIST_CONTEXT_FULL = 1;
+
/**
* Lock task mode is not active.
*/
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 97793c5..7b8ec74 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2519,6 +2519,17 @@ public final class ActivityThread {
if (r != null) {
r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
r.activity.onProvideAssistData(data);
+ if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
+ data.putParcelable(AssistStructure.ASSIST_KEY, new AssistStructure(r.activity));
+ AssistContent content = new AssistContent();
+ Intent intent = new Intent(r.activity.getIntent());
+ intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
+ intent.removeUnsafeExtras();
+ content.setIntent(intent);
+ r.activity.onProvideAssistContent(content);
+ data.putParcelable(AssistContent.ASSIST_KEY, content);
+ }
}
if (data.isEmpty()) {
data = null;
diff --git a/core/java/android/app/AssistContent.aidl b/core/java/android/app/AssistContent.aidl
new file mode 100644
index 0000000..a6321bf
--- /dev/null
+++ b/core/java/android/app/AssistContent.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2015, 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 android.app;
+
+parcelable AssistContent;
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
new file mode 100644
index 0000000..ace4af7
--- /dev/null
+++ b/core/java/android/app/AssistContent.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 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 android.app;
+
+import android.content.ClipData;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Holds information about the content an application is viewing, to hand to an
+ * assistant at the user's request. This is filled in by
+ * {@link Activity#onProvideAssistContent Activity.onProvideAssistContent}.
+ */
+public class AssistContent implements Parcelable {
+ private Intent mIntent;
+ private ClipData mClipData;
+
+ /**
+ * Key name this data structure is stored in the Bundle generated by
+ * {@link Activity#onProvideAssistData}.
+ */
+ public static final String ASSIST_KEY = "android:assist_content";
+
+ /**
+ * Retrieve the framework-generated AssistContent that is stored within
+ * the Bundle filled in by {@link Activity#onProvideAssistContent}.
+ */
+ public static AssistContent getAssistContent(Bundle assistBundle) {
+ return assistBundle.getParcelable(ASSIST_KEY);
+ }
+
+ public AssistContent() {
+ }
+
+ /**
+ * Sets the Intent associated with the content, describing the current top-level context of
+ * the activity. If this contains a reference to a piece of data related to the activity,
+ * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibilty
+ * service can access it.
+ */
+ public void setIntent(Intent intent) {
+ mIntent = intent;
+ }
+
+ /**
+ * Return the current {@link #setIntent}, which you can modify in-place.
+ */
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * Optional additional content items that are involved with
+ * the current UI. Access to this content will be granted to the assistant as if you
+ * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+ */
+ public void setClipData(ClipData clip) {
+ mClipData = clip;
+ }
+
+ /**
+ * Return the current {@link #setClipData}, which you can modify in-place.
+ */
+ public ClipData getClipData() {
+ return mClipData;
+ }
+
+ AssistContent(Parcel in) {
+ if (in.readInt() != 0) {
+ mIntent = Intent.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mClipData = ClipData.CREATOR.createFromParcel(in);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (mIntent != null) {
+ dest.writeInt(1);
+ mIntent.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mClipData != null) {
+ dest.writeInt(1);
+ mClipData.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ }
+
+ public static final Parcelable.Creator<AssistContent> CREATOR
+ = new Parcelable.Creator<AssistContent>() {
+ public AssistContent createFromParcel(Parcel in) {
+ return new AssistContent(in);
+ }
+
+ public AssistContent[] newArray(int size) {
+ return new AssistContent[size];
+ }
+ };
+}
diff --git a/core/java/android/app/AssistStructure.aidl b/core/java/android/app/AssistStructure.aidl
new file mode 100644
index 0000000..07fb2453
--- /dev/null
+++ b/core/java/android/app/AssistStructure.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2015, 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 android.app;
+
+parcelable AssistStructure;
diff --git a/core/java/android/app/AssistData.java b/core/java/android/app/AssistStructure.java
index 7b5eb6d..25153fc 100644
--- a/core/java/android/app/AssistData.java
+++ b/core/java/android/app/AssistStructure.java
@@ -17,13 +17,19 @@
package android.app;
import android.content.ComponentName;
+import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PooledStringReader;
+import android.os.PooledStringWriter;
+import android.text.TextPaint;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
-import android.view.ViewAssistData;
+import android.view.ViewAssistStructure;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
@@ -34,28 +40,32 @@ import java.util.ArrayList;
/**
* Assist data automatically created by the platform's implementation
* of {@link Activity#onProvideAssistData}. Retrieve it from the assist
- * data with {@link #getAssistData(android.os.Bundle)}.
+ * data with {@link #getAssistStructure(android.os.Bundle)}.
*/
-final public class AssistData implements Parcelable {
- static final String TAG = "AssistData";
+final public class AssistStructure implements Parcelable {
+ static final String TAG = "AssistStructure";
/**
* Key name this data structure is stored in the Bundle generated by
* {@link Activity#onProvideAssistData}.
*/
- public static final String ASSIST_KEY = "android:assist";
+ public static final String ASSIST_KEY = "android:assist_structure";
final ComponentName mActivityComponent;
final ArrayList<ViewNodeImpl> mRootViews = new ArrayList<>();
- ViewAssistDataImpl mTmpViewAssistDataImpl = new ViewAssistDataImpl();
+ ViewAssistStructureImpl mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
Bundle mTmpExtras = new Bundle();
- final static class ViewAssistDataImpl extends ViewAssistData {
+ final static class ViewAssistStructureImpl extends ViewAssistStructure {
CharSequence mText;
int mTextSelectionStart = -1;
int mTextSelectionEnd = -1;
+ int mTextColor = ViewNode.TEXT_COLOR_UNDEFINED;
+ int mTextBackgroundColor = ViewNode.TEXT_COLOR_UNDEFINED;
+ float mTextSize = 0;
+ int mTextStyle = 0;
CharSequence mHint;
@Override
@@ -72,6 +82,33 @@ final public class AssistData implements Parcelable {
}
@Override
+ public void setTextPaint(TextPaint paint) {
+ mTextColor = paint.getColor();
+ mTextBackgroundColor = paint.bgColor;
+ mTextSize = paint.getTextSize();
+ mTextStyle = 0;
+ Typeface tf = paint.getTypeface();
+ if (tf != null) {
+ if (tf.isBold()) {
+ mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
+ }
+ if (tf.isItalic()) {
+ mTextStyle |= ViewNode.TEXT_STYLE_ITALIC;
+ }
+ }
+ int pflags = paint.getFlags();
+ if ((pflags& Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
+ mTextStyle |= ViewNode.TEXT_STYLE_BOLD;
+ }
+ if ((pflags& Paint.UNDERLINE_TEXT_FLAG) != 0) {
+ mTextStyle |= ViewNode.TEXT_STYLE_UNDERLINE;
+ }
+ if ((pflags& Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
+ mTextStyle |= ViewNode.TEXT_STYLE_STRIKE_THRU;
+ }
+ }
+
+ @Override
public void setHint(CharSequence hint) {
mHint = hint;
}
@@ -98,29 +135,45 @@ final public class AssistData implements Parcelable {
}
final static class ViewNodeTextImpl {
- final String mText;
+ final CharSequence mText;
final int mTextSelectionStart;
final int mTextSelectionEnd;
+ int mTextColor;
+ int mTextBackgroundColor;
+ float mTextSize;
+ int mTextStyle;
final String mHint;
- ViewNodeTextImpl(ViewAssistDataImpl data) {
- mText = data.mText != null ? data.mText.toString() : null;
+ ViewNodeTextImpl(ViewAssistStructureImpl data) {
+ mText = data.mText;
mTextSelectionStart = data.mTextSelectionStart;
mTextSelectionEnd = data.mTextSelectionEnd;
+ mTextColor = data.mTextColor;
+ mTextBackgroundColor = data.mTextBackgroundColor;
+ mTextSize = data.mTextSize;
+ mTextStyle = data.mTextStyle;
mHint = data.mHint != null ? data.mHint.toString() : null;
}
ViewNodeTextImpl(Parcel in) {
- mText = in.readString();
+ mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mTextSelectionStart = in.readInt();
mTextSelectionEnd = in.readInt();
+ mTextColor = in.readInt();
+ mTextBackgroundColor = in.readInt();
+ mTextSize = in.readFloat();
+ mTextStyle = in.readInt();
mHint = in.readString();
}
void writeToParcel(Parcel out) {
- out.writeString(mText);
+ TextUtils.writeToParcel(mText, out, 0);
out.writeInt(mTextSelectionStart);
out.writeInt(mTextSelectionEnd);
+ out.writeInt(mTextColor);
+ out.writeInt(mTextBackgroundColor);
+ out.writeFloat(mTextSize);
+ out.writeInt(mTextStyle);
out.writeString(mHint);
}
}
@@ -155,7 +208,7 @@ final public class AssistData implements Parcelable {
final ViewNodeImpl[] mChildren;
- ViewNodeImpl(AssistData assistData, View view, int left, int top,
+ ViewNodeImpl(AssistStructure assistStructure, View view, int left, int top,
CharSequence contentDescription) {
mX = left;
mY = top;
@@ -197,18 +250,18 @@ final public class AssistData implements Parcelable {
mFlags = flags;
mClassName = view.getAccessibilityClassName().toString();
mContentDescription = contentDescription != null ? contentDescription.toString() : null;
- final ViewAssistDataImpl viewData = assistData.mTmpViewAssistDataImpl;
- final Bundle extras = assistData.mTmpExtras;
- view.onProvideAssistData(viewData, extras);
+ final ViewAssistStructureImpl viewData = assistStructure.mTmpViewAssistStructureImpl;
+ final Bundle extras = assistStructure.mTmpExtras;
+ view.onProvideAssistStructure(viewData, extras);
if (viewData.mText != null || viewData.mHint != null) {
mText = new ViewNodeTextImpl(viewData);
- assistData.mTmpViewAssistDataImpl = new ViewAssistDataImpl();
+ assistStructure.mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
} else {
mText = null;
}
if (!extras.isEmpty()) {
mExtras = extras;
- assistData.mTmpExtras = new Bundle();
+ assistStructure.mTmpExtras = new Bundle();
} else {
mExtras = null;
}
@@ -218,7 +271,7 @@ final public class AssistData implements Parcelable {
if (NCHILDREN > 0) {
mChildren = new ViewNodeImpl[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNodeImpl(assistData, vg.getChildAt(i));
+ mChildren[i] = new ViewNodeImpl(assistStructure, vg.getChildAt(i));
}
} else {
mChildren = null;
@@ -228,11 +281,11 @@ final public class AssistData implements Parcelable {
}
}
- ViewNodeImpl(AssistData assistData, View view) {
- this(assistData, view, view.getLeft(), view.getTop(), view.getContentDescription());
+ ViewNodeImpl(AssistStructure assistStructure, View view) {
+ this(assistStructure, view, view.getLeft(), view.getTop(), view.getContentDescription());
}
- ViewNodeImpl(Parcel in) {
+ ViewNodeImpl(Parcel in, PooledStringReader preader) {
mX = in.readInt();
mY = in.readInt();
mScrollX = in.readInt();
@@ -240,7 +293,7 @@ final public class AssistData implements Parcelable {
mWidth = in.readInt();
mHeight = in.readInt();
mFlags = in.readInt();
- mClassName = in.readString();
+ mClassName = preader.readString();
mContentDescription = in.readString();
if (in.readInt() != 0) {
mText = new ViewNodeTextImpl(in);
@@ -252,14 +305,14 @@ final public class AssistData implements Parcelable {
if (NCHILDREN > 0) {
mChildren = new ViewNodeImpl[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNodeImpl(in);
+ mChildren[i] = new ViewNodeImpl(in, preader);
}
} else {
mChildren = null;
}
}
- void writeToParcel(Parcel out) {
+ void writeToParcel(Parcel out, PooledStringWriter pwriter) {
out.writeInt(mX);
out.writeInt(mY);
out.writeInt(mScrollX);
@@ -267,7 +320,7 @@ final public class AssistData implements Parcelable {
out.writeInt(mWidth);
out.writeInt(mHeight);
out.writeInt(mFlags);
- out.writeString(mClassName);
+ pwriter.writeString(mClassName);
out.writeString(mContentDescription);
if (mText != null) {
out.writeInt(1);
@@ -280,7 +333,7 @@ final public class AssistData implements Parcelable {
final int NCHILDREN = mChildren.length;
out.writeInt(NCHILDREN);
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i].writeToParcel(out);
+ mChildren[i].writeToParcel(out, pwriter);
}
} else {
out.writeInt(0);
@@ -292,6 +345,17 @@ final public class AssistData implements Parcelable {
* Provides access to information about a single view in the assist data.
*/
static public class ViewNode {
+ /**
+ * Magic value for text color that has not been defined, which is very unlikely
+ * to be confused with a real text color.
+ */
+ public static final int TEXT_COLOR_UNDEFINED = 1;
+
+ public static final int TEXT_STYLE_BOLD = 1<<0;
+ public static final int TEXT_STYLE_ITALIC = 1<<1;
+ public static final int TEXT_STYLE_UNDERLINE = 1<<2;
+ public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
+
ViewNodeImpl mImpl;
public ViewNode() {
@@ -373,7 +437,7 @@ final public class AssistData implements Parcelable {
return mImpl.mContentDescription;
}
- public String getText() {
+ public CharSequence getText() {
return mImpl.mText != null ? mImpl.mText.mText : null;
}
@@ -385,6 +449,22 @@ final public class AssistData implements Parcelable {
return mImpl.mText != null ? mImpl.mText.mTextSelectionEnd : -1;
}
+ public int getTextColor() {
+ return mImpl.mText != null ? mImpl.mText.mTextColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ public int getTextBackgroundColor() {
+ return mImpl.mText != null ? mImpl.mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ public float getTextSize() {
+ return mImpl.mText != null ? mImpl.mText.mTextSize : 0;
+ }
+
+ public int getTextStyle() {
+ return mImpl.mText != null ? mImpl.mText.mTextStyle : 0;
+ }
+
public String getHint() {
return mImpl.mText != null ? mImpl.mText.mHint : null;
}
@@ -402,7 +482,7 @@ final public class AssistData implements Parcelable {
}
}
- AssistData(Activity activity) {
+ AssistStructure(Activity activity) {
mActivityComponent = activity.getComponentName();
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
activity.getActivityToken());
@@ -417,11 +497,12 @@ final public class AssistData implements Parcelable {
}
}
- AssistData(Parcel in) {
+ AssistStructure(Parcel in) {
+ PooledStringReader preader = new PooledStringReader(in);
mActivityComponent = ComponentName.readFromParcel(in);
final int N = in.readInt();
for (int i=0; i<N; i++) {
- mRootViews.add(new ViewNodeImpl(in));
+ mRootViews.add(new ViewNodeImpl(in, preader));
}
//dump();
}
@@ -450,10 +531,14 @@ final public class AssistData implements Parcelable {
if (contentDescription != null) {
Log.i(TAG, prefix + " Content description: " + contentDescription);
}
- String text = node.getText();
+ CharSequence text = node.getText();
if (text != null) {
Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
+ node.getTextSelectionEnd() + "): " + text);
+ Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
+ + node.getTextStyle());
+ Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
+ + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
}
String hint = node.getHint();
if (hint != null) {
@@ -476,10 +561,10 @@ final public class AssistData implements Parcelable {
}
/**
- * Retrieve the framework-generated AssistData that is stored within
+ * Retrieve the framework-generated AssistStructure that is stored within
* the Bundle filled in by {@link Activity#onProvideAssistData}.
*/
- public static AssistData getAssistData(Bundle assistBundle) {
+ public static AssistStructure getAssistStructure(Bundle assistBundle) {
return assistBundle.getParcelable(ASSIST_KEY);
}
@@ -509,23 +594,25 @@ final public class AssistData implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
int start = out.dataPosition();
+ PooledStringWriter pwriter = new PooledStringWriter(out);
ComponentName.writeToParcel(mActivityComponent, out);
final int N = mRootViews.size();
out.writeInt(N);
for (int i=0; i<N; i++) {
- mRootViews.get(i).writeToParcel(out);
+ mRootViews.get(i).writeToParcel(out, pwriter);
}
+ pwriter.finish();
Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
}
- public static final Parcelable.Creator<AssistData> CREATOR
- = new Parcelable.Creator<AssistData>() {
- public AssistData createFromParcel(Parcel in) {
- return new AssistData(in);
+ public static final Parcelable.Creator<AssistStructure> CREATOR
+ = new Parcelable.Creator<AssistStructure>() {
+ public AssistStructure createFromParcel(Parcel in) {
+ return new AssistStructure(in);
}
- public AssistData[] newArray(int size) {
- return new AssistData[size];
+ public AssistStructure[] newArray(int size) {
+ return new AssistStructure[size];
}
};
}
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 03e7ff4..6d27910 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -31,5 +31,5 @@ interface ISearchManager {
ComponentName getGlobalSearchActivity();
ComponentName getWebSearchActivity();
ComponentName getAssistIntent(int userHandle);
- boolean launchAssistAction(int requestType, String hint, int userHandle);
+ boolean launchAssistAction(String hint, int userHandle);
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index d7c4467..fa27631 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -969,7 +969,7 @@ public class SearchManager
intent.setComponent(comp);
if (inclContext) {
IActivityManager am = ActivityManagerNative.getDefault();
- Bundle extras = am.getAssistContextExtras(0);
+ Bundle extras = am.getAssistContextExtras(ActivityManager.ASSIST_CONTEXT_BASIC);
if (extras != null) {
intent.replaceExtras(extras);
}
@@ -985,12 +985,12 @@ public class SearchManager
* Launch an assist action for the current top activity.
* @hide
*/
- public boolean launchAssistAction(int requestType, String hint, int userHandle) {
+ public boolean launchAssistAction(String hint, int userHandle) {
try {
if (mService == null) {
return false;
}
- return mService.launchAssistAction(requestType, hint, userHandle);
+ return mService.launchAssistAction(hint, userHandle);
} catch (RemoteException re) {
Log.e(TAG, "launchAssistAction() failed: " + re);
return false;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3222b2b..2ed8c44 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1239,6 +1239,13 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.ASSIST_PACKAGE";
/**
+ * An optional field on {@link #ACTION_ASSIST} containing the uid of the current foreground
+ * application package at the time the assist was invoked.
+ */
+ public static final String EXTRA_ASSIST_UID
+ = "android.intent.extra.ASSIST_UID";
+
+ /**
* An optional field on {@link #ACTION_ASSIST} and containing additional contextual
* information supplied by the current foreground app at the time of the assist request.
* This is a {@link Bundle} of additional data.
@@ -5386,6 +5393,16 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * Filter extras to only basic types.
+ * @hide
+ */
+ public void removeUnsafeExtras() {
+ if (mExtras != null) {
+ mExtras.filterValues();
+ }
+ }
+
+ /**
* Retrieve any special flags associated with this intent. You will
* normally just set them with {@link #setFlags} and let the system
* take the appropriate action with them.
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 7f8c95b..c373308 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -22,7 +22,6 @@ import android.util.Log;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Map;
import java.util.Set;
/**
@@ -309,7 +308,7 @@ public class BaseBundle {
*
* @param map a Map
*/
- void putAll(Map map) {
+ void putAll(ArrayMap map) {
unparcel();
mMap.putAll(map);
}
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index c20024a..5e9b8c1 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -252,6 +252,29 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
/**
+ * Filter values in Bundle to only basic types.
+ * @hide
+ */
+ public void filterValues() {
+ unparcel();
+ if (mMap != null) {
+ for (int i = mMap.size() - 1; i >= 0; i--) {
+ Object value = mMap.valueAt(i);
+ if (PersistableBundle.isValidType(value)) {
+ continue;
+ }
+ if (value instanceof Bundle) {
+ ((Bundle)value).filterValues();
+ }
+ if (value.getClass().getName().startsWith("android.")) {
+ continue;
+ }
+ mMap.removeAt(i);
+ }
+ }
+ }
+
+ /**
* Inserts a byte value into the mapping of this Bundle, replacing
* any existing value for the given key.
*
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index a467c87..ea180b2 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -45,6 +45,16 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL;
}
+ /** @hide */
+ public static boolean isValidType(Object value) {
+ return (value instanceof Integer) || (value instanceof Long) ||
+ (value instanceof Double) || (value instanceof String) ||
+ (value instanceof int[]) || (value instanceof long[]) ||
+ (value instanceof double[]) || (value instanceof String[]) ||
+ (value instanceof PersistableBundle) || (value == null) ||
+ (value instanceof Boolean) || (value instanceof boolean[]);
+ }
+
/**
* Constructs a new, empty PersistableBundle.
*/
@@ -78,29 +88,22 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
* @param map a Map containing only those items that can be persisted.
* @throws IllegalArgumentException if any element of #map cannot be persisted.
*/
- private PersistableBundle(Map<String, Object> map) {
+ private PersistableBundle(ArrayMap<String, Object> map) {
super();
// First stuff everything in.
putAll(map);
// Now verify each item throwing an exception if there is a violation.
- Set<String> keys = map.keySet();
- Iterator<String> iterator = keys.iterator();
- while (iterator.hasNext()) {
- String key = iterator.next();
- Object value = map.get(key);
- if (value instanceof Map) {
+ final int N = mMap.size();
+ for (int i=0; i<N; i++) {
+ Object value = mMap.valueAt(i);
+ if (value instanceof ArrayMap) {
// Fix up any Maps by replacing them with PersistableBundles.
- putPersistableBundle(key, new PersistableBundle((Map<String, Object>) value));
- } else if (!(value instanceof Integer) && !(value instanceof Long) &&
- !(value instanceof Double) && !(value instanceof String) &&
- !(value instanceof int[]) && !(value instanceof long[]) &&
- !(value instanceof double[]) && !(value instanceof String[]) &&
- !(value instanceof PersistableBundle) && (value != null) &&
- !(value instanceof Boolean) && !(value instanceof boolean[])) {
- throw new IllegalArgumentException("Bad value in PersistableBundle key=" + key +
- " value=" + value);
+ mMap.setValueAt(i, new PersistableBundle((ArrayMap<String, Object>) value));
+ } else if (!isValidType(value)) {
+ throw new IllegalArgumentException("Bad value in PersistableBundle key="
+ + mMap.keyAt(i) + " value=" + value);
}
}
}
@@ -242,8 +245,9 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
(event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
if (event == XmlPullParser.START_TAG) {
- return new PersistableBundle((Map<String, Object>)
- XmlUtils.readThisMapXml(in, startTag, tagName, new MyReadMapCallback()));
+ return new PersistableBundle((ArrayMap<String, Object>)
+ XmlUtils.readThisArrayMapXml(in, startTag, tagName,
+ new MyReadMapCallback()));
}
}
return EMPTY;
diff --git a/core/java/android/os/PooledStringReader.java b/core/java/android/os/PooledStringReader.java
new file mode 100644
index 0000000..7795957
--- /dev/null
+++ b/core/java/android/os/PooledStringReader.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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 android.os;
+
+/**
+ * Helper class for reading pooling strings from a Parcel. It must be used
+ * in conjunction with {@link android.os.PooledStringWriter}. This really needs
+ * to be pushed in to Parcel itself, but doing that is... complicated.
+ * @hide
+ */
+public class PooledStringReader {
+ private final Parcel mIn;
+
+ /**
+ * The pool of strings we have collected so far.
+ */
+ private final String[] mPool;
+
+ public PooledStringReader(Parcel in) {
+ mIn = in;
+ final int size = in.readInt();
+ mPool = new String[size];
+ }
+
+ public String readString() {
+ int idx = mIn.readInt();
+ if (idx >= 0) {
+ return mPool[idx];
+ } else {
+ idx = (-idx) - 1;
+ String str = mIn.readString();
+ mPool[idx] = str;
+ return str;
+ }
+ }
+}
diff --git a/core/java/android/os/PooledStringWriter.java b/core/java/android/os/PooledStringWriter.java
new file mode 100644
index 0000000..eac297d
--- /dev/null
+++ b/core/java/android/os/PooledStringWriter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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 android.os;
+
+import java.util.HashMap;
+
+/**
+ * Helper class for writing pooled strings into a Parcel. It must be used
+ * in conjunction with {@link android.os.PooledStringReader}. This really needs
+ * to be pushed in to Parcel itself, but doing that is... complicated.
+ * @hide
+ */
+public class PooledStringWriter {
+ private final Parcel mOut;
+
+ /**
+ * Book-keeping for writing pooled string objects, mapping strings we have
+ * written so far to their index in the pool. We deliberately use HashMap
+ * here since performance is critical, we expect to be doing lots of adds to
+ * it, and it is only a temporary object so its overall memory footprint is
+ * not a signifciant issue.
+ */
+ private final HashMap<String, Integer> mPool;
+
+ /**
+ * Book-keeping for writing pooling string objects, indicating where we
+ * started writing the pool, which is where we need to ultimately store
+ * how many strings are in the pool.
+ */
+ private int mStart;
+
+ /**
+ * Next available index in the pool.
+ */
+ private int mNext;
+
+ public PooledStringWriter(Parcel out) {
+ mOut = out;
+ mPool = new HashMap<>();
+ mStart = out.dataPosition();
+ out.writeInt(0); // reserve space for final pool size.
+ }
+
+ public void writeString(String str) {
+ final Integer cur = mPool.get(str);
+ if (cur != null) {
+ mOut.writeInt(cur);
+ } else {
+ mPool.put(str, mNext);
+ mOut.writeInt(-(mNext+1));
+ mOut.writeString(str);
+ mNext++;
+ }
+ }
+
+ public void finish() {
+ final int pos = mOut.dataPosition();
+ mOut.setDataPosition(mStart);
+ mOut.writeInt(mNext);
+ mOut.setDataPosition(pos);
+ }
+}
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index d4b14f6..cf5affc 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -4158,7 +4158,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
// On TVs, if the app doesn't implement search, we want to launch assist.
return ((SearchManager)getContext().getSystemService(Context.SEARCH_SERVICE))
- .launchAssistAction(0, null, UserHandle.myUserId());
+ .launchAssistAction(null, UserHandle.myUserId());
}
return result;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4f2d4a6..69eb7b4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5620,12 +5620,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Called when assist data is being retrieved from a view as part of
+ * Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
- * @param data
- * @param extras
+ * @param structure Additional standard structured view structure to supply.
+ * @param extras Non-standard extensions.
*/
- public void onProvideAssistData(ViewAssistData data, Bundle extras) {
+ public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
}
/**
diff --git a/core/java/android/view/ViewAssistData.java b/core/java/android/view/ViewAssistStructure.java
index 74436ea..5132bb9 100644
--- a/core/java/android/view/ViewAssistData.java
+++ b/core/java/android/view/ViewAssistStructure.java
@@ -16,13 +16,16 @@
package android.view;
+import android.text.TextPaint;
+
/**
- * Container for storing data generated by {@link View#onProvideAssistData
- * View.onProvideAssistData}.
+ * Container for storing additional per-view data generated by {@link View#onProvideAssistStructure
+ * View.onProvideAssistStructure}.
*/
-public abstract class ViewAssistData {
+public abstract class ViewAssistStructure {
public abstract void setText(CharSequence text);
public abstract void setText(CharSequence text, int selectionStart, int selectionEnd);
+ public abstract void setTextPaint(TextPaint paint);
public abstract void setHint(CharSequence hint);
public abstract CharSequence getText();
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index ce1834e..bb290e7 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -46,7 +46,7 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
-import android.view.ViewAssistData;
+import android.view.ViewAssistStructure;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -1363,18 +1363,19 @@ public class Switch extends CompoundButton {
}
@Override
- public void onProvideAssistData(ViewAssistData data, Bundle extras) {
- super.onProvideAssistData(data, extras);
+ public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
+ super.onProvideAssistStructure(structure, extras);
CharSequence switchText = isChecked() ? mTextOn : mTextOff;
if (!TextUtils.isEmpty(switchText)) {
- CharSequence oldText = data.getText();
+ CharSequence oldText = structure.getText();
if (TextUtils.isEmpty(oldText)) {
- data.setText(switchText);
+ structure.setText(switchText);
} else {
StringBuilder newText = new StringBuilder();
newText.append(oldText).append(' ').append(switchText);
- data.setText(newText);
+ structure.setText(newText);
}
+ structure.setTextPaint(mTextPaint);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 628833d..447e9ac 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -115,7 +115,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewAssistData;
+import android.view.ViewAssistStructure;
import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup.LayoutParams;
@@ -8580,13 +8580,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
- public void onProvideAssistData(ViewAssistData data, Bundle extras) {
- super.onProvideAssistData(data, extras);
+ public void onProvideAssistStructure(ViewAssistStructure structure, Bundle extras) {
+ super.onProvideAssistStructure(structure, extras);
final boolean isPassword = hasPasswordTransformationMethod();
if (!isPassword) {
- data.setText(getText(), getSelectionStart(), getSelectionEnd());
+ structure.setText(getText(), getSelectionStart(), getSelectionEnd());
+ structure.setTextPaint(mTextPaint);
}
- data.setHint(getHint());
+ structure.setHint(getHint());
}
/** @hide */
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 2bd607c..0350d61 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
+import android.util.ArrayMap;
import android.util.Base64;
import android.util.Xml;
@@ -822,7 +823,36 @@ public class XmlUtils {
int eventType = parser.getEventType();
do {
if (eventType == parser.START_TAG) {
- Object val = readThisValueXml(parser, name, callback);
+ Object val = readThisValueXml(parser, name, callback, false);
+ map.put(name[0], val);
+ } else if (eventType == parser.END_TAG) {
+ if (parser.getName().equals(endTag)) {
+ return map;
+ }
+ throw new XmlPullParserException(
+ "Expected " + endTag + " end tag at: " + parser.getName());
+ }
+ eventType = parser.next();
+ } while (eventType != parser.END_DOCUMENT);
+
+ throw new XmlPullParserException(
+ "Document ended before " + endTag + " end tag");
+ }
+
+ /**
+ * Like {@link #readThisMapXml}, but returns an ArrayMap instead of HashMap.
+ * @hide
+ */
+ public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
+ String[] name, ReadMapCallback callback)
+ throws XmlPullParserException, java.io.IOException
+ {
+ ArrayMap<String, Object> map = new ArrayMap<>();
+
+ int eventType = parser.getEventType();
+ do {
+ if (eventType == parser.START_TAG) {
+ Object val = readThisValueXml(parser, name, callback, true);
map.put(name[0], val);
} else if (eventType == parser.END_TAG) {
if (parser.getName().equals(endTag)) {
@@ -854,7 +884,7 @@ public class XmlUtils {
*/
public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
String[] name) throws XmlPullParserException, java.io.IOException {
- return readThisListXml(parser, endTag, name, null);
+ return readThisListXml(parser, endTag, name, null, false);
}
/**
@@ -872,14 +902,14 @@ public class XmlUtils {
* @see #readListXml
*/
private static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
- String[] name, ReadMapCallback callback)
+ String[] name, ReadMapCallback callback, boolean arrayMap)
throws XmlPullParserException, java.io.IOException {
ArrayList list = new ArrayList();
int eventType = parser.getEventType();
do {
if (eventType == parser.START_TAG) {
- Object val = readThisValueXml(parser, name, callback);
+ Object val = readThisValueXml(parser, name, callback, arrayMap);
list.add(val);
//System.out.println("Adding to list: " + val);
} else if (eventType == parser.END_TAG) {
@@ -915,7 +945,7 @@ public class XmlUtils {
*/
public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name)
throws XmlPullParserException, java.io.IOException {
- return readThisSetXml(parser, endTag, name, null);
+ return readThisSetXml(parser, endTag, name, null, false);
}
/**
@@ -937,13 +967,14 @@ public class XmlUtils {
* @hide
*/
private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name,
- ReadMapCallback callback) throws XmlPullParserException, java.io.IOException {
+ ReadMapCallback callback, boolean arrayMap)
+ throws XmlPullParserException, java.io.IOException {
HashSet set = new HashSet();
int eventType = parser.getEventType();
do {
if (eventType == parser.START_TAG) {
- Object val = readThisValueXml(parser, name, callback);
+ Object val = readThisValueXml(parser, name, callback, arrayMap);
set.add(val);
//System.out.println("Adding to set: " + val);
} else if (eventType == parser.END_TAG) {
@@ -1292,7 +1323,7 @@ public class XmlUtils {
int eventType = parser.getEventType();
do {
if (eventType == parser.START_TAG) {
- return readThisValueXml(parser, name, null);
+ return readThisValueXml(parser, name, null, false);
} else if (eventType == parser.END_TAG) {
throw new XmlPullParserException(
"Unexpected end tag at: " + parser.getName());
@@ -1308,7 +1339,8 @@ public class XmlUtils {
}
private static final Object readThisValueXml(XmlPullParser parser, String[] name,
- ReadMapCallback callback) throws XmlPullParserException, java.io.IOException {
+ ReadMapCallback callback, boolean arrayMap)
+ throws XmlPullParserException, java.io.IOException {
final String valueName = parser.getAttributeValue(null, "name");
final String tagName = parser.getName();
@@ -1368,19 +1400,21 @@ public class XmlUtils {
return res;
} else if (tagName.equals("map")) {
parser.next();
- res = readThisMapXml(parser, "map", name);
+ res = arrayMap
+ ? readThisArrayMapXml(parser, "map", name, callback)
+ : readThisMapXml(parser, "map", name, callback);
name[0] = valueName;
//System.out.println("Returning value for " + valueName + ": " + res);
return res;
} else if (tagName.equals("list")) {
parser.next();
- res = readThisListXml(parser, "list", name);
+ res = readThisListXml(parser, "list", name, callback, arrayMap);
name[0] = valueName;
//System.out.println("Returning value for " + valueName + ": " + res);
return res;
} else if (tagName.equals("set")) {
parser.next();
- res = readThisSetXml(parser, "set", name);
+ res = readThisSetXml(parser, "set", name, callback, arrayMap);
name[0] = valueName;
//System.out.println("Returning value for " + valueName + ": " + res);
return res;