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

Commit cde90185 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Component Alias initial (rudimentary) prototype"

parents 40aeb2ed fc007928
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -6993,6 +6993,7 @@ public class Intent implements Parcelable, Cloneable {
    private int mContentUserHint = UserHandle.USER_CURRENT;
    /** Token to track instant app launches. Local only; do not copy cross-process. */
    private String mLaunchToken;
    private Intent mOriginalIntent; // Used for the experimental "component alias" feature.

    // ---------------------------------------------------------------------

@@ -7029,6 +7030,7 @@ public class Intent implements Parcelable, Cloneable {
        this.mIdentifier = o.mIdentifier;
        this.mPackage = o.mPackage;
        this.mComponent = o.mComponent;
        this.mOriginalIntent = o.mOriginalIntent;

        if (o.mCategories != null) {
            this.mCategories = new ArraySet<>(o.mCategories);
@@ -8193,6 +8195,22 @@ public class Intent implements Parcelable, Cloneable {
        return mType;
    }


    /**
     * @hide For the experimental component alias feature. Do not use, unless you know what it is.
     */
    @Nullable
    public Intent getOriginalIntent() {
        return mOriginalIntent;
    }

    /**
     * @hide For the experimental component alias feature. Do not use, unless you know what it is.
     */
    public void setOriginalIntent(@Nullable Intent originalIntent) {
        mOriginalIntent = originalIntent;
    }

    /**
     * Return the MIME data type of this intent.  If the type field is
     * explicitly set, that is simply returned.  Otherwise, if the data is set,
@@ -10838,6 +10856,11 @@ public class Intent implements Parcelable, Cloneable {
            mSelector.toShortString(b, secure, comp, extras, clip);
            b.append("}");
        }
        if (mOriginalIntent != null) {
            b.append(" org={");
            mOriginalIntent.toShortString(b, secure, comp, extras, clip);
            b.append("}");
        }
    }

    /** @hide */
@@ -11133,6 +11156,13 @@ public class Intent implements Parcelable, Cloneable {
        }
        out.writeInt(mContentUserHint);
        out.writeBundle(mExtras);

        if (mOriginalIntent != null) {
            out.writeInt(1);
            mOriginalIntent.writeToParcel(out, flags);
        } else {
            out.writeInt(0);
        }
    }

    public static final @android.annotation.NonNull Parcelable.Creator<Intent> CREATOR
@@ -11186,6 +11216,9 @@ public class Intent implements Parcelable, Cloneable {
        }
        mContentUserHint = in.readInt();
        mExtras = in.readBundle();
        if (in.readInt() != 0) {
            mOriginalIntent = new Intent(in);
        }
    }

    /**
@@ -11410,6 +11443,9 @@ public class Intent implements Parcelable, Cloneable {
        if (mClipData != null) {
            mClipData.prepareToLeaveProcess(leavingPackage, getFlags());
        }
        if (mOriginalIntent != null) {
            mOriginalIntent.prepareToLeaveProcess(leavingPackage);
        }

        if (mExtras != null && !mExtras.isParcelled()) {
            final Object intent = mExtras.get(Intent.EXTRA_INTENT);
@@ -11505,6 +11541,9 @@ public class Intent implements Parcelable, Cloneable {
        if (mClipData != null) {
            mClipData.prepareToEnterProcess(source);
        }
        if (mOriginalIntent != null) {
            mOriginalIntent.prepareToEnterProcess(false, source);
        }

        if (mContentUserHint != UserHandle.USER_CURRENT) {
            if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) {
+55 −12
Original line number Diff line number Diff line
@@ -816,8 +816,19 @@ public final class ActiveServices {
            return null;
        }

        return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
        // If what the client try to start/connect was an alias, then we need to return the
        // alias component name to the client, not the "target" component name, which is
        // what realResult contains.
        final ComponentName realResult =
                startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
                allowBackgroundActivityStarts, backgroundActivityStartsToken);
        if (res.aliasComponent != null
                && !realResult.getPackageName().startsWith("!")
                && !realResult.getPackageName().startsWith("?")) {
            return res.aliasComponent;
        } else {
            return realResult;
        }
    }

    private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
@@ -2838,7 +2849,7 @@ public final class ActiveServices {
            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
            ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent,
                    callerApp.uid, callerApp.processName, callingPackage);
                    callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);

            IBinder binder = connection.asBinder();
            s.addConnection(binder, c);
@@ -2915,8 +2926,13 @@ public final class ActiveServices {
            if (s.app != null && b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.

                // If what the client try to start/connect was an alias, then we need to
                // pass the alias component name instead to the client.
                final ComponentName clientSideComponentName =
                        res.aliasComponent != null ? res.aliasComponent : s.name;
                try {
                    c.conn.connected(s.name, b.intent.binder, false);
                    c.conn.connected(clientSideComponentName, b.intent.binder, false);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure sending service " + s.shortInstanceName
                            + " to connection " + c.conn.asBinder()
@@ -2987,8 +3003,12 @@ public final class ActiveServices {
                                continue;
                            }
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                            // If what the client try to start/connect was an alias, then we need to
                            // pass the alias component name instead to the client.
                            final ComponentName clientSideComponentName =
                                    c.aliasComponent != null ? c.aliasComponent : r.name;
                            try {
                                c.conn.connected(r.name, service, false);
                                c.conn.connected(clientSideComponentName, service, false);
                            } catch (Exception e) {
                                Slog.w(TAG, "Failure sending service " + r.shortInstanceName
                                      + " to connection " + c.conn.asBinder()
@@ -3140,9 +3160,22 @@ public final class ActiveServices {
        final ServiceRecord record;
        final String permission;

        ServiceLookupResult(ServiceRecord _record, String _permission) {
        /**
         * Set only when we looked up to this service via an alias. Otherwise, it's null.
         */
        @Nullable
        final ComponentName aliasComponent;

        ServiceLookupResult(ServiceRecord _record, ComponentName _aliasComponent) {
            record = _record;
            permission = null;
            aliasComponent = _aliasComponent;
        }

        ServiceLookupResult(String _permission) {
            record = null;
            permission = _permission;
            aliasComponent = null;
        }
    }

