Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add safer intents sample #162

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ android {

defaultConfig {
applicationId = "com.example.platform.app"
minSdk = 21
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not looking to upgrade our minSdk to 24. You should use RequiresApi annotation around your sample instead

minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ accompanist = "0.32.0"
androidx-datastore = "1.0.0"
androidx-navigation = "2.7.7"
androidx-window = "1.2.0"
agp = "8.2.2"
agp = "8.4.1"
casa = "0.5.1"
coil = "2.4.0"
ksp = "1.9.22-1.0.17"
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
#Wed Dec 07 13:21:03 CET 2022
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 2 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Shows Predictive Back animations.
Add your custom tile to the Quick Settings.
- [Receive data shared by other apps](user-interface/share/src/main/java/com/example/platform/ui/share/receiver/ShareReceiverActivity.kt):
Receive texts and images from other apps.
- [SaferIntents](security/intents/src/main/java/com/example/platform/security/intents/SaferIntents.kt):
Example on how can fix the miss use of intents
- [Scan with BLE Intent](connectivity/bluetooth/ble/src/main/java/com/example/platform/connectivity/bluetooth/ble/BLEScanIntentSample.kt):
This samples shows how to use the BLE intent to scan for devices
- [Screenshot Detection](privacy/transparency/src/main/java/com/example/platform/privacy/transparency/ScreenshotDetection.kt):
Expand Down
10 changes: 10 additions & 0 deletions samples/security/intents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SaferIntents samples

This sample shows that it is important to not have a NULL intent.
It contains 2 buttons:

- One button sends an NULL intent
- Another button sends a regular intent

It is important to note that for the NULL intent an exception handling has taken place.
If an app sends a NULL intent it will crash with an `ActivityNotFound` exception
29 changes: 29 additions & 0 deletions samples/security/intents/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


plugins {
id("com.example.platform.sample")
}

android {
namespace = "com.example.platform.security.intents"
}

dependencies {
// Add samples specific dependencies
}
27 changes: 27 additions & 0 deletions samples/security/intents/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".SaferIntentsActivity"
android:exported="true">
<intent-filter>
<action android:name="com.example.platform.security.intents.MY_ACTION" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this intent action filter, will this activity be launched with the NULL intent? If yes, explain it in comments

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@

/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package com.example.platform.security.intents

import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Intent
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.google.android.catalog.framework.annotations.Sample

@Sample(
name = "SaferIntents",
description = "Example on how can fix the miss use of intents"
)
@SuppressLint("IntentWithNullActionLaunch")
@Composable
fun SaferIntents() {
val context = LocalContext.current

Column (
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
){
Button(onClick = {
val intent = Intent()
try {
context.startActivity(intent)
} catch (e : ActivityNotFoundException) {
Toast.makeText(context, "Error: " + e.message, Toast.LENGTH_SHORT).show()
}
}) {
Text(text = "Send NULL Intent")
}

Button(onClick = {
val intent = Intent("com.example.platform.security.intents.MY_ACTION")
context.startActivity(intent)
}) {
Text(text = "Send Intent")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.platform.security.intents

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

class SaferIntentsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Toast.makeText(applicationContext, "Activity successfully created", Toast.LENGTH_SHORT).show()

setContent {
MaterialTheme {
Surface (
Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
){
HelloAndroidScreen()
}
}
}
}
}
@Composable
fun HelloAndroidScreen() {
Text(text = "Hello Android!")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline this function directly inside the Surface composable

}
Loading