am f8b8a3fa: Refector preferred activity code out of package manager.

* commit 'f8b8a3fa955b545843ca264428c620b67c2a5359':
  Refector preferred activity code out of package manager.
This commit is contained in:
Dianne Hackborn
2011-03-04 00:22:40 -08:00
committed by Android Git Automerger
2 changed files with 249 additions and 169 deletions

View File

@@ -2025,10 +2025,10 @@ class PackageManagerService extends IPackageManager.Stub {
final int M = prefs.size(); final int M = prefs.size();
for (int i=0; i<M; i++) { for (int i=0; i<M; i++) {
PreferredActivity pa = prefs.get(i); PreferredActivity pa = prefs.get(i);
if (pa.mMatch != match) { if (pa.mPref.mMatch != match) {
continue; continue;
} }
ActivityInfo ai = getActivityInfo(pa.mActivity, flags); ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags);
if (DEBUG_PREFERRED) { if (DEBUG_PREFERRED) {
Log.v(TAG, "Got preferred activity:"); Log.v(TAG, "Got preferred activity:");
if (ai != null) { if (ai != null) {
@@ -2052,7 +2052,7 @@ class PackageManagerService extends IPackageManager.Stub {
// If the result set is different from when this // If the result set is different from when this
// was created, we need to clear it and re-ask the // was created, we need to clear it and re-ask the
// user their preference. // user their preference.
if (!pa.sameSet(query, priority)) { if (!pa.mPref.sameSet(query, priority)) {
Slog.i(TAG, "Result set changed, dropping preferred activity for " Slog.i(TAG, "Result set changed, dropping preferred activity for "
+ intent + " type " + resolvedType); + intent + " type " + resolvedType);
mSettings.mPreferredActivities.removeFilter(pa); mSettings.mPreferredActivities.removeFilter(pa);
@@ -6358,7 +6358,7 @@ class PackageManagerService extends IPackageManager.Stub {
// remove from preferred activities. // remove from preferred activities.
ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
if (pa.mActivity.getPackageName().equals(deletedPs.name)) { if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) {
removed.add(pa); removed.add(pa);
} }
} }
@@ -6805,7 +6805,7 @@ class PackageManagerService extends IPackageManager.Stub {
PreferredActivity pa = it.next(); PreferredActivity pa = it.next();
if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) { if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
it.remove(); it.remove();
Log.i(TAG, "Removed preferred activity " + pa.mActivity + ":"); Log.i(TAG, "Removed preferred activity " + pa.mPref.mComponent + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " "); filter.dump(new LogPrinter(Log.INFO, TAG), " ");
} }
} }
@@ -6843,7 +6843,7 @@ class PackageManagerService extends IPackageManager.Stub {
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator(); Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) { while (it.hasNext()) {
PreferredActivity pa = it.next(); PreferredActivity pa = it.next();
if (pa.mActivity.getPackageName().equals(packageName)) { if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
it.remove(); it.remove();
changed = true; changed = true;
} }
@@ -6860,12 +6860,12 @@ class PackageManagerService extends IPackageManager.Stub {
while (it.hasNext()) { while (it.hasNext()) {
PreferredActivity pa = it.next(); PreferredActivity pa = it.next();
if (packageName == null if (packageName == null
|| pa.mActivity.getPackageName().equals(packageName)) { || pa.mPref.mComponent.getPackageName().equals(packageName)) {
if (outFilters != null) { if (outFilters != null) {
outFilters.add(new IntentFilter(pa)); outFilters.add(new IntentFilter(pa));
} }
if (outActivities != null) { if (outActivities != null) {
outActivities.add(pa.mActivity); outActivities.add(pa.mPref.mComponent);
} }
} }
} }
@@ -7717,108 +7717,30 @@ class PackageManagerService extends IPackageManager.Stub {
} }
} }
static class PreferredActivity extends IntentFilter { static class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
final int mMatch; final PreferredComponent mPref;
final String[] mSetPackages;
final String[] mSetClasses;
final String[] mSetComponents;
final ComponentName mActivity;
final String mShortActivity;
String mParseError;
PreferredActivity(IntentFilter filter, int match, ComponentName[] set, PreferredActivity(IntentFilter filter, int match, ComponentName[] set,
ComponentName activity) { ComponentName activity) {
super(filter); super(filter);
mMatch = match&IntentFilter.MATCH_CATEGORY_MASK; mPref = new PreferredComponent(this, match, set, activity);
mActivity = activity;
mShortActivity = activity.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<N; i++) {
ComponentName cn = set[i];
if (cn == null) {
mSetPackages = null;
mSetClasses = null;
mSetComponents = null;
return;
}
myPackages[i] = cn.getPackageName().intern();
myClasses[i] = cn.getClassName().intern();
myComponents[i] = cn.flattenToShortString().intern();
}
mSetPackages = myPackages;
mSetClasses = myClasses;
mSetComponents = myComponents;
} else {
mSetPackages = null;
mSetClasses = null;
mSetComponents = null;
}
} }
PreferredActivity(XmlPullParser parser) throws XmlPullParserException, PreferredActivity(XmlPullParser parser) throws XmlPullParserException,
IOException { IOException {
mShortActivity = parser.getAttributeValue(null, "name"); mPref = new PreferredComponent(this, parser);
mActivity = ComponentName.unflattenFromString(mShortActivity);
if (mActivity == null) {
mParseError = "Bad activity name " + mShortActivity;
}
String matchStr = parser.getAttributeValue(null, "match");
mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
String setCountStr = parser.getAttributeValue(null, "set");
int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
String[] myPackages = setCount > 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(); public void writeToXml(XmlSerializer serializer) throws IOException {
//Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth=" mPref.writeToXml(serializer);
// + parser.getDepth() + " tag=" + tagName); serializer.startTag(null, "filter");
if (tagName.equals("set")) { super.writeToXml(serializer);
String name = parser.getAttributeValue(null, "name"); serializer.endTag(null, "filter");
if (name == null) {
if (mParseError == null) {
mParseError = "No name in set tag in preferred activity "
+ mShortActivity;
} }
} else if (setPos >= setCount) {
if (mParseError == null) { public boolean onReadTag(String tagName, XmlPullParser parser)
mParseError = "Too many set tags in preferred activity " throws XmlPullParserException, IOException {
+ mShortActivity; if (tagName.equals("filter")) {
}
} else {
ComponentName cn = ComponentName.unflattenFromString(name);
if (cn == null) {
if (mParseError == null) {
mParseError = "Bad set name " + name + " in preferred activity "
+ mShortActivity;
}
} else {
myPackages[setPos] = cn.getPackageName();
myClasses[setPos] = cn.getClassName();
myComponents[setPos] = name;
setPos++;
}
}
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals("filter")) {
//Log.i(TAG, "Starting to parse filter..."); //Log.i(TAG, "Starting to parse filter...");
readFromXml(parser); readFromXml(parser);
//Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth=" //Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth="
@@ -7829,56 +7751,7 @@ class PackageManagerService extends IPackageManager.Stub {
+ parser.getName()); + parser.getName());
XmlUtils.skipCurrentTag(parser); XmlUtils.skipCurrentTag(parser);
} }
} return true;
if (setPos != setCount) {
if (mParseError == null) {
mParseError = "Not enough set tags (expected " + setCount
+ " but found " + setPos + ") in " + mShortActivity;
}
}
mSetPackages = myPackages;
mSetClasses = myClasses;
mSetComponents = myComponents;
}
public void writeToXml(XmlSerializer serializer) throws IOException {
final int NS = mSetClasses != null ? mSetClasses.length : 0;
serializer.attribute(null, "name", mShortActivity);
serializer.attribute(null, "match", Integer.toHexString(mMatch));
serializer.attribute(null, "set", Integer.toString(NS));
for (int s=0; s<NS; s++) {
serializer.startTag(null, "set");
serializer.attribute(null, "name", mSetComponents[s]);
serializer.endTag(null, "set");
}
serializer.startTag(null, "filter");
super.writeToXml(serializer);
serializer.endTag(null, "filter");
}
boolean sameSet(List<ResolveInfo> 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<NQ; i++) {
ResolveInfo ri = query.get(i);
if (ri.priority != priority) continue;
ActivityInfo ai = ri.activityInfo;
boolean good = false;
for (int j=0; j<NS; j++) {
if (mSetPackages[j].equals(ai.packageName)
&& mSetClasses[j].equals(ai.name)) {
numMatch++;
good = true;
break;
}
}
if (!good) return false;
}
return numMatch == NS;
} }
} }
@@ -8161,24 +8034,12 @@ class PackageManagerService extends IPackageManager.Stub {
new IntentResolver<PreferredActivity, PreferredActivity>() { new IntentResolver<PreferredActivity, PreferredActivity>() {
@Override @Override
protected String packageForFilter(PreferredActivity filter) { protected String packageForFilter(PreferredActivity filter) {
return filter.mActivity.getPackageName(); return filter.mPref.mComponent.getPackageName();
} }
@Override @Override
protected void dumpFilter(PrintWriter out, String prefix, protected void dumpFilter(PrintWriter out, String prefix,
PreferredActivity filter) { PreferredActivity filter) {
out.print(prefix); out.print( filter.mPref.dump(out, prefix, filter);
Integer.toHexString(System.identityHashCode(filter)));
out.print(' ');
out.print(filter.mActivity.flattenToShortString());
out.print(" match=0x");
out.println( Integer.toHexString(filter.mMatch));
if (filter.mSetComponents != null) {
out.print(prefix); out.println(" Selected from:");
for (int i=0; i<filter.mSetComponents.length; i++) {
out.print(prefix); out.print(" ");
out.println(filter.mSetComponents[i]);
}
}
} }
}; };
private final HashMap<String, SharedUserSetting> mSharedUsers = private final HashMap<String, SharedUserSetting> mSharedUsers =
@@ -10010,12 +9871,12 @@ class PackageManagerService extends IPackageManager.Stub {
String tagName = parser.getName(); String tagName = parser.getName();
if (tagName.equals("item")) { if (tagName.equals("item")) {
PreferredActivity pa = new PreferredActivity(parser); PreferredActivity pa = new PreferredActivity(parser);
if (pa.mParseError == null) { if (pa.mPref.getParseError() == null) {
mPreferredActivities.addFilter(pa); mPreferredActivities.addFilter(pa);
} else { } else {
reportSettingsProblem(Log.WARN, reportSettingsProblem(Log.WARN,
"Error in package manager settings: <preferred-activity> " "Error in package manager settings: <preferred-activity> "
+ pa.mParseError + " at " + pa.mPref.getParseError() + " at "
+ parser.getPositionDescription()); + parser.getPositionDescription());
} }
} else { } else {

View File

@@ -0,0 +1,219 @@
/*
* 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;
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 {
public final int mMatch;
public final ComponentName mComponent;
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) {
mCallbacks = callbacks;
mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
mComponent = component;
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<N; i++) {
ComponentName cn = set[i];
if (cn == null) {
mSetPackages = null;
mSetClasses = null;
mSetComponents = null;
return;
}
myPackages[i] = cn.getPackageName().intern();
myClasses[i] = cn.getClassName().intern();
myComponents[i] = cn.flattenToShortString().intern();
}
mSetPackages = myPackages;
mSetClasses = myClasses;
mSetComponents = myComponents;
} else {
mSetPackages = null;
mSetClasses = null;
mSetComponents = null;
}
}
public PreferredComponent(Callbacks callbacks, XmlPullParser parser)
throws XmlPullParserException, IOException {
mCallbacks = callbacks;
mShortComponent = parser.getAttributeValue(null, "name");
mComponent = ComponentName.unflattenFromString(mShortComponent);
if (mComponent == null) {
mParseError = "Bad activity name " + mShortComponent;
}
String matchStr = parser.getAttributeValue(null, "match");
mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
String setCountStr = parser.getAttributeValue(null, "set");
int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
String[] myPackages = setCount > 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("set")) {
String name = parser.getAttributeValue(null, "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) throws IOException {
final int NS = mSetClasses != null ? mSetClasses.length : 0;
serializer.attribute(null, "name", mShortComponent);
if (mMatch != 0) {
serializer.attribute(null, "match", Integer.toHexString(mMatch));
}
serializer.attribute(null, "set", Integer.toString(NS));
for (int s=0; s<NS; s++) {
serializer.startTag(null, "set");
serializer.attribute(null, "name", mSetComponents[s]);
serializer.endTag(null, "set");
}
}
public boolean sameSet(List<ResolveInfo> 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<NQ; i++) {
ResolveInfo ri = query.get(i);
if (ri.priority != priority) continue;
ActivityInfo ai = ri.activityInfo;
boolean good = false;
for (int j=0; j<NS; j++) {
if (mSetPackages[j].equals(ai.packageName)
&& mSetClasses[j].equals(ai.name)) {
numMatch++;
good = true;
break;
}
}
if (!good) return false;
}
return numMatch == NS;
}
public void dump(PrintWriter out, String prefix, Object ident) {
out.print(prefix); out.print(
Integer.toHexString(System.identityHashCode(ident)));
out.print(' ');
out.print(mComponent.flattenToShortString());
out.print(" match=0x");
out.println( Integer.toHexString(mMatch));
if (mSetComponents != null) {
out.print(prefix); out.println(" Selected from:");
for (int i=0; i<mSetComponents.length; i++) {
out.print(prefix); out.print(" ");
out.println(mSetComponents[i]);
}
}
}
}