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

Commit 6fc592b6 authored by William Escande's avatar William Escande
Browse files

Revert "SystemServer: AutoOn: Hidden api listener"

This reverts commit c26a815f.

Reason for revert: The hidden api listener was a hack for QPR release.
                   Since the feature hasn't shipped before V, this code
                   is considered as dead code and now need to be removed

Bug: 323060869
Bug: 316946334
Change-Id: I654e3d32f06c88672702498a1c3c8325fa0cc3d6
Test: atest ServiceBluetoothRoboTests
parent 31546bd8
Loading
Loading
Loading
Loading
+0 −87
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.ContentObserver
import android.os.Build
import android.os.Handler
import android.os.Looper
@@ -142,16 +141,6 @@ public fun setUserEnabled(
    resetAutoOnTimerForUser(looper, context, state, callback_on)
}

// Listener is needed because code should be actionable prior to V API release
public fun registerHiddenApiListener(
    looper: Looper,
    context: Context,
    state: BluetoothAdapterState,
    callback_on: () -> Unit
) {
    HiddenApiListener.registerUser(looper, context, state, callback_on)
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// PRIVATE METHODS /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -312,79 +301,3 @@ private fun setFeatureEnabledForUserUnchecked(context: Context, status: Boolean)
    }
    return ret
}

