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

Commit 367a617b authored by Mayank Dandwani's avatar Mayank Dandwani Committed by mayankkk
Browse files

Revert "Cache sticky broadcast intents on the client side."

Revert submission 29548976

Reason for revert: Doing caching using IPCDataCache

Reverted changes: /q/submissionid:29548976

Change-Id: Ia682134cc5dd6393f0921a813f3e9ecdeb0fa1ad
parent 06015995
Loading
Loading
Loading
Loading
+0 −175
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 android.app;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.SystemProperties;
import android.util.ArrayMap;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;

/** @hide */
public class BroadcastStickyCache {

    @GuardedBy("sCachedStickyBroadcasts")
    private static final ArrayList<CachedStickyBroadcast> sCachedStickyBroadcasts =
            new ArrayList<>();

    @GuardedBy("sCachedPropertyHandles")
    private static final ArrayMap<String, SystemProperties.Handle> sCachedPropertyHandles =
            new ArrayMap<>();

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public static boolean useCache(@Nullable IntentFilter filter) {
        if (!Flags.useStickyBcastCache()) {
            return false;
        }
        if (filter == null || filter.safeCountActions() != 1) {
            return false;
        }
        synchronized (sCachedStickyBroadcasts) {
            final CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter);
            if (cachedStickyBroadcast == null) {
                return false;
            }
            final long version = cachedStickyBroadcast.propertyHandle.getLong(-1 /* def */);
            return version > 0 && cachedStickyBroadcast.version == version;
        }
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public static void add(@Nullable IntentFilter filter, @Nullable Intent intent) {
        if (!Flags.useStickyBcastCache()) {
            return;
        }
        if (filter == null || filter.safeCountActions() != 1) {
            return;
        }
        synchronized (sCachedStickyBroadcasts) {
            CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter);
            if (cachedStickyBroadcast == null) {
                final String key = getKey(filter.getAction(0));
                final SystemProperties.Handle handle = SystemProperties.find(key);
                final long version = handle == null ? -1 : handle.getLong(-1 /* def */);
                if (version == -1) {
                    return;
                }
                cachedStickyBroadcast = new CachedStickyBroadcast(filter, handle);
                sCachedStickyBroadcasts.add(cachedStickyBroadcast);
                cachedStickyBroadcast.intent = intent;
                cachedStickyBroadcast.version = version;
            } else {
                cachedStickyBroadcast.intent = intent;
                cachedStickyBroadcast.version = cachedStickyBroadcast.propertyHandle
                        .getLong(-1 /* def */);
            }
        }
    }

    @VisibleForTesting
    @NonNull
    public static String getKey(@NonNull String action) {
        return "cache_key.system_server.sticky_bcast." + action;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    @Nullable
    public static Intent getIntentUnchecked(@NonNull IntentFilter filter) {
        synchronized (sCachedStickyBroadcasts) {
            final CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter);
            return cachedStickyBroadcast.intent;
        }
    }

    @GuardedBy("sCachedStickyBroadcasts")
    @Nullable
    private static CachedStickyBroadcast getValueUncheckedLocked(@NonNull IntentFilter filter) {
        for (int i = sCachedStickyBroadcasts.size() - 1; i >= 0; --i) {
            final CachedStickyBroadcast cachedStickyBroadcast = sCachedStickyBroadcasts.get(i);
            if (IntentFilter.filterEquals(filter, cachedStickyBroadcast.filter)) {
                return cachedStickyBroadcast;
            }
        }
        return null;
    }

    public static void incrementVersion(@NonNull String action) {
        if (!Flags.useStickyBcastCache()) {
            return;
        }
        final String key = getKey(action);
        synchronized (sCachedPropertyHandles) {
            SystemProperties.Handle handle = sCachedPropertyHandles.get(key);
            final long version;
            if (handle == null) {
                handle = SystemProperties.find(key);
                if (handle != null) {
                    sCachedPropertyHandles.put(key, handle);
                }
            }
            version = handle == null ? 0 : handle.getLong(0 /* def */);
            SystemProperties.set(key, String.valueOf(version + 1));
            if (handle == null) {
                sCachedPropertyHandles.put(key, SystemProperties.find(key));
            }
        }
    }

    public static void incrementVersionIfExists(@NonNull String action) {
        if (!Flags.useStickyBcastCache()) {
            return;
        }
        final String key = getKey(action);
        synchronized (sCachedPropertyHandles) {
            final SystemProperties.Handle handle = sCachedPropertyHandles.get(key);
            if (handle == null) {
                return;
            }
            final long version = handle.getLong(0 /* def */);
            SystemProperties.set(key, String.valueOf(version + 1));
        }
    }

    @VisibleForTesting
    public static void clearForTest() {
        synchronized (sCachedStickyBroadcasts) {
            sCachedStickyBroadcasts.clear();
        }
        synchronized (sCachedPropertyHandles) {
            sCachedPropertyHandles.clear();
        }
    }

    private static final class CachedStickyBroadcast {
        @NonNull public final IntentFilter filter;
        @Nullable public Intent intent;
        @IntRange(from = 0) public long version;
        @NonNull public final SystemProperties.Handle propertyHandle;

        CachedStickyBroadcast(@NonNull IntentFilter filter,
                @NonNull SystemProperties.Handle propertyHandle) {
            this.filter = filter;
            this.propertyHandle = propertyHandle;
        }
    }
}
+4 −13
Original line number Diff line number Diff line
@@ -1922,19 +1922,10 @@ class ContextImpl extends Context {
            }
        }
        try {
            final Intent intent;
            if (receiver == null && BroadcastStickyCache.useCache(filter)) {
                intent = BroadcastStickyCache.getIntentUnchecked(filter);
            } else {
                intent = ActivityManager.getService().registerReceiverWithFeature(
            final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
                    mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
                        AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission,
                        userId,
                    AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
                    flags);
                if (receiver == null) {
                    BroadcastStickyCache.add(filter, intent);
                }
            }
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                // TODO: determine at registration time if caller is
+0 −4
Original line number Diff line number Diff line
@@ -177,10 +177,6 @@
        {
            "file_patterns": ["(/|^)AppOpsManager.java"],
            "name": "CtsAppOpsTestCases"
        },
        {
            "file_patterns": ["(/|^)BroadcastStickyCache.java"],
            "name": "BroadcastUnitTests"
        }
    ]
}
+3 −33
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ import android.app.ApplicationExitInfo;
import android.app.ApplicationThreadConstants;
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
import android.app.BroadcastStickyCache;
import android.app.IApplicationThread;
import android.app.compat.CompatChanges;
import android.appwidget.AppWidgetManager;
@@ -702,8 +701,6 @@ class BroadcastController {
            boolean serialized, boolean sticky, int userId) {
        mService.enforceNotIsolatedCaller("broadcastIntent");

        boolean isCallerCore;
        int result;
        synchronized (mService) {
            intent = verifyBroadcastLocked(intent);

@@ -725,8 +722,7 @@ class BroadcastController {

            final long origId = Binder.clearCallingIdentity();
            try {
                isCallerCore = UserHandle.isCore(callingUid);
                result = broadcastIntentLocked(callerApp,
                return broadcastIntentLocked(callerApp,
                        callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
                        intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
                        resultExtras, requiredPermissions, excludedPermissions, excludedPackages,
@@ -737,10 +733,6 @@ class BroadcastController {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }
        if (sticky && isCallerCore && result == ActivityManager.BROADCAST_SUCCESS) {
            BroadcastStickyCache.incrementVersion(intent.getAction());
        }
        return result;
    }

    // Not the binder call surface
@@ -751,7 +743,6 @@ class BroadcastController {
            boolean serialized, boolean sticky, int userId,
            BackgroundStartPrivileges backgroundStartPrivileges,
            @Nullable int[] broadcastAllowList) {
        int result;
        synchronized (mService) {
            intent = verifyBroadcastLocked(intent);

@@ -759,7 +750,7 @@ class BroadcastController {
            String[] requiredPermissions = requiredPermission == null ? null
                    : new String[] {requiredPermission};
            try {
                result = broadcastIntentLocked(null, packageName, featureId, intent, resolvedType,
                return broadcastIntentLocked(null, packageName, featureId, intent, resolvedType,
                        resultToApp, resultTo, resultCode, resultData, resultExtras,
                        requiredPermissions, null, null, OP_NONE, bOptions, serialized, sticky, -1,
                        uid, realCallingUid, realCallingPid, userId,
@@ -769,10 +760,6 @@ class BroadcastController {
                Binder.restoreCallingIdentity(origId);
            }
        }
        if (sticky && result == ActivityManager.BROADCAST_SUCCESS) {
            BroadcastStickyCache.incrementVersion(intent.getAction());
        }
        return result;
    }

    @GuardedBy("mService")
@@ -1471,7 +1458,6 @@ class BroadcastController {
                    list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive,
                            callingUid, callerAppProcessState, resolvedType));
                }
                BroadcastStickyCache.incrementVersion(intent.getAction());
            }
        }

@@ -1738,7 +1724,6 @@ class BroadcastController {
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        final ArrayList<String> changedStickyBroadcasts = new ArrayList<>();
        synchronized (mStickyBroadcasts) {
            ArrayMap<String, ArrayList<StickyBroadcast>> stickies = mStickyBroadcasts.get(userId);
            if (stickies != null) {
@@ -1755,16 +1740,12 @@ class BroadcastController {
                    if (list.size() <= 0) {
                        stickies.remove(intent.getAction());
                    }
                    changedStickyBroadcasts.add(intent.getAction());
                }
                if (stickies.size() <= 0) {
                    mStickyBroadcasts.remove(userId);
                }
            }
        }
        for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) {
            BroadcastStickyCache.incrementVersionIfExists(changedStickyBroadcasts.get(i));
        }
    }

    void finishReceiver(IBinder caller, int resultCode, String resultData,
@@ -1927,9 +1908,7 @@ class BroadcastController {

    private void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
        mService.mProcessList.sendPackageBroadcastLocked(cmd, packages, userId);
    }

    private List<ResolveInfo> collectReceiverComponents(
    }private List<ResolveInfo> collectReceiverComponents(
            Intent intent, String resolvedType, int callingUid, int callingPid,
            int[] users, int[] broadcastAllowList) {
        // TODO: come back and remove this assumption to triage all broadcasts
@@ -2145,18 +2124,9 @@ class BroadcastController {
    }

    void removeStickyBroadcasts(int userId) {
        final ArrayList<String> changedStickyBroadcasts = new ArrayList<>();
        synchronized (mStickyBroadcasts) {
            final ArrayMap<String, ArrayList<StickyBroadcast>> stickies =
                    mStickyBroadcasts.get(userId);
            if (stickies != null) {
                changedStickyBroadcasts.addAll(stickies.keySet());
            }
            mStickyBroadcasts.remove(userId);
        }
        for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) {
            BroadcastStickyCache.incrementVersionIfExists(changedStickyBroadcasts.get(i));
        }
    }

    @NeverCompile

tests/broadcasts/OWNERS

deleted100644 → 0
+0 −2
Original line number Diff line number Diff line
# Bug component: 316181
include platform/frameworks/base:/BROADCASTS_OWNERS
Loading