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

This commit is contained in:
Beth Thibodeau
2021-06-03 15:38:45 +00:00
committed by Android (Google) Code Review
2 changed files with 157 additions and 18 deletions

View File

@@ -15,14 +15,32 @@
*/ */
package com.android.systemui.globalactions package com.android.systemui.globalactions
import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.service.quickaccesswallet.QuickAccessWalletClient import android.service.quickaccesswallet.QuickAccessWalletClient
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import com.android.systemui.R
import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import javax.inject.Inject 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( class GlobalActionsInfoProvider @Inject constructor(
private val context: Context, private val context: Context,
private val walletClient: QuickAccessWalletClient, private val walletClient: QuickAccessWalletClient,
@@ -30,9 +48,69 @@ class GlobalActionsInfoProvider @Inject constructor(
private val activityStarter: ActivityStarter 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 { fun shouldShowMessage(): Boolean {
return false // 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()
} }
} }

View File

@@ -14,45 +14,75 @@
* limitations under the License. * 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.service.quickaccesswallet.QuickAccessWalletClient
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.view.ViewGroup import android.view.ViewGroup
import androidx.test.filters.SmallTest 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.controls.controller.ControlsController
import com.android.systemui.globalactions.GlobalActionsInfoProvider
import com.android.systemui.plugins.ActivityStarter 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.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyObject import org.mockito.ArgumentMatchers.anyObject
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.mock import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.never import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations 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 @SmallTest
@RunWith(AndroidTestingRunner::class) @RunWith(AndroidTestingRunner::class)
class GlobalActionsInfoProviderTest : SysuiTestCase() { class GlobalActionsInfoProviderTest : SysuiTestCase() {
@Mock @Mock private lateinit var walletClient: QuickAccessWalletClient
private lateinit var walletClient: QuickAccessWalletClient @Mock private lateinit var controlsController: ControlsController
@Mock @Mock private lateinit var activityStarter: ActivityStarter
private lateinit var controlsController: ControlsController @Mock private lateinit var mockContext: Context
@Mock @Mock private lateinit var mockResources: Resources
private lateinit var activityStarter: ActivityStarter @Mock private lateinit var sharedPrefs: SharedPreferences
@Mock private lateinit var sharedPrefsEditor: SharedPreferences.Editor
private lateinit var infoProvider: GlobalActionsInfoProvider private lateinit var infoProvider: GlobalActionsInfoProvider
@Before @Before
fun setup() { fun setup() {
MockitoAnnotations.initMocks(this) 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( infoProvider = GlobalActionsInfoProvider(
context, mockContext,
walletClient, walletClient,
controlsController, controlsController,
activityStarter activityStarter
@@ -60,14 +90,45 @@ class GlobalActionsInfoProviderTest : SysuiTestCase() {
} }
@Test @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) val parent = mock(ViewGroup::class.java)
infoProvider.addPanel(context, parent, 1, { }) infoProvider.addPanel(mockContext, parent, 5, { })
verify(parent, never()).addView(anyObject(), anyInt()) verify(parent, never()).addView(anyObject(), anyInt())
} }
@Test @Test
fun testShouldShowPanel() { fun testLimitTimesShown() {
assertThat(infoProvider.shouldShowMessage()).isFalse() whenever(sharedPrefs.getInt(eq(KEY_VIEW_COUNT), anyInt())).thenReturn(4)
assertFalse(infoProvider.shouldShowMessage())
} }
} }