@@ -3174,10 +3207,19 @@ public final class ActiveServices {
                /* name= */ "service", callingPackage);

        ServiceMap smap = getServiceMapLocked(userId);

        // See if the intent refers to an alias. If so, update the intent with the target component
        // name. `resolution` will contain the alias component name, which we need to return
        // to the client.
        final ComponentAliasResolver.Resolution resolution =
                mAm.mComponentAliasResolver.resolveService(service, resolvedType,
                        /* match flags */ 0, userId, callingUid);

        final ComponentName comp;
        if (instanceName == null) {
            comp = service.getComponent();
        } else {
            // This is for isolated services
            final ComponentName realComp = service.getComponent();
            if (realComp == null) {
                throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
@@ -3186,6 +3228,7 @@ public final class ActiveServices {
            comp = new ComponentName(realComp.getPackageName(),
                    realComp.getClassName() + ":" + instanceName);
        }

        if (comp != null) {
            r = smap.mServicesByInstanceName.get(comp);
            if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by component: " + r);
@@ -3243,7 +3286,7 @@ public final class ActiveServices {
                    String msg = "association not allowed between packages "
                            + callingPackage + " and " + name.getPackageName();
                    Slog.w(TAG, "Service lookup failed: " + msg);
                    return new ServiceLookupResult(null, msg);
                    return new ServiceLookupResult(msg);
                }

                // Store the defining packageName and uid, as they might be changed in
@@ -3361,11 +3404,11 @@ public final class ActiveServices {
                String msg = "association not allowed between packages "
                        + callingPackage + " and " + r.packageName;
                Slog.w(TAG, "Service lookup failed: " + msg);
                return new ServiceLookupResult(null, msg);
                return new ServiceLookupResult(msg);
            }
            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                    resolvedType, r.appInfo)) {
                return new ServiceLookupResult(null, "blocked by firewall");
                return new ServiceLookupResult("blocked by firewall");
            }
            if (mAm.checkComponentPermission(r.permission,
                    callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
@@ -3374,14 +3417,14 @@ public final class ActiveServices {
                            + " from pid=" + callingPid
                            + ", uid=" + callingUid
                            + " that is not exported from uid " + r.appInfo.uid);
                    return new ServiceLookupResult(null, "not exported from uid "
                    return new ServiceLookupResult("not exported from uid "
                            + r.appInfo.uid);
                }
                Slog.w(TAG, "Permission Denial: Accessing service " + r.shortInstanceName
                        + " from pid=" + callingPid
                        + ", uid=" + callingUid
                        + " requires " + r.permission);
                return new ServiceLookupResult(null, r.permission);
                return new ServiceLookupResult(r.permission);
            } else if (Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
                    && callingUid != Process.SYSTEM_UID) {
                // Hotword detection must run in its own sandbox, and we don't even trust
@@ -3392,7 +3435,7 @@ public final class ActiveServices {
                        + ", uid=" + callingUid
                        + " requiring permission " + r.permission
                        + " can only be bound to from the system.");
                return new ServiceLookupResult(null, "can only be bound to "
                return new ServiceLookupResult("can only be bound to "
                        + "by the system.");
            } else if (r.permission != null && callingPackage != null) {
                final int opCode = AppOpsManager.permissionToOpCode(r.permission);
@@ -3405,7 +3448,7 @@ public final class ActiveServices {
                    return null;
                }
            }
            return new ServiceLookupResult(r, null);
            return new ServiceLookupResult(r, resolution.getAliasComponent());
        }
        return null;
    }
+32 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ final class ActivityManagerConstants extends ContentObserver {
    static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle";
    static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME =
            "kill_bg_restricted_cached_idle_settle_time";
    static final String KEY_ENABLE_COMPONENT_ALIAS = "enable_experimental_component_alias";
    static final String KEY_COMPONENT_ALIAS_OVERRIDES = "component_alias_overrides";

    private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
    private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000;
@@ -197,6 +199,8 @@ final class ActivityManagerConstants extends ContentObserver {
     * Whether or not to enable the extra delays to service restarts on memory pressure.
     */
    private static final boolean DEFAULT_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE = true;
    private static final boolean DEFAULT_ENABLE_COMPONENT_ALIAS = false;
    private static final String DEFAULT_COMPONENT_ALIAS_OVERRIDES = "";

    // Flag stored in the DeviceConfig API.
    /**
@@ -580,6 +584,14 @@ final class ActivityManagerConstants extends ContentObserver {
    @GuardedBy("mService")
    boolean mEnableExtraServiceRestartDelayOnMemPressure =
            DEFAULT_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE;
    /** Whether to enable "component alias" experimental feature. */
    volatile boolean mEnableComponentAlias = DEFAULT_ENABLE_COMPONENT_ALIAS;

    /**
     * Defines component aliases. Format
     * ComponentName ":" ComponentName ( "," ComponentName ":" ComponentName )*
     */
    volatile String mComponentAliasOverrides = DEFAULT_COMPONENT_ALIAS_OVERRIDES;

    private final ActivityManagerService mService;
    private ContentResolver mResolver;
@@ -812,6 +824,10 @@ final class ActivityManagerConstants extends ContentObserver {
                            case KEY_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE:
                                updateEnableExtraServiceRestartDelayOnMemPressure();
                                break;
                            case KEY_ENABLE_COMPONENT_ALIAS:
                            case KEY_COMPONENT_ALIAS_OVERRIDES:
                                updateComponentAliases();
                                break;
                            default:
                                break;
                        }
@@ -1243,6 +1259,18 @@ final class ActivityManagerConstants extends ContentObserver {
        return def;
    }

    private void updateComponentAliases() {
        mEnableComponentAlias = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_ENABLE_COMPONENT_ALIAS,
                DEFAULT_ENABLE_COMPONENT_ALIAS);
        mComponentAliasOverrides = DeviceConfig.getString(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_COMPONENT_ALIAS_OVERRIDES,
                DEFAULT_COMPONENT_ALIAS_OVERRIDES);
        mService.mComponentAliasResolver.update(mEnableComponentAlias, mComponentAliasOverrides);
    }

    private void updateImperceptibleKillExemptions() {
        IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
        IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
@@ -1472,6 +1500,10 @@ final class ActivityManagerConstants extends ContentObserver {
        pw.print("="); pw.println(mPushMessagingOverQuotaBehavior);
        pw.print("  "); pw.print(KEY_FGS_ALLOW_OPT_OUT);
        pw.print("="); pw.println(mFgsAllowOptOut);
        pw.print("  "); pw.print(KEY_ENABLE_COMPONENT_ALIAS);
        pw.print("="); pw.println(mEnableComponentAlias);
        pw.print("  "); pw.print(KEY_COMPONENT_ALIAS_OVERRIDES);
        pw.print("="); pw.println(mComponentAliasOverrides);

        pw.println();
        if (mOverrideMaxCachedProcesses >= 0) {
+17 −0
Original line number Diff line number Diff line
@@ -779,6 +779,9 @@ public class ActivityManagerService extends IActivityManager.Stub
    @GuardedBy("this")
    private ArrayMap<String, PackageAssociationInfo> mAllowedAssociations;
    @GuardedBy("this")
    final ComponentAliasResolver mComponentAliasResolver;
    /**
     * Tracks association information for a particular package along with debuggability.
     * <p> Associations for a package A are allowed to package B if B is part of the
@@ -2220,6 +2223,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mUseFifoUiScheduling = false;
        mEnableOffloadQueue = false;
        mFgBroadcastQueue = mBgBroadcastQueue = mOffloadBroadcastQueue = null;
        mComponentAliasResolver = new ComponentAliasResolver(this);
    }
    // Note: This method is invoked on the main thread but may need to attach various
@@ -2346,6 +2350,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mInternal = new LocalService();
        mPendingStartActivityUids = new PendingStartActivityUids(mContext);
        mTraceErrorLogger = new TraceErrorLogger();
        mComponentAliasResolver = new ComponentAliasResolver(this);
    }
    public void setSystemServiceManager(SystemServiceManager mgr) {
@@ -4784,6 +4789,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        showConsoleNotificationIfActive();
        t.traceEnd();
        // Load the component aliases.
        mComponentAliasResolver.update(
                mConstants.mEnableComponentAlias, mConstants.mComponentAliasOverrides);
    }
    private void showConsoleNotificationIfActive() {
@@ -8791,6 +8800,12 @@ public class ActivityManagerService extends IActivityManager.Stub
                pw.println("-------------------------------------------------------------------------------");
            }
            dumpUsers(pw);
            pw.println();
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
            }
            mComponentAliasResolver.dump(pw);
        }
    }
@@ -9107,6 +9122,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    opti++;
                }
                mProcessList.mAppExitInfoTracker.dumpHistoryProcessExitInfo(pw, dumpPackage);
            } else if ("component-alias".equals(cmd)) {
                mComponentAliasResolver.dump(pw);
            } else {
                // Dumping a single activity?
                if (!mAtmInternal.dumpActivity(fd, pw, cmd, args, opti, dumpAll,
+326 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading