• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.pm;
17 
18 import android.annotation.NonNull;
19 import android.text.TextUtils;
20 import android.util.TypedXmlPullParser;
21 import android.util.TypedXmlSerializer;
22 
23 import org.xmlpull.v1.XmlPullParser;
24 import org.xmlpull.v1.XmlPullParserException;
25 
26 import java.io.IOException;
27 import java.util.ArrayList;
28 
29 /**
30  * Represents a Share Target definition, read from the application's manifest (shortcuts.xml)
31  */
32 class ShareTargetInfo {
33 
34     private static final String TAG_SHARE_TARGET = "share-target";
35     private static final String ATTR_TARGET_CLASS = "targetClass";
36 
37     private static final String TAG_DATA = "data";
38     private static final String ATTR_SCHEME = "scheme";
39     private static final String ATTR_HOST = "host";
40     private static final String ATTR_PORT = "port";
41     private static final String ATTR_PATH = "path";
42     private static final String ATTR_PATH_PATTERN = "pathPattern";
43     private static final String ATTR_PATH_PREFIX = "pathPrefix";
44     private static final String ATTR_MIME_TYPE = "mimeType";
45 
46     private static final String TAG_CATEGORY = "category";
47     private static final String ATTR_NAME = "name";
48 
49     static class TargetData {
50         final String mScheme;
51         final String mHost;
52         final String mPort;
53         final String mPath;
54         final String mPathPattern;
55         final String mPathPrefix;
56         final String mMimeType;
57 
TargetData(String scheme, String host, String port, String path, String pathPattern, String pathPrefix, String mimeType)58         TargetData(String scheme, String host, String port, String path, String pathPattern,
59                 String pathPrefix, String mimeType) {
60             mScheme = scheme;
61             mHost = host;
62             mPort = port;
63             mPath = path;
64             mPathPattern = pathPattern;
65             mPathPrefix = pathPrefix;
66             mMimeType = mimeType;
67         }
68 
toStringInner(StringBuilder strBuilder)69         public void toStringInner(StringBuilder strBuilder) {
70             if (!TextUtils.isEmpty(mScheme)) {
71                 strBuilder.append(" scheme=").append(mScheme);
72             }
73             if (!TextUtils.isEmpty(mHost)) {
74                 strBuilder.append(" host=").append(mHost);
75             }
76             if (!TextUtils.isEmpty(mPort)) {
77                 strBuilder.append(" port=").append(mPort);
78             }
79             if (!TextUtils.isEmpty(mPath)) {
80                 strBuilder.append(" path=").append(mPath);
81             }
82             if (!TextUtils.isEmpty(mPathPattern)) {
83                 strBuilder.append(" pathPattern=").append(mPathPattern);
84             }
85             if (!TextUtils.isEmpty(mPathPrefix)) {
86                 strBuilder.append(" pathPrefix=").append(mPathPrefix);
87             }
88             if (!TextUtils.isEmpty(mMimeType)) {
89                 strBuilder.append(" mimeType=").append(mMimeType);
90             }
91         }
92 
93         @Override
toString()94         public String toString() {
95             StringBuilder strBuilder = new StringBuilder();
96             toStringInner(strBuilder);
97             return strBuilder.toString();
98         }
99     }
100 
101     final TargetData[] mTargetData;
102     final String mTargetClass;
103     final String[] mCategories;
104 
ShareTargetInfo(TargetData[] data, String targetClass, String[] categories)105     ShareTargetInfo(TargetData[] data, String targetClass, String[] categories) {
106         mTargetData = data;
107         mTargetClass = targetClass;
108         mCategories = categories;
109     }
110 
111     @Override
toString()112     public String toString() {
113         StringBuilder strBuilder = new StringBuilder();
114         strBuilder.append("targetClass=").append(mTargetClass);
115         for (int i = 0; i < mTargetData.length; i++) {
116             strBuilder.append(" data={");
117             mTargetData[i].toStringInner(strBuilder);
118             strBuilder.append("}");
119         }
120         for (int i = 0; i < mCategories.length; i++) {
121             strBuilder.append(" category=").append(mCategories[i]);
122         }
123 
124         return strBuilder.toString();
125     }
126 
saveToXml(@onNull TypedXmlSerializer out)127     void saveToXml(@NonNull TypedXmlSerializer out) throws IOException {
128         out.startTag(null, TAG_SHARE_TARGET);
129 
130         ShortcutService.writeAttr(out, ATTR_TARGET_CLASS, mTargetClass);
131 
132         for (int i = 0; i < mTargetData.length; i++) {
133             out.startTag(null, TAG_DATA);
134             ShortcutService.writeAttr(out, ATTR_SCHEME, mTargetData[i].mScheme);
135             ShortcutService.writeAttr(out, ATTR_HOST, mTargetData[i].mHost);
136             ShortcutService.writeAttr(out, ATTR_PORT, mTargetData[i].mPort);
137             ShortcutService.writeAttr(out, ATTR_PATH, mTargetData[i].mPath);
138             ShortcutService.writeAttr(out, ATTR_PATH_PATTERN, mTargetData[i].mPathPattern);
139             ShortcutService.writeAttr(out, ATTR_PATH_PREFIX, mTargetData[i].mPathPrefix);
140             ShortcutService.writeAttr(out, ATTR_MIME_TYPE, mTargetData[i].mMimeType);
141             out.endTag(null, TAG_DATA);
142         }
143 
144         for (int i = 0; i < mCategories.length; i++) {
145             out.startTag(null, TAG_CATEGORY);
146             ShortcutService.writeAttr(out, ATTR_NAME, mCategories[i]);
147             out.endTag(null, TAG_CATEGORY);
148         }
149 
150         out.endTag(null, TAG_SHARE_TARGET);
151     }
152 
loadFromXml(TypedXmlPullParser parser)153     static ShareTargetInfo loadFromXml(TypedXmlPullParser parser)
154             throws IOException, XmlPullParserException {
155         final String targetClass = ShortcutService.parseStringAttribute(parser, ATTR_TARGET_CLASS);
156         final ArrayList<ShareTargetInfo.TargetData> targetData = new ArrayList<>();
157         final ArrayList<String> categories = new ArrayList<>();
158 
159         int type;
160         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
161             if (type == XmlPullParser.START_TAG) {
162                 switch (parser.getName()) {
163                     case TAG_DATA:
164                         targetData.add(parseTargetData(parser));
165                         break;
166                     case TAG_CATEGORY:
167                         categories.add(ShortcutService.parseStringAttribute(parser, ATTR_NAME));
168                         break;
169                 }
170             } else if (type == XmlPullParser.END_TAG && parser.getName().equals(TAG_SHARE_TARGET)) {
171                 break;
172             }
173         }
174         if (targetData.isEmpty() || targetClass == null || categories.isEmpty()) {
175             return null;
176         }
177         return new ShareTargetInfo(
178                 targetData.toArray(new ShareTargetInfo.TargetData[targetData.size()]),
179                 targetClass, categories.toArray(new String[categories.size()]));
180     }
181 
parseTargetData(TypedXmlPullParser parser)182     private static ShareTargetInfo.TargetData parseTargetData(TypedXmlPullParser parser) {
183         final String scheme = ShortcutService.parseStringAttribute(parser, ATTR_SCHEME);
184         final String host = ShortcutService.parseStringAttribute(parser, ATTR_HOST);
185         final String port = ShortcutService.parseStringAttribute(parser, ATTR_PORT);
186         final String path = ShortcutService.parseStringAttribute(parser, ATTR_PATH);
187         final String pathPattern = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PATTERN);
188         final String pathPrefix = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PREFIX);
189         final String mimeType = ShortcutService.parseStringAttribute(parser, ATTR_MIME_TYPE);
190 
191         return new ShareTargetInfo.TargetData(scheme, host, port, path, pathPattern, pathPrefix,
192                 mimeType);
193     }
194 }
195