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

Commit d02b21fc authored by Wilhelm Fitzpatrick's avatar Wilhelm Fitzpatrick Committed by Stephen Bird
Browse files

SystemConfig: allow app-link to be set to any possible state

Allow app-link entries in /system/etc/sysconfig to set a system
apps app-link state to any of the available states, and not just
"always" as was previously possible.

If the "state" attribute is not present in an app-link
declaration, the state will default to "always" to preserve
existing behavior.

This change is needed to allow certain apps to be set to the
"always-ask" state so they'll be sure to participate in intent
resolution via the disambugation dialog in the default
configuration.

These setting can be changed by the user via the standard
app-link configuration section in Settings -> Apps.

Ticket: RIDE-335
Change-Id: I2f98c69ebbeb40492d7ae8d33327986675b18b65
(cherry picked from commit 94c32d8b)
parent 6a1cc7ff
Loading
Loading
Loading
Loading
+43 −3
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@

package com.android.server;

import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.FeatureInfo;
@@ -99,7 +105,7 @@ public class SystemConfig {

    // These are the package names of apps which should be in the 'always'
    // URL-handling state upon factory reset.
    final ArraySet<String> mLinkedApps = new ArraySet<>();
    final ArraySet<AppLink> mLinkedApps = new ArraySet<>();

    // These are the permitted backup transport service components
    final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
@@ -148,7 +154,7 @@ public class SystemConfig {
        return mFixedImeApps;
    }

    public ArraySet<String> getLinkedApps() {
    public ArraySet<AppLink> getLinkedApps() {
        return mLinkedApps;
    }

@@ -426,11 +432,12 @@ public class SystemConfig {

                } else if ("app-link".equals(name)) {
                    String pkgname = parser.getAttributeValue(null, "package");
                    String state = parser.getAttributeValue(null, "state");
                    if (pkgname == null) {
                        Slog.w(TAG, "<app-link> without package in " + permFile + " at "
                                + parser.getPositionDescription());
                    } else {
                        mLinkedApps.add(pkgname);
                        mLinkedApps.add(makeLink(pkgname, state));
                    }
                    XmlUtils.skipCurrentTag(parser);
                } else if ("backup-transport-whitelisted-service".equals(name)) {
@@ -471,6 +478,23 @@ public class SystemConfig {
        }
    }

    private AppLink makeLink(String pkgname, String state) {
        AppLink al = new AppLink();
        al.pkgname = pkgname;
        if (state == null || "always".equals(state)) { // default
            al.state = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
        } else if ("always-ask".equals(state)) {
            al.state = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
        } else if ("ask".equals("state")) {
            al.state = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
        } else if ("never".equals("state")) {
            al.state = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
        } else {
            al.state = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
        }
        return al;
    }

    void readPermission(XmlPullParser parser, String name)
            throws IOException, XmlPullParserException {
        if (mPermissions.containsKey(name)) {
@@ -505,4 +529,20 @@ public class SystemConfig {
            XmlUtils.skipCurrentTag(parser);
        }
    }

    /** Simple value class to hold an app-link entry.
     *  It is public because PackageManagerService needs to see it */
    public static class AppLink {
        public String pkgname;
        public int state;

        @Override
        public int hashCode() { return pkgname.hashCode(); }

        @Override
        public boolean equals(Object other) {
            if (!(other instanceof AppLink)) { return false; }
            return pkgname.equals(((AppLink)other).pkgname);
        }
    }
}
+8 −6
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ import com.android.server.IntentResolver;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.SystemConfig.AppLink;
import com.android.server.Watchdog;
import com.android.server.pm.PermissionsState.PermissionState;
import com.android.server.pm.Settings.DatabaseVersion;
@@ -2637,10 +2638,11 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        SystemConfig systemConfig = SystemConfig.getInstance();
        ArraySet<String> packages = systemConfig.getLinkedApps();
        ArraySet<AppLink> links = systemConfig.getLinkedApps();
        ArraySet<String> domains = new ArraySet<String>();
        for (String packageName : packages) {
        for (AppLink link : links) {
            String packageName = link.pkgname;
            PackageParser.Package pkg = mPackages.get(packageName);
            if (pkg != null) {
                if (!pkg.isSystemApp()) {
@@ -2665,11 +2667,11 @@ public class PackageManagerService extends IPackageManager.Stub {
                    // state w.r.t. the formal app-linkage "no verification attempted" state;
                    // and then 'always' in the per-user state actually used for intent resolution.
                    final IntentFilterVerificationInfo ivi;
                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
                            new ArrayList<String>(domains));
                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(
                            packageName, new ArrayList<String>(domains));
                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
                    mSettings.updateIntentFilterVerificationStatusLPw(
                            packageName, link.state, userId);
                } else {
                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
                            + "' does not handle web links");