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

Commit e77df8f5 authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "[DO NOT MERGE] Move code to fix studio build" into sc-dev

parents 89681165 123a85fd
Loading
Loading
Loading
Loading
+81 −3
Original line number Diff line number Diff line
@@ -15,14 +15,32 @@
 */
package com.android.systemui.globalactions

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.service.quickaccesswallet.QuickAccessWalletClient
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import com.android.systemui.R
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.plugins.ActivityStarter
import javax.inject.Inject

// Empty class, will be overridden for relevant devices
private const val TAG = "GlobalActionsInfo"

/** Maximum number of times to show change info message  */
private const val MAX_VIEW_COUNT = 3

/** Maximum number of buttons allowed in landscape before this panel does not fit */
private const val MAX_BUTTONS_LANDSCAPE = 4

private const val PREFERENCE = "global_actions_info_prefs"
private const val KEY_VIEW_COUNT = "view_count"

class GlobalActionsInfoProvider @Inject constructor(
    private val context: Context,
    private val walletClient: QuickAccessWalletClient,
@@ -30,9 +48,69 @@ class GlobalActionsInfoProvider @Inject constructor(
    private val activityStarter: ActivityStarter
) {

    fun addPanel(context: Context, parent: ViewGroup, nActions: Int, dismissParent: Runnable) { }
    private var pendingIntent: PendingIntent

    init {
        val url = context.resources.getString(R.string.global_actions_change_url)
        val intent = Intent(Intent.ACTION_VIEW).apply {
            setData(Uri.parse(url))
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
    }

    fun addPanel(context: Context, parent: ViewGroup, nActions: Int, dismissParent: Runnable) {
        // This panel does not fit on landscape with two rows of buttons showing,
        // so skip adding the panel (and incrementing view counT) in that case
        val isLandscape =
                context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
        if (isLandscape && nActions > MAX_BUTTONS_LANDSCAPE) {
            return
        }

        val view = LayoutInflater.from(context).inflate(R.layout.global_actions_change_panel,
                parent, false)
        val button = view.findViewById<ImageView>(R.id.global_actions_change_button)
        button.setOnClickListener { _ ->
            dismissParent.run()
            activityStarter.postStartActivityDismissingKeyguard(pendingIntent)
        }
        parent.addView(view, 0) // Add to top
        incrementViewCount()
    }

    fun shouldShowMessage(): Boolean {
        // This is only relevant for some devices
        val isEligible = context.resources.getBoolean(
                R.bool.global_actions_show_change_info)
        if (!isEligible) {
            return false
        }

        val sharedPrefs = context.getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE)

        // Only show to users who previously had these items set up
        val viewCount = if (sharedPrefs.contains(KEY_VIEW_COUNT) || hadContent()) {
            sharedPrefs.getInt(KEY_VIEW_COUNT, 0)
        } else {
            -1
        }

        // Limit number of times this is displayed
        return viewCount > -1 && viewCount < MAX_VIEW_COUNT
    }

    private fun hadContent(): Boolean {
        // Check whether user would have seen content in the power menu that has now moved
        val hadControls = controlsController.getFavorites().size > 0
        val hadCards = walletClient.isWalletFeatureAvailable
        Log.d(TAG, "Previously had controls $hadControls, cards $hadCards")
        return hadControls || hadCards
    }

    private fun incrementViewCount() {
        val sharedPrefs = context.getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE)
        val count = sharedPrefs.getInt(KEY_VIEW_COUNT, 0)
        sharedPrefs.edit().putInt(KEY_VIEW_COUNT, count + 1).apply()
    }
}
 No newline at end of file
+76 −15
Original line number Diff line number Diff line
@@ -14,45 +14,75 @@
 * limitations under the License.
 */

package com.android.systemui.globalactions
package com.google.android.systemui.globalactions

