Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54b3cb17 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

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

* commit 'f8b8a3fa':
  Refector preferred activity code out of package manager.
parents a6d2c62b f8b8a3fa
Loading
Loading
Loading
Loading
+30 −169
Original line number Diff line number Diff line
@@ -2025,10 +2025,10 @@ class PackageManagerService extends IPackageManager.Stub {
                final int M = prefs.size();
                for (int i=0; i<M; i++) {
                    PreferredActivity pa = prefs.get(i);
                    if (pa.mMatch != match) {
                    if (pa.mPref.mMatch != match) {
                        continue;
                    }
                    ActivityInfo ai = getActivityInfo(pa.mActivity, flags);
                    ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags);
                    if (DEBUG_PREFERRED) {
                        Log.v(TAG, "Got preferred activity:");
                        if (ai != null) {
@@ -2052,7 +2052,7 @@ class PackageManagerService extends IPackageManager.Stub {
                            // If the result set is different from when this
                            // was created, we need to clear it and re-ask the
                            // user their preference.
                            if (!pa.sameSet(query, priority)) {
                            if (!pa.mPref.sameSet(query, priority)) {
                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
                                        + intent + " type " + resolvedType);
                                mSettings.mPreferredActivities.removeFilter(pa);
@@ -6358,7 +6358,7 @@ class PackageManagerService extends IPackageManager.Stub {
                // remove from preferred activities.
                ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
                for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
                    if (pa.mActivity.getPackageName().equals(deletedPs.name)) {
                    if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) {
                        removed.add(pa);
                    }
                }
@@ -6805,7 +6805,7 @@ class PackageManagerService extends IPackageManager.Stub {
                PreferredActivity pa = it.next();
                if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
                    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), "  ");
                }
            }
@@ -6843,7 +6843,7 @@ class PackageManagerService extends IPackageManager.Stub {
        Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
        while (it.hasNext()) {
            PreferredActivity pa = it.next();
            if (pa.mActivity.getPackageName().equals(packageName)) {
            if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
                it.remove();
                changed = true;
            }
@@ -6860,12 +6860,12 @@ class PackageManagerService extends IPackageManager.Stub {
            while (it.hasNext()) {
                PreferredActivity pa = it.next();
                if (packageName == null
                        || pa.mActivity.getPackageName().equals(packageName)) {
                        || pa.mPref.mComponent.getPackageName().equals(packageName)) {
                    if (outFilters != null) {
                        outFilters.add(new IntentFilter(pa));
                    }
                    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 {
        final int mMatch;
        final String[] mSetPackages;
        final String[] mSetClasses;
        final String[] mSetComponents;
        final ComponentName mActivity;
        final String mShortActivity;
        String mParseError;
    static class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
        final PreferredComponent mPref;

        PreferredActivity(IntentFilter filter, int match, ComponentName[] set,
                ComponentName activity) {
            super(filter);
            mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
            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;
            }
            mPref = new PreferredComponent(this, match, set, activity);
        }

        PreferredActivity(XmlPullParser parser) throws XmlPullParserException,
                IOException {
            mShortActivity = parser.getAttributeValue(null, "name");
            mActivity = ComponentName.unflattenFromString(mShortActivity);
            if (mActivity == null) {
                mParseError = "Bad activity name " + mShortActivity;
            mPref = new PreferredComponent(this, parser);
        }
            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;
        public void writeToXml(XmlSerializer serializer) throws IOException {
            mPref.writeToXml(serializer);
            serializer.startTag(null, "filter");
            super.writeToXml(serializer);
            serializer.endTag(null, "filter");
        }

                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 "
                                + mShortActivity;
                        }
                    } else if (setPos >= setCount) {
                        if (mParseError == null) {
                            mParseError = "Too many set tags in preferred activity "
                                + mShortActivity;
                        }
                    } 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")) {
        public boolean onReadTag(String tagName, XmlPullParser parser)
                throws XmlPullParserException, IOException {
            if (tagName.equals("filter")) {
                //Log.i(TAG, "Starting to parse filter...");
                readFromXml(parser);
                //Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth="
@@ -7829,56 +7751,7 @@ class PackageManagerService extends IPackageManager.Stub {
                        + parser.getName());
                XmlUtils.skipCurrentTag(parser);
            }
            }

            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;
            return true;
        }
    }

@@ -8161,24 +8034,12 @@ class PackageManagerService extends IPackageManager.Stub {
                    new IntentResolver<PreferredActivity, PreferredActivity>() {
            @Override
            protected String packageForFilter(PreferredActivity filter) {
                return filter.mActivity.getPackageName();
                return filter.mPref.mComponent.getPackageName();
            }
            @Override
            protected void dumpFilter(PrintWriter out, String prefix,
                    PreferredActivity filter) {
                out.print(prefix); out.print(
                        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]);
                    }
                }
                filter.mPref.dump(out, prefix, filter);
            }
        };
        private final HashMap<String, SharedUserSetting> mSharedUsers =
@@ -10010,12 +9871,12 @@ class PackageManagerService extends IPackageManager.Stub {
                String tagName = parser.getName();
                if (tagName.equals("item")) {
                    PreferredActivity pa = new PreferredActivity(parser);
                    if (pa.mParseError == null) {
                    if (pa.mPref.getParseError() == null) {
                        mPreferredActivities.addFilter(pa);
                    } else {
                        reportSettingsProblem(Log.WARN,
                                "Error in package manager settings: <preferred-activity> "
                                + pa.mParseError + " at "
                                + pa.mPref.getParseError() + " at "
                                + parser.getPositionDescription());
                    }
                } else {
+219 −0
Original line number Diff line number Diff line
/*
 * 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]);
            }
        }
    }
}