For #22576 - Indicate mutability flag for PendingIntent

* For #22576 - Indicate mutability flag for PendingIntent

* Fix lint issues

* Make Analytics Pending Intent flag mutable

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
upstream-sync
Sarah541 2 years ago committed by GitHub
parent 4a8cfb0d6a
commit ef5966cddd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1031,72 +1031,6 @@
column="10"/> column="10"/>
</issue> </issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" 0"
errorLine2=" ~">
<location
file="src/main/java/org/mozilla/fenix/components/Analytics.kt"
line="77"
column="13"/>
</issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" 0"
errorLine2=" ~">
<location
file="src/main/java/org/mozilla/fenix/onboarding/DefaultBrowserNotificationWorker.kt"
line="57"
column="13"/>
</issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/org/mozilla/fenix/components/NotificationManager.kt"
line="61"
column="63"/>
</issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" .getActivity(context, 0, homeScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/org/mozilla/fenix/components/PrivateShortcutCreateManager.kt"
line="57"
column="56"/>
</issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" REQUEST_CODE_NEW_TAB, intent, PendingIntent.FLAG_UPDATE_CURRENT"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/java/org/mozilla/gecko/search/SearchWidgetProvider.kt"
line="96"
column="51"/>
</issue>
<issue
id="UnspecifiedImmutableFlag"
message="Missing `PendingIntent` mutability flag"
errorLine1=" REQUEST_CODE_VOICE, voiceIntent, 0"
errorLine2=" ~">
<location
file="src/main/java/org/mozilla/gecko/search/SearchWidgetProvider.kt"
line="120"
column="50"/>
</issue>
<issue <issue
id="MozMultipleConstraintLayouts" id="MozMultipleConstraintLayouts"
message="Flatten the view hierarchy by using one `ConstraintLayout`, if possible. If the alternative is several nested `ViewGroup`, it may not help performance and this may be worth suppressing." message="Flatten the view hierarchy by using one `ConstraintLayout`, if possible. If the alternative is several nested `ViewGroup`, it may not help performance and this may be worth suppressing."