import android.content.Context
import android.content.SharedPreferences
import android.content.res.Configuration
import android.content.res.Resources
import android.service.quickaccesswallet.QuickAccessWalletClient
import android.testing.AndroidTestingRunner
import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.R
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.globalactions.GlobalActionsInfoProvider
import com.android.systemui.plugins.ActivityStarter
import com.google.common.truth.Truth.assertThat
import com.android.systemui.SysuiTestCase
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyObject
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever

private const val PREFERENCE = "global_actions_info_prefs"
private const val KEY_VIEW_COUNT = "view_count"

private fun <T> eq(value: T): T = Mockito.eq(value) ?: value

@SmallTest
@RunWith(AndroidTestingRunner::class)
class GlobalActionsInfoProviderTest : SysuiTestCase() {

    @Mock
    private lateinit var walletClient: QuickAccessWalletClient
    @Mock
    private lateinit var controlsController: ControlsController
    @Mock
    private lateinit var activityStarter: ActivityStarter
    @Mock private lateinit var walletClient: QuickAccessWalletClient
    @Mock private lateinit var controlsController: ControlsController
    @Mock private lateinit var activityStarter: ActivityStarter
    @Mock private lateinit var mockContext: Context
    @Mock private lateinit var mockResources: Resources
    @Mock private lateinit var sharedPrefs: SharedPreferences
    @Mock private lateinit var sharedPrefsEditor: SharedPreferences.Editor

    private lateinit var infoProvider: GlobalActionsInfoProvider

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        mockContext = spy(context)
        mockResources = spy(context.resources)
        whenever(mockContext.resources).thenReturn(mockResources)
        whenever(mockResources.getBoolean(R.bool.global_actions_show_change_info))
                .thenReturn(true)
        whenever(mockContext.getSharedPreferences(eq(PREFERENCE), anyInt()))
                .thenReturn(sharedPrefs)
        whenever(sharedPrefs.edit()).thenReturn(sharedPrefsEditor)
        whenever(sharedPrefsEditor.putInt(anyString(), anyInt())).thenReturn(sharedPrefsEditor)
        whenever(sharedPrefsEditor.putBoolean(anyString(), anyBoolean()))
                .thenReturn(sharedPrefsEditor)

        infoProvider = GlobalActionsInfoProvider(
                context,
                mockContext,
                walletClient,
                controlsController,
                activityStarter
@@ -60,14 +90,45 @@ class GlobalActionsInfoProviderTest : SysuiTestCase() {
    }

    @Test
    fun testAddPanel_doesNothing() {
    fun testIsEligible_noCards() {
        whenever(sharedPrefs.contains(eq(KEY_VIEW_COUNT))).thenReturn(false)
        whenever(walletClient.isWalletFeatureAvailable).thenReturn(false)

        assertFalse(infoProvider.shouldShowMessage())
    }

    @Test
    fun testIsEligible_hasCards() {
        whenever(sharedPrefs.contains(eq(KEY_VIEW_COUNT))).thenReturn(false)
        whenever(walletClient.isWalletFeatureAvailable).thenReturn(true)

        assertTrue(infoProvider.shouldShowMessage())
    }

    @Test
    fun testNotEligible_shouldNotShow() {
        whenever(mockResources.getBoolean(R.bool.global_actions_show_change_info))
                .thenReturn(false)

        assertFalse(infoProvider.shouldShowMessage())
    }

    @Test
    fun testTooManyButtons_doesNotAdd() {
        val configuration = Configuration()
        configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
        whenever(mockResources.configuration).thenReturn(configuration)

        val parent = mock(ViewGroup::class.java)
        infoProvider.addPanel(context, parent, 1, { })
        infoProvider.addPanel(mockContext, parent, 5, { })

        verify(parent, never()).addView(anyObject(), anyInt())
    }

    @Test
    fun testShouldShowPanel() {
        assertThat(infoProvider.shouldShowMessage()).isFalse()
    fun testLimitTimesShown() {
        whenever(sharedPrefs.getInt(eq(KEY_VIEW_COUNT), anyInt())).thenReturn(4)

        assertFalse(infoProvider.shouldShowMessage())
    }
}
 No newline at end of file