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

Commit 353ff476 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Include the hardcoded list of sticky broadcasts to cache.

These broadcast actions will be used in determining whether
to cache the broadcast intent and whether to modify the
system property.

Bug: 356148006
Test: atest tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
Flag: android.app.use_sticky_bcast_cache
Change-Id: Ia4f4b6ef05016d654e9c9c04967f669c6c57e34b
parent 9e719d36
Loading
Loading
Loading
Loading
+64 −10
Original line number Diff line number Diff line
@@ -20,17 +20,54 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.TetheringManager;
import android.net.nsd.NsdManager;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.SystemProperties;
import android.os.UpdateLock;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.view.WindowManagerPolicyConstants;

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

import java.util.ArrayList;

/** @hide */
public class BroadcastStickyCache {

    private static final String[] CACHED_BROADCAST_ACTIONS = {
            AudioManager.ACTION_HDMI_AUDIO_PLUG,
            AudioManager.ACTION_HEADSET_PLUG,
            AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED,
            AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED,
            AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION,
            AudioManager.RINGER_MODE_CHANGED_ACTION,
            ConnectivityManager.CONNECTIVITY_ACTION,
            Intent.ACTION_BATTERY_CHANGED,
            Intent.ACTION_DEVICE_STORAGE_FULL,
            Intent.ACTION_DEVICE_STORAGE_LOW,
            Intent.ACTION_SIM_STATE_CHANGED,
            NsdManager.ACTION_NSD_STATE_CHANGED,
            TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED,
            TetheringManager.ACTION_TETHER_STATE_CHANGED,
            UpdateLock.UPDATE_LOCK_CHANGED,
            UsbManager.ACTION_USB_STATE,
            WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED,
            WifiManager.NETWORK_STATE_CHANGED_ACTION,
            WifiManager.SUPPLICANT_STATE_CHANGED_ACTION,
            WifiManager.WIFI_STATE_CHANGED_ACTION,
            WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
            WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED,
            "android.net.conn.INET_CONDITION_ACTION" // ConnectivityManager.INET_CONDITION_ACTION
    };