@ -50,6 +50,7 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource
import org.mozilla.fenix.ui.robots.BrowserRobot import org.mozilla.fenix.ui.robots.BrowserRobot
import org.mozilla.fenix.ui.robots.mDevice import org.mozilla.fenix.ui.robots.mDevice
import org.mozilla.fenix.utils.IntentUtils
import java.io.File import java.io.File
object TestHelper { object TestHelper {
@ -176,7 +177,7 @@ object TestHelper {
val appContext = InstrumentationRegistry.getInstrumentation() val appContext = InstrumentationRegistry.getInstrumentation()
.targetContext .targetContext
.applicationContext .applicationContext
val pendingIntent = PendingIntent.getActivity(appContext, 0, Intent(), 0) val pendingIntent = PendingIntent.getActivity(appContext, 0, Intent(), IntentUtils.defaultIntentPendingFlags)
val customTabsIntent = CustomTabsIntent.Builder() val customTabsIntent = CustomTabsIntent.Builder()
.addMenuItem(customMenuItemLabel, pendingIntent) .addMenuItem(customMenuItemLabel, pendingIntent)
.setShareState(CustomTabsIntent.SHARE_STATE_ON) .setShareState(CustomTabsIntent.SHARE_STATE_ON)

@ -8,6 +8,7 @@ import android.app.Application
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import mozilla.components.lib.crash.CrashReporter import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.service.CrashReporterService import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.lib.crash.service.GleanCrashReporterService import mozilla.components.lib.crash.service.GleanCrashReporterService
@ -69,12 +70,16 @@ class Analytics(
val intent = Intent(context, HomeActivity::class.java).apply { val intent = Intent(context, HomeActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
} }
val crashReportingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_MUTABLE
} else {
0 // No flags. Default behavior.
}
val pendingIntent = PendingIntent.getActivity( val pendingIntent = PendingIntent.getActivity(
context, context,
0, 0,
intent, intent,
0 crashReportingIntentFlags
) )
CrashReporter( CrashReporter(

@ -21,6 +21,7 @@ import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.TabData import mozilla.components.concept.sync.TabData
import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.utils.IntentUtils
/** /**
* Manages notification channels and allows displaying different types of notifications. * Manages notification channels and allows displaying different types of notifications.
@ -54,11 +55,12 @@ class NotificationManager(private val context: Context) {
// For now, a single notification per tab received will suffice. // For now, a single notification per tab received will suffice.
logger.debug("Showing ${tabs.size} tab(s) received from deviceID=${device?.id}") logger.debug("Showing ${tabs.size} tab(s) received from deviceID=${device?.id}")
tabs.forEach { tab -> tabs.forEach { tab ->
val showReceivedTabsIntentFlags = IntentUtils.defaultIntentPendingFlags or PendingIntent.FLAG_ONE_SHOT
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(tab.url)) val intent = Intent(Intent.ACTION_VIEW, Uri.parse(tab.url))
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra(RECEIVE_TABS_TAG, true) intent.putExtra(RECEIVE_TABS_TAG, true)
val pendingIntent: PendingIntent = val pendingIntent: PendingIntent =
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT) PendingIntent.getActivity(context, 0, intent, showReceivedTabsIntentFlags)
val builder = NotificationCompat.Builder(context, RECEIVE_TABS_CHANNEL_ID) val builder = NotificationCompat.Builder(context, RECEIVE_TABS_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_status_logo) .setSmallIcon(R.drawable.ic_status_logo)

@ -13,6 +13,7 @@ import androidx.core.graphics.drawable.IconCompat
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.home.intent.StartSearchIntentProcessor import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
import org.mozilla.fenix.utils.IntentUtils
import java.util.UUID import java.util.UUID
/** /**
@ -50,11 +51,13 @@ object PrivateShortcutCreateManager {
} }
) )
.build() .build()
val createPrivateShortcutIntentFlags = IntentUtils.defaultIntentPendingFlags or
PendingIntent.FLAG_UPDATE_CURRENT
val homeScreenIntent = Intent(Intent.ACTION_MAIN) val homeScreenIntent = Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME) .addCategory(Intent.CATEGORY_HOME)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val intentSender = PendingIntent val intentSender = PendingIntent
.getActivity(context, 0, homeScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT) .getActivity(context, 0, homeScreenIntent, createPrivateShortcutIntentFlags)
.intentSender .intentSender
ShortcutManagerCompat.requestPinShortcut(context, shortcut, intentSender) ShortcutManagerCompat.requestPinShortcut(context, shortcut, intentSender)
} }

@ -24,6 +24,7 @@ import mozilla.components.support.base.ids.SharedIdsHelper
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.utils.IntentUtils
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
class DefaultBrowserNotificationWorker( class DefaultBrowserNotificationWorker(
@ -54,7 +55,7 @@ class DefaultBrowserNotificationWorker(
applicationContext, applicationContext,
SharedIdsHelper.getNextIdForTag(applicationContext, NOTIFICATION_PENDING_INTENT_TAG), SharedIdsHelper.getNextIdForTag(applicationContext, NOTIFICATION_PENDING_INTENT_TAG),
intent, intent,
0 IntentUtils.defaultIntentPendingFlags
) )
with(applicationContext) { with(applicationContext) {

@ -0,0 +1,23 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.utils
import android.app.PendingIntent
import android.os.Build
object IntentUtils {
/**
* Since Android 12 we need to set PendingIntent mutability explicitly, but Android 6 can be the minimum version
* This additional requirement improves your app's security.
* FLAG_IMMUTABLE -> Flag indicating that the created PendingIntent should be immutable.
*/
val defaultIntentPendingFlags
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_IMMUTABLE
} else {
0 // No flags. Default behavior.
}
}

@ -28,6 +28,7 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.intent.StartSearchIntentProcessor import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
import org.mozilla.fenix.utils.IntentUtils
import org.mozilla.fenix.widget.VoiceSearchActivity import org.mozilla.fenix.widget.VoiceSearchActivity
import org.mozilla.fenix.widget.VoiceSearchActivity.Companion.SPEECH_PROCESSING import org.mozilla.fenix.widget.VoiceSearchActivity.Companion.SPEECH_PROCESSING
@ -89,11 +90,13 @@ class SearchWidgetProvider : AppWidgetProvider() {
private fun createTextSearchIntent(context: Context): PendingIntent { private fun createTextSearchIntent(context: Context): PendingIntent {
return Intent(context, IntentReceiverActivity::class.java) return Intent(context, IntentReceiverActivity::class.java)
.let { intent -> .let { intent ->
val createTextSearchIntentFlags = IntentUtils.defaultIntentPendingFlags or
PendingIntent.FLAG_UPDATE_CURRENT
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra(HomeActivity.OPEN_TO_SEARCH, StartSearchIntentProcessor.SEARCH_WIDGET) intent.putExtra(HomeActivity.OPEN_TO_SEARCH, StartSearchIntentProcessor.SEARCH_WIDGET)
PendingIntent.getActivity( PendingIntent.getActivity(
context, context,
REQUEST_CODE_NEW_TAB, intent, PendingIntent.FLAG_UPDATE_CURRENT REQUEST_CODE_NEW_TAB, intent, createTextSearchIntentFlags
) )
} }
} }
@ -117,7 +120,7 @@ class SearchWidgetProvider : AppWidgetProvider() {
return intentSpeech.resolveActivity(context.packageManager)?.let { return intentSpeech.resolveActivity(context.packageManager)?.let {
PendingIntent.getActivity( PendingIntent.getActivity(
context, context,
REQUEST_CODE_VOICE, voiceIntent, 0 REQUEST_CODE_VOICE, voiceIntent, IntentUtils.defaultIntentPendingFlags
) )
} }
} }

@ -24,6 +24,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.intent.StartSearchIntentProcessor import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
import org.mozilla.fenix.utils.IntentUtils
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class PrivateShortcutCreateManagerTest { class PrivateShortcutCreateManagerTest {
@ -59,7 +60,7 @@ class PrivateShortcutCreateManagerTest {
PrivateShortcutCreateManager.createPrivateShortcut(testContext) PrivateShortcutCreateManager.createPrivateShortcut(testContext)
verify { PendingIntent.getActivity(testContext, 0, capture(intent), PendingIntent.FLAG_UPDATE_CURRENT) } verify { PendingIntent.getActivity(testContext, 0, capture(intent), IntentUtils.defaultIntentPendingFlags or PendingIntent.FLAG_UPDATE_CURRENT) }
verify { ShortcutManagerCompat.requestPinShortcut(testContext, capture(shortcut), capture(intentSender)) } verify { ShortcutManagerCompat.requestPinShortcut(testContext, capture(shortcut), capture(intentSender)) }
`assert shortcutInfoCompat is build correctly`(shortcut.captured) `assert shortcutInfoCompat is build correctly`(shortcut.captured)
`assert homeScreenIntent is built correctly`(intent.captured) `assert homeScreenIntent is built correctly`(intent.captured)

Loading…
Cancel
Save