| /* |
| * Copyright 2018 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.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; |
| final String mPort; |
| final String mPath; |
| final String mPathPattern; |
| final String mPathPrefix; |
| final String mMimeType; |
| |
| TargetData(String scheme, String host, String port, String path, String pathPattern, |
| String pathPrefix, String mimeType) { |
| mScheme = scheme; |
| mHost = host; |
| mPort = port; |
| mPath = path; |
| mPathPattern = pathPattern; |
| mPathPrefix = pathPrefix; |
| mMimeType = mimeType; |
| } |
| |
| public void toStringInner(StringBuilder strBuilder) { |
| if (!TextUtils.isEmpty(mScheme)) { |
| strBuilder.append(" scheme=").append(mScheme); |
| } |
| if (!TextUtils.isEmpty(mHost)) { |
| strBuilder.append(" host=").append(mHost); |
| } |
| if (!TextUtils.isEmpty(mPort)) { |
| strBuilder.append(" port=").append(mPort); |
| } |
| if (!TextUtils.isEmpty(mPath)) { |
| strBuilder.append(" path=").append(mPath); |
| } |
| if (!TextUtils.isEmpty(mPathPattern)) { |
| strBuilder.append(" pathPattern=").append(mPathPattern); |
| } |
| if (!TextUtils.isEmpty(mPathPrefix)) { |
| strBuilder.append(" pathPrefix=").append(mPathPrefix); |
| } |
| if (!TextUtils.isEmpty(mMimeType)) { |
| strBuilder.append(" mimeType=").append(mMimeType); |
| } |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder strBuilder = new StringBuilder(); |
| toStringInner(strBuilder); |
| return strBuilder.toString(); |
| } |
| } |
| |
| final TargetData[] mTargetData; |
| final String mTargetClass; |
| final String[] mCategories; |
| |
| ShareTargetInfo(TargetData[] data, String targetClass, String[] categories) { |
| mTargetData = data; |
| mTargetClass = targetClass; |
| mCategories = categories; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder strBuilder = new StringBuilder(); |
| strBuilder.append("targetClass=").append(mTargetClass); |
| for (int i = 0; i < mTargetData.length; i++) { |
| strBuilder.append(" data={"); |
| mTargetData[i].toStringInner(strBuilder); |
| strBuilder.append("}"); |
| } |
| for (int i = 0; i < mCategories.length; i++) { |
| strBuilder.append(" category=").append(mCategories[i]); |
| } |
| |
| 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); |
| } |
| } |