Skip to content

Commit

Permalink
Add PendingIntent mutability flags
Browse files Browse the repository at this point in the history
Use `FLAG_IMMUTABLE` except for the one case where we support remote input (on Wear OS devices).
  • Loading branch information
ianhanniballake committed Jul 17, 2021
1 parent b862a2c commit d4f348a
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.example.muzei.unsplash

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
Expand Down Expand Up @@ -46,6 +47,7 @@ class UnsplashExampleArtProvider : MuzeiArtProvider() {
createVisitUnsplashAction(context))
}

@SuppressLint("InlinedApi")
private fun createViewProfileAction(context: Context, artwork: Artwork): RemoteActionCompat? {
val profileUri = artwork.metadata?.toUri() ?: return null
val title = context.getString(R.string.action_view_profile, artwork.byline)
Expand All @@ -55,9 +57,10 @@ class UnsplashExampleArtProvider : MuzeiArtProvider() {
title,
title,
PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
}

@SuppressLint("InlinedApi")
private fun createVisitUnsplashAction(context: Context): RemoteActionCompat {
val title = context.getString(R.string.action_visit_unsplash)
val unsplashUri = context.getString(R.string.unsplash_link) +
Expand All @@ -69,7 +72,7 @@ class UnsplashExampleArtProvider : MuzeiArtProvider() {
title,
title,
PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT)).apply {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)).apply {
setShouldShowIcon(false)
}
}
Expand All @@ -85,4 +88,4 @@ class UnsplashExampleArtProvider : MuzeiArtProvider() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.apps.muzei.legacy

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
Expand All @@ -32,13 +33,14 @@ class SendActionBroadcastReceiver : BroadcastReceiver() {
private const val TAG = "SendActionReceiver"
private const val KEY_ID = "id"

@SuppressLint("InlinedApi")
fun createPendingIntent(
context: Context,
id: Int
): PendingIntent = PendingIntent.getBroadcast(context, id,
Intent(context, SendActionBroadcastReceiver::class.java).apply {
putExtra(KEY_ID, id)
}, PendingIntent.FLAG_UPDATE_CURRENT)
}, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}

override fun onReceive(context: Context, intent: Intent) {
Expand All @@ -56,4 +58,4 @@ class SendActionBroadcastReceiver : BroadcastReceiver() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class SourceArtProvider : MuzeiArtProvider() {
}
} ?: super.getCommandActions(artwork)

