/* * Copyright (C) 2011 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 com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import android.content.ComponentName; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; import android.util.Slog; import java.io.IOException; import java.io.PrintWriter; import java.util.List; public class PreferredComponent { private static final String TAG_SET = "set"; private static final String ATTR_ALWAYS = "always"; // boolean private static final String ATTR_MATCH = "match"; // number private static final String ATTR_NAME = "name"; // component name private static final String ATTR_SET = "set"; // number public final int mMatch; public final ComponentName mComponent; // Whether this is to be the one that's always chosen. If false, it's the most recently chosen. public boolean mAlways; private final String[] mSetPackages; private final String[] mSetClasses; private final String[] mSetComponents; private final String mShortComponent; private String mParseError; private final Callbacks mCallbacks; public interface Callbacks { public boolean onReadTag(String tagName, XmlPullParser parser) throws XmlPullParserException, IOException; } public PreferredComponent(Callbacks callbacks, int match, ComponentName[] set, ComponentName component, boolean always) { mCallbacks = callbacks; mMatch = match&IntentFilter.MATCH_CATEGORY_MASK; mComponent = component; mAlways = always; mShortComponent = component.flattenToShortString(); mParseError = null; if (set != null) { final int N = set.length; String[] myPackages = new String[N]; String[] myClasses = new String[N]; String[] myComponents = new String[N]; for (int i=0; i 0 ? new String[setCount] : null; String[] myClasses = setCount > 0 ? new String[setCount] : null; String[] myComponents = setCount > 0 ? new String[setCount] : null; int setPos = 0; int outerDepth = parser.getDepth(); int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth=" // + parser.getDepth() + " tag=" + tagName); if (tagName.equals(TAG_SET)) { String name = parser.getAttributeValue(null, ATTR_NAME); if (name == null) { if (mParseError == null) { mParseError = "No name in set tag in preferred activity " + mShortComponent; } } else if (setPos >= setCount) { if (mParseError == null) { mParseError = "Too many set tags in preferred activity " + mShortComponent; } } else { ComponentName cn = ComponentName.unflattenFromString(name); if (cn == null) { if (mParseError == null) { mParseError = "Bad set name " + name + " in preferred activity " + mShortComponent; } } else { myPackages[setPos] = cn.getPackageName(); myClasses[setPos] = cn.getClassName(); myComponents[setPos] = name; setPos++; } } XmlUtils.skipCurrentTag(parser); } else if (!mCallbacks.onReadTag(tagName, parser)) { Slog.w("PreferredComponent", "Unknown element: " + parser.getName()); XmlUtils.skipCurrentTag(parser); } } if (setPos != setCount) { if (mParseError == null) { mParseError = "Not enough set tags (expected " + setCount + " but found " + setPos + ") in " + mShortComponent; } } mSetPackages = myPackages; mSetClasses = myClasses; mSetComponents = myComponents; } public String getParseError() { return mParseError; } public void writeToXml(XmlSerializer serializer, boolean full) throws IOException { final int NS = mSetClasses != null ? mSetClasses.length : 0; serializer.attribute(null, ATTR_NAME, mShortComponent); if (full) { if (mMatch != 0) { serializer.attribute(null, ATTR_MATCH, Integer.toHexString(mMatch)); } serializer.attribute(null, ATTR_ALWAYS, Boolean.toString(mAlways)); serializer.attribute(null, ATTR_SET, Integer.toString(NS)); for (int s=0; s query, int priority) { if (mSetPackages == null) return false; final int NQ = query.size(); final int NS = mSetPackages.length; int numMatch = 0; for (int i=0; i