mirror of
https://github.com/bitwarden/android.git
synced 2024-11-22 01:16:02 +03:00
Add My Vault and Password Generator Quick Settings tiles (#3764)
This commit is contained in:
parent
76a3265bbb
commit
9dbb40f33b
6 changed files with 175 additions and 4 deletions
|
@ -72,6 +72,7 @@
|
||||||
<action android:name="com.x8bit.bitwarden.fido2.ACTION_CREATE_PASSKEY" />
|
<action android:name="com.x8bit.bitwarden.fido2.ACTION_CREATE_PASSKEY" />
|
||||||
<action android:name="com.x8bit.bitwarden.fido2.ACTION_GET_PASSKEY" />
|
<action android:name="com.x8bit.bitwarden.fido2.ACTION_GET_PASSKEY" />
|
||||||
<action android:name="com.x8bit.bitwarden.fido2.ACTION_UNLOCK_ACCOUNT" />
|
<action android:name="com.x8bit.bitwarden.fido2.ACTION_UNLOCK_ACCOUNT" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -191,6 +192,42 @@
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The GeneratorTileService name below refers to the legacy Xamarin app's service name.
|
||||||
|
This must always match in order for the app to properly query if it is providing generator
|
||||||
|
tile services.
|
||||||
|
-->
|
||||||
|
<!--suppress AndroidDomInspection -->
|
||||||
|
<service
|
||||||
|
android:name="com.x8bit.bitwarden.GeneratorTileService"
|
||||||
|
android:exported="true"
|
||||||
|
android:icon="@drawable/ic_generator"
|
||||||
|
android:label="@string/password_generator"
|
||||||
|
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
|
||||||
|
tools:ignore="MissingClass">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.quicksettings.action.QS_TILE" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The MyVaultTileService name below refers to the legacy Xamarin app's service name.
|
||||||
|
This must always match in order for the app to properly query if it is providing vault
|
||||||
|
tile services.
|
||||||
|
-->
|
||||||
|
<!--suppress AndroidDomInspection -->
|
||||||
|
<service
|
||||||
|
android:name="com.x8bit.bitwarden.MyVaultTileService"
|
||||||
|
android:exported="true"
|
||||||
|
android:icon="@drawable/ic_notification"
|
||||||
|
android:label="@string/my_vault"
|
||||||
|
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
|
||||||
|
tools:ignore="MissingClass">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.quicksettings.action.QS_TILE" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.content.APP_RESTRICTIONS"
|
android:name="android.content.APP_RESTRICTIONS"
|
||||||
android:resource="@xml/app_restrictions" />
|
android:resource="@xml/app_restrictions" />
|
||||||
|
|
|
@ -7,10 +7,14 @@ import androidx.core.app.AppComponentFactory
|
||||||
import com.x8bit.bitwarden.data.autofill.BitwardenAutofillService
|
import com.x8bit.bitwarden.data.autofill.BitwardenAutofillService
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.BitwardenFido2ProviderService
|
import com.x8bit.bitwarden.data.autofill.fido2.BitwardenFido2ProviderService
|
||||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||||
|
import com.x8bit.bitwarden.data.tiles.BitwardenGeneratorTileService
|
||||||
|
import com.x8bit.bitwarden.data.tiles.BitwardenVaultTileService
|
||||||
|
|
||||||
private const val LEGACY_AUTOFILL_SERVICE_NAME = "com.x8bit.bitwarden.Autofill.AutofillService"
|
private const val LEGACY_AUTOFILL_SERVICE_NAME = "com.x8bit.bitwarden.Autofill.AutofillService"
|
||||||
private const val LEGACY_CREDENTIAL_SERVICE_NAME =
|
private const val LEGACY_CREDENTIAL_SERVICE_NAME =
|
||||||
"com.x8bit.bitwarden.Autofill.CredentialProviderService"
|
"com.x8bit.bitwarden.Autofill.CredentialProviderService"
|
||||||
|
private const val LEGACY_VAULT_TILE_SERVICE_NAME = "com.x8bit.bitwarden.MyVaultTileService"
|
||||||
|
private const val LEGACY_GENERATOR_TILE_SERVICE_NAME = "com.x8bit.bitwarden.GeneratorTileService"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory class that allows us to intercept when a manifest element is being instantiated
|
* A factory class that allows us to intercept when a manifest element is being instantiated
|
||||||
|
@ -20,10 +24,11 @@ private const val LEGACY_CREDENTIAL_SERVICE_NAME =
|
||||||
@OmitFromCoverage
|
@OmitFromCoverage
|
||||||
class BitwardenAppComponentFactory : AppComponentFactory() {
|
class BitwardenAppComponentFactory : AppComponentFactory() {
|
||||||
/**
|
/**
|
||||||
* Used to intercept when the [BitwardenAutofillService] or [BitwardenFido2ProviderService] is
|
* Used to intercept when the [BitwardenAutofillService], [BitwardenFido2ProviderService],
|
||||||
* being instantiated and modify which service is created. This is required because the
|
* [BitwardenVaultTileService], or [BitwardenGeneratorTileService] is being instantiated and
|
||||||
* [className] used in the manifest must match the legacy Xamarin app service name but the
|
* modify which service is created. This is required because the [className] used in the
|
||||||
* service name in this app is different.
|
* manifest must match the legacy Xamarin app service name but the service name in this app is
|
||||||
|
* different.
|
||||||
*/
|
*/
|
||||||
override fun instantiateServiceCompat(
|
override fun instantiateServiceCompat(
|
||||||
cl: ClassLoader,
|
cl: ClassLoader,
|
||||||
|
@ -48,6 +53,18 @@ class BitwardenAppComponentFactory : AppComponentFactory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LEGACY_VAULT_TILE_SERVICE_NAME -> {
|
||||||
|
super.instantiateServiceCompat(cl, BitwardenVaultTileService::class.java.name, intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
LEGACY_GENERATOR_TILE_SERVICE_NAME -> {
|
||||||
|
super.instantiateServiceCompat(
|
||||||
|
cl,
|
||||||
|
BitwardenGeneratorTileService::class.java.name,
|
||||||
|
intent,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
else -> super.instantiateServiceCompat(cl, className, intent)
|
else -> super.instantiateServiceCompat(cl, className, intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.x8bit.bitwarden.data.tiles
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import android.service.quicksettings.TileService
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.isBuildVersionBelow
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.Runnable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service for handling the Password Generator quick settings tile.
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
@Keep
|
||||||
|
@OmitFromCoverage
|
||||||
|
class BitwardenGeneratorTileService : TileService() {
|
||||||
|
@Inject
|
||||||
|
lateinit var intentManager: IntentManager
|
||||||
|
|
||||||
|
override fun onClick() {
|
||||||
|
if (isLocked) {
|
||||||
|
unlockAndRun(Runnable { launchGenerator() })
|
||||||
|
} else {
|
||||||
|
launchGenerator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
@SuppressLint("StartActivityAndCollapseDeprecated")
|
||||||
|
private fun launchGenerator() {
|
||||||
|
val intent = intentManager.createTileIntent("bitwarden://password_generator")
|
||||||
|
|
||||||
|
if (isBuildVersionBelow(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)) {
|
||||||
|
startActivityAndCollapse(intent)
|
||||||
|
} else {
|
||||||
|
startActivityAndCollapse(intentManager.createTilePendingIntent(0, intent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.x8bit.bitwarden.data.tiles
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import android.service.quicksettings.TileService
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.isBuildVersionBelow
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.Runnable
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service for handling the My Vault quick settings tile.
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
@Keep
|
||||||
|
@OmitFromCoverage
|
||||||
|
class BitwardenVaultTileService : TileService() {
|
||||||
|
@Inject
|
||||||
|
lateinit var intentManager: IntentManager
|
||||||
|
|
||||||
|
override fun onClick() {
|
||||||
|
if (isLocked) {
|
||||||
|
unlockAndRun(Runnable { launchVault() })
|
||||||
|
} else {
|
||||||
|
launchVault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
@SuppressLint("StartActivityAndCollapseDeprecated")
|
||||||
|
private fun launchVault() {
|
||||||
|
val intent = intentManager.createTileIntent("bitwarden://my_vault")
|
||||||
|
|
||||||
|
if (isBuildVersionBelow(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)) {
|
||||||
|
startActivityAndCollapse(intent)
|
||||||
|
} else {
|
||||||
|
startActivityAndCollapse(intentManager.createTilePendingIntent(0, intent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,6 +87,17 @@ interface IntentManager {
|
||||||
*/
|
*/
|
||||||
fun createDocumentIntent(fileName: String): Intent
|
fun createDocumentIntent(fileName: String): Intent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an intent using [data] when selecting a quick settings tile.
|
||||||
|
*/
|
||||||
|
fun createTileIntent(data: String): Intent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a pending intent using [requestCode] and [tileIntent] when selecting a quick
|
||||||
|
* settings tile on API 34+.
|
||||||
|
*/
|
||||||
|
fun createTilePendingIntent(requestCode: Int, tileIntent: Intent): PendingIntent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a pending intent to use when providing [androidx.credentials.provider.CreateEntry]
|
* Creates a pending intent to use when providing [androidx.credentials.provider.CreateEntry]
|
||||||
* instances for FIDO 2 credential creation.
|
* instances for FIDO 2 credential creation.
|
||||||
|
|
|
@ -20,8 +20,10 @@ import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.credentials.CredentialManager
|
import androidx.credentials.CredentialManager
|
||||||
import com.x8bit.bitwarden.BuildConfig
|
import com.x8bit.bitwarden.BuildConfig
|
||||||
|
import com.x8bit.bitwarden.MainActivity
|
||||||
import com.x8bit.bitwarden.R
|
import com.x8bit.bitwarden.R
|
||||||
import com.x8bit.bitwarden.data.autofill.util.toPendingIntentMutabilityFlag
|
import com.x8bit.bitwarden.data.autofill.util.toPendingIntentMutabilityFlag
|
||||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||||
|
@ -215,6 +217,24 @@ class IntentManagerImpl(
|
||||||
putExtra(Intent.EXTRA_TITLE, fileName)
|
putExtra(Intent.EXTRA_TITLE, fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createTileIntent(data: String): Intent {
|
||||||
|
return Intent(
|
||||||
|
context,
|
||||||
|
MainActivity::class.java,
|
||||||
|
)
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
.setData(data.toUri())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTilePendingIntent(requestCode: Int, tileIntent: Intent): PendingIntent {
|
||||||
|
return PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
requestCode,
|
||||||
|
tileIntent,
|
||||||
|
PendingIntent.FLAG_IMMUTABLE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createFido2CreationPendingIntent(
|
override fun createFido2CreationPendingIntent(
|
||||||
action: String,
|
action: String,
|
||||||
userId: String,
|
userId: String,
|
||||||
|
|
Loading…
Reference in a new issue