// Listener is needed because code should be actionable prior to V API release
@VisibleForTesting
internal class HiddenApiListener
private constructor(
    looper: Looper,
    private val context: Context,
    state: BluetoothAdapterState,
    callback_on: () -> Unit
) {
    companion object {
        @VisibleForTesting internal var listener: HiddenApiListener? = null

        fun registerUser(
            looper: Looper,
            context: Context,
            state: BluetoothAdapterState,
            callback_on: () -> Unit
        ) {
            // Remove observer on previous user
            listener?.remove()
            listener = HiddenApiListener(looper, context, state, callback_on)
        }
    }

    private val handler = Handler(looper)

    private val observer =
        object : ContentObserver(handler) {
            override fun onChange(selfChange: Boolean) {
                var previousState = featureState
                var newState =
                    Settings.Secure.getInt(context.contentResolver, USER_SETTINGS_KEY, -1)
                featureState = newState

                if (previousState == newState) {
                    Log.d(TAG, "HiddenApi: State is unchanged: ${newState}")
                    return
                }

                if (previousState == -1) {
                    Log.d(TAG, "HiddenApi: Feature default state got setup to ${newState}")
                    return
                }

                Log.d(TAG, "HiddenApi: Feature state change from ${previousState} to ${newState}")

                Counter.logIncrement("bluetooth.value_auto_on_hidden_usage")
                Counter.logIncrement(
                    if (newState == 1) "bluetooth.value_auto_on_enabled"
                    else "bluetooth.value_auto_on_disabled"
                )

                resetAutoOnTimerForUser(looper, context, state, callback_on)
            }
        }

    private var featureState =
        Settings.Secure.getInt(context.contentResolver, USER_SETTINGS_KEY, -1)

    init {
        val notifyForDescendants = false

        context.contentResolver.registerContentObserver(
            Settings.Secure.getUriFor(USER_SETTINGS_KEY),
            notifyForDescendants,
            observer
        )
    }

    @VisibleForTesting
    internal fun remove() {
        context.contentResolver.unregisterContentObserver(observer)
        handler.removeCallbacksAndMessages(null)
    }
}
+0 −107
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.provider.Settings
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.truth.content.IntentSubject.assertThat
import com.android.server.bluetooth.BluetoothAdapterState
import com.android.server.bluetooth.HiddenApiListener
import com.android.server.bluetooth.Log
import com.android.server.bluetooth.Timer
import com.android.server.bluetooth.USER_SETTINGS_KEY
@@ -35,7 +34,6 @@ import com.android.server.bluetooth.isUserEnabled
import com.android.server.bluetooth.isUserSupported
import com.android.server.bluetooth.notifyBluetoothOn
import com.android.server.bluetooth.pause
import com.android.server.bluetooth.registerHiddenApiListener
import com.android.server.bluetooth.resetAutoOnTimerForUser
import com.android.server.bluetooth.satellite.isOn as isSatelliteModeOn
import com.android.server.bluetooth.satellite.test.ModeListenerTest as SatelliteListener
@@ -58,8 +56,6 @@ import org.robolectric.Shadows.shadowOf
@RunWith(RobolectricTestRunner::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class AutoOnFeatureTest {
    private val SETTING_URI = Settings.Secure.getUriFor(USER_SETTINGS_KEY)

    private val looper = Looper.getMainLooper()
    private val state = BluetoothAdapterState()
    private val context = ApplicationProvider.getApplicationContext<Context>()
@@ -81,9 +77,6 @@ class AutoOnFeatureTest {

    @After
    fun tearDown() {
        HiddenApiListener.listener?.let { it.remove() }
        HiddenApiListener.listener = null

        callback_count = 0
        timer?.cancel()
        timer = null
@@ -446,104 +439,4 @@ class AutoOnFeatureTest {
        expect.that(callback_count).isEqualTo(0)
        expectStorageTime()
    }

    @Test
    fun registerHiddenListener_whenNothing_isRegistered() {
        registerHiddenApiListener(looper, context, state, this::callback_on)

        assertThat(HiddenApiListener.listener).isNotNull()
    }

    @Test
    fun unregisterHiddenListener_whenRegistered_isNotRegistered() {
        registerHiddenApiListener(looper, context, state, this::callback_on)

        HiddenApiListener.listener?.let { it.remove() }

        assertThat(shadowOf(resolver).getContentObservers(SETTING_URI).size).isEqualTo(0)
    }

    @Test
    fun registerHiddenListener_whenAlreadyRegistered_isRegisteredOnce() {
        registerHiddenApiListener(looper, context, state, this::callback_on)

        registerHiddenApiListener(looper, context, state, this::callback_on)

        expect.that(shadowOf(resolver).getContentObservers(SETTING_URI).size).isEqualTo(1)
        expect.that(HiddenApiListener.listener).isNotNull()
    }

    @Test
    fun changeSettingsToDisabled_whenHiddenApiIsRegisteredandNotScheduled_isNotSchedule() {
        registerHiddenApiListener(looper, context, state, this::callback_on)

        disableUserSettings()

        expect.that(timer).isNull()
        expect.that(callback_count).isEqualTo(0)
        expectNoStorageTime()
    }

    @Test
    fun changeSettingsToDisabled_whenHiddenApiIsRegisteredandScheduled_isNotSchedule() {
        setupTimer()
        registerHiddenApiListener(looper, context, state, this::callback_on)

        disableUserSettings()

        expect.that(timer).isNull()
        expect.that(callback_count).isEqualTo(0)
        expectNoStorageTime()
    }

    @Test
    fun changeSettingsToEnabled_whenHiddenApiIsRegisteredandNotScheduled_isSchedule() {
        disableUserSettings()
        registerHiddenApiListener(looper, context, state, this::callback_on)

        enableUserSettings()

        expect.that(timer).isNotNull()
        expect.that(callback_count).isEqualTo(0)
        expectStorageTime()
    }

    @Test
    fun setSettingsToSameValue_whenHiddenApiIsRegisteredandNotScheduled_isNotSchedule() {
        restoreSettings()
        registerHiddenApiListener(looper, context, state, this::callback_on)

        Settings.Secure.putInt(resolver, USER_SETTINGS_KEY, -1)
        shadowOf(looper).idle()

        expect.that(timer).isNull()
        expect.that(callback_count).isEqualTo(0)
        expectNoStorageTime()
    }

    @Test
    fun setSettingsToEnabled_whenHiddenApiIsRegisteredandNotSupported_isNotSchedule() {
        restoreSettings()
        registerHiddenApiListener(looper, context, state, this::callback_on)

        enableUserSettings()

        expect.that(timer).isNull()
        expect.that(callback_count).isEqualTo(0)
        expectNoStorageTime()
    }

    @Test
    fun setSettingsToDisable_whenHiddenApiIsRegisteredandNotSupported_isNotSchedule() {
        // Current design will set the feature to enabled, but there is no reason to not support
        // having a default value to disabled
        restoreSettings()
        registerHiddenApiListener(looper, context, state, this::callback_on)

        disableUserSettings()

        expect.that(timer).isNull()
        expect.that(callback_count).isEqualTo(0)
        expectNoStorageTime()
    }
}
+0 −18
Original line number Diff line number Diff line
@@ -1297,8 +1297,6 @@ class BluetoothManagerService {
        } else {
            autoOnSetupTimer();
        }

        autoOnHiddenListener();
    }

    /** Called when switching to a different foreground user. */
@@ -1908,9 +1906,6 @@ class BluetoothManagerService {
                    } else {
                        autoOnSetupTimer();
                    }

                    autoOnHiddenListener();

                    break;

                case MESSAGE_USER_UNLOCKED:
@@ -2611,19 +2606,6 @@ class BluetoothManagerService {
                mLooper, mCurrentUserContext, mState, this::enableFromAutoOn);
    }

    private void autoOnHiddenListener() {
        if (!mDeviceConfigAllowAutoOn) {
            Log.d(TAG, "No support for AutoOn feature: Not listening on hidden api");
            return;
        }
        if (isAtLeastV()) {
            Log.d(TAG, "AutoOn feature: prevent listening on hidden api. Use proper API in V+");
            return;
        }
        AutoOnFeature.registerHiddenApiListener(
                mLooper, mCurrentUserContext, mState, this::enableFromAutoOn);
    }

    private <T> T postAndWait(Callable<T> callable) {
        FutureTask<T> task = new FutureTask(callable);