@SuppressLint("InlinedApi")
override fun getArtworkInfo(artwork: Artwork): PendingIntent? {
val context = context ?: return null
val webUri = artwork.webUri ?: return null
Expand All @@ -129,7 +130,8 @@ class SourceArtProvider : MuzeiArtProvider() {
Intent.parseUri(webUri.toString(), Intent.URI_INTENT_SCHEME)?.run {
// Make sure any data URIs granted to Muzei are passed onto the started Activity
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
return PendingIntent.getActivity(context, 0, this, 0)
return PendingIntent.getActivity(context, 0, this,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
} catch (e: URISyntaxException) {
Log.i(TAG, "Unable to parse viewIntent $artwork", e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.google.android.apps.muzei.legacy

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
Expand Down Expand Up @@ -143,6 +144,7 @@ class LegacySourcePackageListener(
legacySources.toList()
}

@SuppressLint("InlinedApi")
private fun updateNotifiedSources(legacySources: Set<LegacySourceInfo>) {
val additions = legacySources - lastNotifiedSources
val removals = lastNotifiedSources - legacySources
Expand Down Expand Up @@ -173,14 +175,14 @@ class LegacySourcePackageListener(
Intent(Intent.ACTION_VIEW, LegacySourceManager.LEARN_MORE_LINK).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
},
0)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
// Send a notification for each new Legacy Source
for (info in additions) {
val sendFeedbackPendingIntent = PendingIntent.getActivity(
applicationContext, 0,
Intent(Intent.ACTION_VIEW,
"https://play.google.com/store/apps/details?id=${info.packageName}".toUri()),
0)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL)
.setSmallIcon(R.drawable.ic_stat_muzei)
.setColor(ContextCompat.getColor(applicationContext, R.color.notification))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.apps.muzei.notifications

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
Expand Down Expand Up @@ -101,6 +102,7 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
return sp.getBoolean(PREF_ENABLED, true)
}

@SuppressLint("InlinedApi")
suspend fun maybeShowNewArtworkNotification(context: Context) {
if (ArtDetailOpen.value) {
return
Expand Down Expand Up @@ -156,11 +158,11 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
.setLargeIcon(largeIcon)
.setContentIntent(PendingIntent.getActivity(context, 0,
context.packageManager.getLaunchIntentForPackage(context.packageName),
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
.setDeleteIntent(PendingIntent.getBroadcast(context, 0,
Intent(context, NewWallpaperNotificationReceiver::class.java)
.setAction(ACTION_MARK_NOTIFICATION_READ),
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
val style = NotificationCompat.BigPictureStyle()
.bigLargeIcon(null)
.setBigContentTitle(title)
Expand All @@ -175,7 +177,7 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
val nextPendingIntent = PendingIntent.getBroadcast(context, 0,
Intent(context, NewWallpaperNotificationReceiver::class.java)
.setAction(ACTION_NEXT_ARTWORK),
PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val nextAction = NotificationCompat.Action.Builder(
R.drawable.ic_notif_next_artwork,
context.getString(R.string.action_next_artwork_condensed),
Expand All @@ -193,7 +195,7 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
val userCommandPendingIntent = PendingIntent.getBroadcast(context, 0,
Intent(context, NewWallpaperNotificationReceiver::class.java)
.setAction(ACTION_USER_COMMAND),
PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
val remoteInput = RemoteInput.Builder(EXTRA_USER_COMMAND)
.setAllowFreeFormInput(false)
.setLabel(context.getString(R.string.action_user_command_prompt))
Expand All @@ -208,7 +210,7 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
}
val viewPendingIntent = PendingIntent.getActivity(context, 0,
ArtworkInfoRedirectActivity.getIntent(context, "notification"),
PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val viewAction = NotificationCompat.Action.Builder(
R.drawable.ic_notif_info,
context.getString(R.string.action_artwork_info),
Expand All @@ -229,11 +231,11 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
.setContentText(context.getString(R.string.notification_new_wallpaper))
.setContentIntent(PendingIntent.getActivity(context, 0,
context.packageManager.getLaunchIntentForPackage(context.packageName),
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
.setDeleteIntent(PendingIntent.getBroadcast(context, 0,
Intent(context, NewWallpaperNotificationReceiver::class.java)
.setAction(ACTION_MARK_NOTIFICATION_READ),
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
nb.setPublicVersion(publicBuilder.build())

val nm = NotificationManagerCompat.from(context)
Expand Down Expand Up @@ -282,7 +284,7 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
.setContentText(context.getText(R.string.notification_settings_moved_text))
.setContentIntent(PendingIntent.getActivity(context, 0,
settingsIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
.setStyle(NotificationCompat.BigTextStyle()
.bigText(context.getText(R.string.notification_settings_moved_text)))
notificationManager.notify(1, builder.build())
Expand Down Expand Up @@ -339,4 +341,4 @@ class NewWallpaperNotificationReceiver : BroadcastReceiver() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.apps.muzei.widget

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
Expand Down Expand Up @@ -126,6 +127,7 @@ suspend fun updateAppWidget(context: Context) = coroutineScope {
}
}

@SuppressLint("InlinedApi")
@OptIn(ExperimentalCoroutinesApi::class)
private suspend fun createRemoteViews(
context: Context,
Expand All @@ -141,13 +143,15 @@ private suspend fun createRemoteViews(

// Update the widget(s) with the new artwork information
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
val launchPendingIntent = PendingIntent.getActivity(context,
0, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val launchPendingIntent = PendingIntent.getActivity(
context, 0, launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val nextArtworkIntent = Intent(context, MuzeiAppWidgetProvider::class.java).apply {
action = MuzeiAppWidgetProvider.ACTION_NEXT_ARTWORK
}
val nextArtworkPendingIntent = PendingIntent.getBroadcast(context,
0, nextArtworkIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val nextArtworkPendingIntent = PendingIntent.getBroadcast(
context, 0, nextArtworkIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val smallWidgetHeight = context.resources.getDimensionPixelSize(
R.dimen.widget_small_height_breakpoint)
val image = ImageLoader.decode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.apps.muzei.api.internal

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ContentUris
Expand Down Expand Up @@ -52,6 +53,7 @@ public class RemoteActionBroadcastReceiver : BroadcastReceiver() {
* through the inefficiency of starting this receiver just to trigger
* your [com.google.android.apps.muzei.api.provider.MuzeiArtProvider].
*/
@SuppressLint("InlinedApi")
public fun createPendingIntent(
context: Context,
authority: String,
Expand All @@ -66,7 +68,7 @@ public class RemoteActionBroadcastReceiver : BroadcastReceiver() {
return PendingIntent.getBroadcast(context,
id + 1000 * artworkId.toInt(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
}

Expand All @@ -88,4 +90,4 @@ public class RemoteActionBroadcastReceiver : BroadcastReceiver() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,14 @@ class ActivateMuzeiReceiver : BroadcastReceiver() {
val deleteIntent = Intent(context, ActivateMuzeiReceiver::class.java).apply {
action = ACTION_MARK_NOTIFICATION_READ
}
builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, deleteIntent, 0))
builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, deleteIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))

val installMuzeiIntent = Intent(context, ActivateMuzeiReceiver::class.java).apply {
action = ACTION_REMOTE_INSTALL_MUZEI
}
val pendingIntent = PendingIntent.getBroadcast(context, 0, installMuzeiIntent, 0)
val pendingIntent = PendingIntent.getBroadcast(context, 0, installMuzeiIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
builder.addAction(NotificationCompat.Action.Builder(R.drawable.open_on_phone,
context.getString(R.string.datalayer_install_action), pendingIntent)
.extend(NotificationCompat.Action.WearableExtender()
Expand Down Expand Up @@ -208,4 +210,4 @@ class ActivateMuzeiReceiver : BroadcastReceiver() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ class DataLayerArtProvider : MuzeiArtProvider() {
title,
title,
PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT))
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
}

@Throws(FileNotFoundException::class)
override fun openFile(artwork: Artwork): InputStream {
val context = context ?: throw FileNotFoundException()
return FileInputStream(getAssetFile(context))
}
}
}

0 comments on commit d4f348a

Please sign in to comment.