    @GuardedBy("sCachedStickyBroadcasts")
    private static final ArrayList<CachedStickyBroadcast> sCachedStickyBroadcasts =
            new ArrayList<>();
@@ -41,10 +78,7 @@ public class BroadcastStickyCache {

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public static boolean useCache(@Nullable IntentFilter filter) {
        if (!Flags.useStickyBcastCache()) {
            return false;
        }
        if (filter == null || filter.safeCountActions() != 1) {
        if (!shouldCache(filter)) {
            return false;
        }
        synchronized (sCachedStickyBroadcasts) {
@@ -59,10 +93,7 @@ public class BroadcastStickyCache {

    @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) {
        if (!shouldCache(filter)) {
            return;
        }
        synchronized (sCachedStickyBroadcasts) {
@@ -86,6 +117,19 @@ public class BroadcastStickyCache {
        }
    }

    private static boolean shouldCache(@Nullable IntentFilter filter) {
        if (!Flags.useStickyBcastCache()) {
            return false;
        }
        if (filter == null || filter.safeCountActions() != 1) {
            return false;
        }
        if (!ArrayUtils.contains(CACHED_BROADCAST_ACTIONS, filter.getAction(0))) {
            return false;
        }
        return true;
    }

    @VisibleForTesting
    @NonNull
    public static String getKey(@NonNull String action) {
@@ -114,7 +158,7 @@ public class BroadcastStickyCache {
    }

    public static void incrementVersion(@NonNull String action) {
        if (!Flags.useStickyBcastCache()) {
        if (!shouldIncrementVersion(action)) {
            return;
        }
        final String key = getKey(action);
@@ -136,7 +180,7 @@ public class BroadcastStickyCache {
    }

    public static void incrementVersionIfExists(@NonNull String action) {
        if (!Flags.useStickyBcastCache()) {
        if (!shouldIncrementVersion(action)) {
            return;
        }
        final String key = getKey(action);
@@ -150,6 +194,16 @@ public class BroadcastStickyCache {
        }
    }

    private static boolean shouldIncrementVersion(@NonNull String action) {
        if (!Flags.useStickyBcastCache()) {
            return false;
        }
        if (!ArrayUtils.contains(CACHED_BROADCAST_ACTIONS, action)) {
            return false;
        }
        return true;
    }

    @VisibleForTesting
    public static void clearForTest() {
        synchronized (sCachedStickyBroadcasts) {
+1 −3
Original line number Diff line number Diff line
@@ -686,7 +686,6 @@ class BroadcastController {
            boolean serialized, boolean sticky, int userId) {
        mService.enforceNotIsolatedCaller("broadcastIntent");

        boolean isCallerCore;
        int result;
        synchronized (mService) {
            intent = verifyBroadcastLocked(intent);
@@ -709,7 +708,6 @@ class BroadcastController {

            final long origId = Binder.clearCallingIdentity();
            try {
                isCallerCore = UserHandle.isCore(callingUid);
                result = broadcastIntentLocked(callerApp,
                        callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
                        intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
@@ -721,7 +719,7 @@ class BroadcastController {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }
        if (sticky && isCallerCore && result == ActivityManager.BROADCAST_SUCCESS) {
        if (sticky && result == ActivityManager.BROADCAST_SUCCESS) {
            BroadcastStickyCache.incrementVersion(intent.getAction());
        }
        return result;
+39 −37
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package android.app;

import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static android.content.Intent.ACTION_DEVICE_STORAGE_LOW;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;

import static com.google.common.truth.Truth.assertThat;
@@ -60,9 +63,8 @@ public class BroadcastStickyCacheTest {
            .mockStatic(SystemProperties.class)
            .build();

    private static final String ACTION_TEST_RED = "action.test.red";
    private static final String ACTION_TEST_GREEN = "action.test.green";
    private static final String PROP_TEST_GREEN = BroadcastStickyCache.getKey(ACTION_TEST_GREEN);
    private static final String PROP_KEY_BATTERY_CHANGED = BroadcastStickyCache.getKey(
            ACTION_BATTERY_CHANGED);

    private final TestSystemProps mTestSystemProps = new TestSystemProps();

@@ -106,52 +108,52 @@ public class BroadcastStickyCacheTest {
    @Test
    public void testUseCache_multipleActions() {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_TEST_RED);
        filter.addAction(ACTION_TEST_GREEN);
        filter.addAction(ACTION_DEVICE_STORAGE_LOW);
        filter.addAction(ACTION_BATTERY_CHANGED);
        assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false);
    }

    @Test
    public void testUseCache_valueNotSet() {
        final IntentFilter filter = new IntentFilter(ACTION_TEST_GREEN);
        final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
        assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false);
    }

    @Test
    public void testUseCache() {
        final IntentFilter filter = new IntentFilter(ACTION_TEST_GREEN);
        final Intent intent = new Intent(ACTION_TEST_GREEN)
        final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
        final Intent intent = new Intent(ACTION_BATTERY_CHANGED)
                .putExtra(BatteryManager.EXTRA_LEVEL, 90);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        BroadcastStickyCache.add(filter, intent);
        assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(true);
    }

    @Test
    public void testUseCache_versionMismatch() {
        final IntentFilter filter = new IntentFilter(ACTION_TEST_GREEN);
        final Intent intent = new Intent(ACTION_TEST_GREEN)
        final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
        final Intent intent = new Intent(ACTION_BATTERY_CHANGED)
                .putExtra(BatteryManager.EXTRA_LEVEL, 90);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        BroadcastStickyCache.add(filter, intent);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);

        assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false);
    }

    @Test
    public void testAdd() {
        final IntentFilter filter = new IntentFilter(ACTION_TEST_GREEN);
        Intent intent = new Intent(ACTION_TEST_GREEN)
        final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
        Intent intent = new Intent(ACTION_BATTERY_CHANGED)
                .putExtra(BatteryManager.EXTRA_LEVEL, 90);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        BroadcastStickyCache.add(filter, intent);
        assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(true);
        Intent actualIntent = BroadcastStickyCache.getIntentUnchecked(filter);
        assertThat(actualIntent).isNotNull();
        assertEquals(actualIntent, intent);

        intent = new Intent(ACTION_TEST_GREEN)
        intent = new Intent(ACTION_BATTERY_CHANGED)
                .putExtra(BatteryManager.EXTRA_LEVEL, 99);
        BroadcastStickyCache.add(filter, intent);
        actualIntent = BroadcastStickyCache.getIntentUnchecked(filter);
@@ -161,45 +163,45 @@ public class BroadcastStickyCacheTest {

    @Test
    public void testIncrementVersion_propExists() {
        SystemProperties.set(PROP_TEST_GREEN, String.valueOf(100));
        SystemProperties.set(PROP_KEY_BATTERY_CHANGED, String.valueOf(100));

        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(101);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(102);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(101);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(102);
    }

    @Test
    public void testIncrementVersion_propNotExists() {
        // Verify that the property doesn't exist
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(-1);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1);

        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(1);
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(2);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(1);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(2);
    }

    @Test
    public void testIncrementVersionIfExists_propExists() {
        BroadcastStickyCache.incrementVersion(ACTION_TEST_GREEN);
        BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED);

        BroadcastStickyCache.incrementVersionIfExists(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(2);
        BroadcastStickyCache.incrementVersionIfExists(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(3);
        BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(2);
        BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(3);
    }

    @Test
    public void testIncrementVersionIfExists_propNotExists() {
        // Verify that the property doesn't exist
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(-1);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1);

        BroadcastStickyCache.incrementVersionIfExists(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(-1);
        BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1);
        // Verify that property is not added as part of the querying.
        BroadcastStickyCache.incrementVersionIfExists(ACTION_TEST_GREEN);
        assertThat(mTestSystemProps.get(PROP_TEST_GREEN, -1 /* def */)).isEqualTo(-1);
        BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED);
        assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1);
    }

    private void assertEquals(Intent actualIntent, Intent expectedIntent) {