1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.tuner; 16 17 import android.content.ComponentName; 18 import android.content.Context; 19 import android.content.Intent; 20 import android.content.pm.ActivityInfo; 21 import android.content.pm.PackageManager; 22 import android.content.pm.PackageManager.NameNotFoundException; 23 import android.content.res.Resources; 24 import android.content.res.TypedArray; 25 import android.content.res.XmlResourceParser; 26 import android.graphics.drawable.Icon; 27 import android.util.AttributeSet; 28 import android.util.Xml; 29 30 import com.android.internal.R; 31 32 import org.xmlpull.v1.XmlPullParser; 33 import org.xmlpull.v1.XmlPullParserException; 34 35 import java.io.IOException; 36 import java.util.ArrayList; 37 import java.util.List; 38 39 public class ShortcutParser { 40 private static final String SHORTCUTS = "android.app.shortcuts"; 41 private static final String SHORTCUT = "shortcut"; 42 private static final String INTENT = "intent"; 43 44 private final Context mContext; 45 private final String mPkg; 46 private final int mResId; 47 private final String mName; 48 private Resources mResources; 49 private AttributeSet mAttrs; 50 ShortcutParser(Context context, ComponentName component)51 public ShortcutParser(Context context, ComponentName component) throws NameNotFoundException { 52 this(context, component.getPackageName(), component.getClassName(), 53 getResId(context, component)); 54 } 55 getResId(Context context, ComponentName component)56 private static int getResId(Context context, ComponentName component) 57 throws NameNotFoundException { 58 ActivityInfo i = context.getPackageManager().getActivityInfo( 59 component, PackageManager.GET_META_DATA); 60 int resId = 0; 61 if (i.metaData != null && i.metaData.containsKey(SHORTCUTS)) { 62 resId = i.metaData.getInt(SHORTCUTS); 63 } 64 return resId; 65 } 66 ShortcutParser(Context context, String pkg, String name, int resId)67 public ShortcutParser(Context context, String pkg, String name, int resId) { 68 mContext = context; 69 mPkg = pkg; 70 mResId = resId; 71 mName = name; 72 } 73 getShortcuts()74 public List<Shortcut> getShortcuts() { 75 List<Shortcut> list = new ArrayList<>(); 76 if (mResId != 0) { 77 try { 78 mResources = mContext.getPackageManager().getResourcesForApplication(mPkg); 79 XmlResourceParser parser = mResources.getXml(mResId); 80 mAttrs = Xml.asAttributeSet(parser); 81 int type; 82 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 83 if (type != XmlPullParser.START_TAG) { 84 continue; 85 } 86 if (parser.getName().equals(SHORTCUT)) { 87 Shortcut c = parseShortcut(parser); 88 if (c != null) { 89 list.add(c); 90 } 91 } 92 } 93 } catch (Exception e) { 94 e.printStackTrace(); 95 } 96 } 97 98 return list; 99 } 100 parseShortcut(XmlResourceParser parser)101 private Shortcut parseShortcut(XmlResourceParser parser) 102 throws IOException, XmlPullParserException { 103 final TypedArray sa = mResources.obtainAttributes(mAttrs, R.styleable.Shortcut); 104 Shortcut c = new Shortcut(); 105 106 final boolean enabled = sa.getBoolean(R.styleable.Shortcut_enabled, true); 107 if (!enabled) return null; 108 final String id = sa.getString(R.styleable.Shortcut_shortcutId); 109 final int iconResId = sa.getResourceId(R.styleable.Shortcut_icon, 0); 110 final int titleResId = sa.getResourceId(R.styleable.Shortcut_shortcutShortLabel, 0); 111 112 c.pkg = mPkg; 113 c.icon = Icon.createWithResource(mPkg, iconResId); 114 c.id = id; 115 c.label = mResources.getString(titleResId); 116 c.name = mName; 117 int type; 118 while ((type = parser.next()) != XmlPullParser.END_TAG) { 119 if (type != XmlPullParser.START_TAG) { 120 continue; 121 } 122 if (parser.getName().equals(INTENT)) { 123 c.intent = Intent.parseIntent(mResources, parser, mAttrs); 124 } 125 } 126 return c.intent != null ? c : null; 127 } 128 129 public static class Shortcut { 130 public Intent intent; 131 public String label; 132 public Icon icon; 133 public String pkg; 134 public String id; 135 public String name; 136 create(Context context, String value)137 public static Shortcut create(Context context, String value) { 138 String[] sp = value.split("::"); 139 try { 140 for (Shortcut shortcut : new ShortcutParser(context, 141 new ComponentName(sp[0], sp[1])).getShortcuts()) { 142 if (shortcut.id.equals(sp[2])) { 143 return shortcut; 144 } 145 } 146 } catch (NameNotFoundException e) { 147 } 148 return null; 149 } 150 151 @Override toString()152 public String toString() { 153 StringBuilder builder = new StringBuilder(); 154 builder.append(pkg); 155 builder.append("::"); 156 builder.append(name); 157 builder.append("::"); 158 builder.append(id); 159 return builder.toString(); 160 } 161 } 162 } 163