summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/ShareTargetInfo.java92
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java75
3 files changed, 179 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/ShareTargetInfo.java b/services/core/java/com/android/server/pm/ShareTargetInfo.java
index 9e8b73e36f69..fdfee773ea74 100644
--- a/services/core/java/com/android/server/pm/ShareTargetInfo.java
+++ b/services/core/java/com/android/server/pm/ShareTargetInfo.java
@@ -15,12 +15,36 @@
*/
package com.android.server.pm;
+import android.annotation.NonNull;
import android.text.TextUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
/**
* Represents a Share Target definition, read from the application's manifest (shortcuts.xml)
*/
class ShareTargetInfo {
+
+ private static final String TAG_SHARE_TARGET = "share-target";
+ private static final String ATTR_TARGET_CLASS = "targetClass";
+
+ private static final String TAG_DATA = "data";
+ private static final String ATTR_SCHEME = "scheme";
+ private static final String ATTR_HOST = "host";
+ private static final String ATTR_PORT = "port";
+ private static final String ATTR_PATH = "path";
+ private static final String ATTR_PATH_PATTERN = "pathPattern";
+ private static final String ATTR_PATH_PREFIX = "pathPrefix";
+ private static final String ATTR_MIME_TYPE = "mimeType";
+
+ private static final String TAG_CATEGORY = "category";
+ private static final String ATTR_NAME = "name";
+
static class TargetData {
final String mScheme;
final String mHost;
@@ -98,4 +122,72 @@ class ShareTargetInfo {
return strBuilder.toString();
}
+
+ void saveToXml(@NonNull XmlSerializer out) throws IOException {
+ out.startTag(null, TAG_SHARE_TARGET);
+
+ ShortcutService.writeAttr(out, ATTR_TARGET_CLASS, mTargetClass);
+
+ for (int i = 0; i < mTargetData.length; i++) {
+ out.startTag(null, TAG_DATA);
+ ShortcutService.writeAttr(out, ATTR_SCHEME, mTargetData[i].mScheme);
+ ShortcutService.writeAttr(out, ATTR_HOST, mTargetData[i].mHost);
+ ShortcutService.writeAttr(out, ATTR_PORT, mTargetData[i].mPort);
+ ShortcutService.writeAttr(out, ATTR_PATH, mTargetData[i].mPath);
+ ShortcutService.writeAttr(out, ATTR_PATH_PATTERN, mTargetData[i].mPathPattern);
+ ShortcutService.writeAttr(out, ATTR_PATH_PREFIX, mTargetData[i].mPathPrefix);
+ ShortcutService.writeAttr(out, ATTR_MIME_TYPE, mTargetData[i].mMimeType);
+ out.endTag(null, TAG_DATA);
+ }
+
+ for (int i = 0; i < mCategories.length; i++) {
+ out.startTag(null, TAG_CATEGORY);
+ ShortcutService.writeAttr(out, ATTR_NAME, mCategories[i]);
+ out.endTag(null, TAG_CATEGORY);
+ }
+
+ out.endTag(null, TAG_SHARE_TARGET);
+ }
+
+ static ShareTargetInfo loadFromXml(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ final String targetClass = ShortcutService.parseStringAttribute(parser, ATTR_TARGET_CLASS);
+ final ArrayList<ShareTargetInfo.TargetData> targetData = new ArrayList<>();
+ final ArrayList<String> categories = new ArrayList<>();
+
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (type == XmlPullParser.START_TAG) {
+ switch (parser.getName()) {
+ case TAG_DATA:
+ targetData.add(parseTargetData(parser));
+ break;
+ case TAG_CATEGORY:
+ categories.add(ShortcutService.parseStringAttribute(parser, ATTR_NAME));
+ break;
+ }
+ } else if (type == XmlPullParser.END_TAG && parser.getName().equals(TAG_SHARE_TARGET)) {
+ break;
+ }
+ }
+ if (targetData.isEmpty() || targetClass == null || categories.isEmpty()) {
+ return null;
+ }
+ return new ShareTargetInfo(
+ targetData.toArray(new ShareTargetInfo.TargetData[targetData.size()]),
+ targetClass, categories.toArray(new String[categories.size()]));
+ }
+
+ private static ShareTargetInfo.TargetData parseTargetData(XmlPullParser parser) {
+ final String scheme = ShortcutService.parseStringAttribute(parser, ATTR_SCHEME);
+ final String host = ShortcutService.parseStringAttribute(parser, ATTR_HOST);
+ final String port = ShortcutService.parseStringAttribute(parser, ATTR_PORT);
+ final String path = ShortcutService.parseStringAttribute(parser, ATTR_PATH);
+ final String pathPattern = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PATTERN);
+ final String pathPrefix = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PREFIX);
+ final String mimeType = ShortcutService.parseStringAttribute(parser, ATTR_MIME_TYPE);
+
+ return new ShareTargetInfo.TargetData(scheme, host, port, path, pathPattern, pathPrefix,
+ mimeType);
+ }
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d6e87aab35fe..06c71baade42 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -73,6 +73,7 @@ class ShortcutPackage extends ShortcutPackageItem {
private static final String TAG_INTENT = "intent";
private static final String TAG_EXTRAS = "extras";
private static final String TAG_SHORTCUT = "shortcut";
+ private static final String TAG_SHARE_TARGET = "share-target";
private static final String TAG_CATEGORIES = "categories";
private static final String TAG_PERSON = "person";
@@ -1453,8 +1454,9 @@ class ShortcutPackage extends ShortcutPackageItem {
public void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
throws IOException, XmlPullParserException {
final int size = mShortcuts.size();
+ final int shareTargetSize = mShareTargets.size();
- if (size == 0 && mApiCallCount == 0) {
+ if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) {
return; // nothing to write.
}
@@ -1470,6 +1472,12 @@ class ShortcutPackage extends ShortcutPackageItem {
getPackageInfo().isBackupAllowed());
}
+ if (!forBackup) {
+ for (int j = 0; j < shareTargetSize; j++) {
+ mShareTargets.get(j).saveToXml(out);
+ }
+ }
+
out.endTag(null, TAG_ROOT);
}
@@ -1627,6 +1635,9 @@ class ShortcutPackage extends ShortcutPackageItem {
// Don't use addShortcut(), we don't need to save the icon.
ret.mShortcuts.put(si.getId(), si);
continue;
+ case TAG_SHARE_TARGET:
+ ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
+ continue;
}
}
ShortcutService.warnForInvalidTag(depth, tag);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 7e6b7da4a058..6c917b7f8636 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -97,16 +97,25 @@ import android.os.UserHandle;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import android.util.SparseArray;
+import android.util.Xml;
import com.android.frameworks.servicestests.R;
+import com.android.internal.util.FastXmlSerializer;
import com.android.server.pm.ShortcutService.ConfigConstants;
import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
import com.android.server.pm.ShortcutUser.PackageWithUser;
import org.mockito.ArgumentCaptor;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -8089,4 +8098,70 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
}
}
+
+ public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
+ List<ShareTargetInfo> expectedValues = new ArrayList<>();
+ expectedValues.add(new ShareTargetInfo(
+ new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
+ "http", "www.google.com", "1234", "somePath", "somePathPattern",
+ "somePathPrefix", "text/plain")}, "com.test.directshare.TestActivity1",
+ new String[]{"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"}));
+ expectedValues.add(new ShareTargetInfo(new ShareTargetInfo.TargetData[]{
+ new ShareTargetInfo.TargetData(null, null, null, null, null, null, "video/mp4"),
+ new ShareTargetInfo.TargetData("content", null, null, null, null, null, "video/*")},
+ "com.test.directshare.TestActivity5",
+ new String[]{"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"}));
+
+ // Write ShareTargets to Xml
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ final XmlSerializer outXml = new FastXmlSerializer();
+ outXml.setOutput(outStream, StandardCharsets.UTF_8.name());
+ outXml.startDocument(null, true);
+ for (int i = 0; i < expectedValues.size(); i++) {
+ expectedValues.get(i).saveToXml(outXml);
+ }
+ outXml.endDocument();
+ outXml.flush();
+
+ // Read ShareTargets from Xml
+ ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new InputStreamReader(inStream));
+ List<ShareTargetInfo> shareTargets = new ArrayList<>();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (type == XmlPullParser.START_TAG && parser.getName().equals("share-target")) {
+ shareTargets.add(ShareTargetInfo.loadFromXml(parser));
+ }
+ }
+
+ // Assert two lists are equal
+ assertNotNull(shareTargets);
+ assertEquals(expectedValues.size(), shareTargets.size());
+
+ for (int i = 0; i < expectedValues.size(); i++) {
+ ShareTargetInfo expected = expectedValues.get(i);
+ ShareTargetInfo actual = shareTargets.get(i);
+
+ assertEquals(expected.mTargetData.length, actual.mTargetData.length);
+ for (int j = 0; j < expected.mTargetData.length; j++) {
+ assertEquals(expected.mTargetData[j].mScheme, actual.mTargetData[j].mScheme);
+ assertEquals(expected.mTargetData[j].mHost, actual.mTargetData[j].mHost);
+ assertEquals(expected.mTargetData[j].mPort, actual.mTargetData[j].mPort);
+ assertEquals(expected.mTargetData[j].mPath, actual.mTargetData[j].mPath);
+ assertEquals(expected.mTargetData[j].mPathPrefix,
+ actual.mTargetData[j].mPathPrefix);
+ assertEquals(expected.mTargetData[j].mPathPattern,
+ actual.mTargetData[j].mPathPattern);
+ assertEquals(expected.mTargetData[j].mMimeType, actual.mTargetData[j].mMimeType);
+ }
+
+ assertEquals(expected.mTargetClass, actual.mTargetClass);
+
+ assertEquals(expected.mCategories.length, actual.mCategories.length);
+ for (int j = 0; j < expected.mCategories.length; j++) {
+ assertEquals(expected.mCategories[j], actual.mCategories[j]);
+ }
+ }
+ }
}