[PS-1312] Migration to android12 and new splashscreen (#2063)

* [PS-1312] Updated Android Target and Framework to Android12 and updated new SplashScreen for Android12

* PS-1312 Changed PendingIntents mutability

* PS-1312 Removed unused imports

* PS-1312 Added method to helper to add mutability option according to Android version

* PS-1312 Renamed helper method AddPendingIntentMutability and fixed validation

* PS-1312 Improved PendingIntentMutability method from helper readability and naming
This commit is contained in:
aj-rosado 2022-09-16 16:44:15 +01:00 committed by GitHub
parent afa9e23707
commit 305c770c58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 69 additions and 15 deletions

View file

@ -15,7 +15,7 @@ using Bit.Core.Utilities;
namespace Bit.Droid.Accessibility namespace Bit.Droid.Accessibility
{ {
[Service(Permission = Android.Manifest.Permission.BindAccessibilityService, Label = "Bitwarden")] [Service(Permission = Android.Manifest.Permission.BindAccessibilityService, Label = "Bitwarden", Exported = true)]
[IntentFilter(new string[] { "android.accessibilityservice.AccessibilityService" })] [IntentFilter(new string[] { "android.accessibilityservice.AccessibilityService" })]
[MetaData("android.accessibilityservice", Resource = "@xml/accessibilityservice")] [MetaData("android.accessibilityservice", Resource = "@xml/accessibilityservice")]
[Register("com.x8bit.bitwarden.Accessibility.AccessibilityService")] [Register("com.x8bit.bitwarden.Accessibility.AccessibilityService")]

View file

@ -15,7 +15,7 @@
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix> <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix> <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<TargetFrameworkVersion>v11.0</TargetFrameworkVersion> <TargetFrameworkVersion>v12.1</TargetFrameworkVersion>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType> <AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
@ -213,6 +213,9 @@
<AndroidResource Include="Resources\values\colors.xml" /> <AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\values\manifest.xml" /> <AndroidResource Include="Resources\values\manifest.xml" />
<AndroidResource Include="Resources\values-v30\manifest.xml" /> <AndroidResource Include="Resources\values-v30\manifest.xml" />
<AndroidResource Include="Resources\drawable-v26\splash_screen_round.xml" />
<AndroidResource Include="Resources\drawable\logo_rounded.xml" />
<AndroidResource Include="Resources\drawable-night-v26\splash_screen_round.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\drawable\splash_screen.xml" /> <AndroidResource Include="Resources\drawable\splash_screen.xml" />
@ -280,6 +283,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Resources\values-v30\" /> <Folder Include="Resources\values-v30\" />
<Folder Include="Resources\drawable-v26\" />
<Folder Include="Resources\drawable-night-v26\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project> </Project>

View file

@ -19,6 +19,7 @@ using AndroidX.AutoFill.Inline;
using AndroidX.AutoFill.Inline.V1; using AndroidX.AutoFill.Inline.V1;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using SaveFlags = Android.Service.Autofill.SaveFlags; using SaveFlags = Android.Service.Autofill.SaveFlags;
using Bit.Droid.Utilities;
namespace Bit.Droid.Autofill namespace Bit.Droid.Autofill
{ {
@ -270,8 +271,7 @@ namespace Bit.Droid.Autofill
return null; return null;
} }
intent.PutExtra("autofillFrameworkUri", uri); intent.PutExtra("autofillFrameworkUri", uri);
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent, var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent, AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.CancelCurrent, true));
PendingIntentFlags.CancelCurrent);
var overlayPresentation = BuildOverlayPresentation( var overlayPresentation = BuildOverlayPresentation(
AppResources.AutofillWithBitwarden, AppResources.AutofillWithBitwarden,
@ -324,7 +324,7 @@ namespace Bit.Droid.Autofill
// InlinePresentation requires nonNull pending intent (even though we only utilize one for the // InlinePresentation requires nonNull pending intent (even though we only utilize one for the
// "my vault" presentation) so we're including an empty one here // "my vault" presentation) so we're including an empty one here
pendingIntent = PendingIntent.GetService(context, 0, new Intent(), pendingIntent = PendingIntent.GetService(context, 0, new Intent(),
PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent); AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent, true));
} }
var slice = CreateInlinePresentationSlice( var slice = CreateInlinePresentationSlice(
inlinePresentationSpec, inlinePresentationSpec,

View file

@ -15,7 +15,7 @@ using Bit.Core.Utilities;
namespace Bit.Droid.Autofill namespace Bit.Droid.Autofill
{ {
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden")] [Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden", Exported = true)]
[IntentFilter(new string[] { "android.service.autofill.AutofillService" })] [IntentFilter(new string[] { "android.service.autofill.AutofillService" })]
[MetaData("android.autofill", Resource = "@xml/autofillservice")] [MetaData("android.autofill", Resource = "@xml/autofillservice")]
[Register("com.x8bit.bitwarden.Autofill.AutofillService")] [Register("com.x8bit.bitwarden.Autofill.AutofillService")]

View file

@ -9,7 +9,7 @@ using Android.Content.Res;
using Android.Nfc; using Android.Nfc;
using Android.OS; using Android.OS;
using Android.Runtime; using Android.Runtime;
using AndroidX.Core.Content; using Android.Views;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Models; using Bit.App.Models;
using Bit.App.Utilities; using Bit.App.Utilities;
@ -49,7 +49,7 @@ namespace Bit.Droid
{ {
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver)); var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent, _eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
PendingIntentFlags.UpdateCurrent); AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, false));
var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build(); var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build();
StrictMode.SetThreadPolicy(policy); StrictMode.SetThreadPolicy(policy);
@ -278,7 +278,7 @@ namespace Bit.Droid
{ {
var intent = new Intent(this, Class); var intent = new Intent(this, Class);
intent.AddFlags(ActivityFlags.SingleTop); intent.AddFlags(ActivityFlags.SingleTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0); var pendingIntent = PendingIntent.GetActivity(this, 0, intent, AndroidHelpers.AddPendingIntentMutabilityFlag(0, false));
// register for all NDEF tags starting with http och https // register for all NDEF tags starting with http och https
var ndef = new IntentFilter(NfcAdapter.ActionNdefDiscovered); var ndef = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
ndef.AddDataScheme("http"); ndef.AddDataScheme("http");

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2022.9.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2022.9.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="32" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/darkgray"/>
<foreground android:drawable="@drawable/logo_rounded"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/logo_rounded"/>
</adaptive-icon>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.11454546"
android:scaleY="0.11454546"
android:translateX="31.663637"
android:translateY="27.54">
<path
android:pathData="M376.4,12.2c-3.7,-3.7 -8.1,-5.6 -13.1,-5.6H26.7c-5.1,0 -9.4,1.9 -13.1,5.6C9.9,15.9 8,20.2 8,25.3v224.4c0,16.7 3.3,33.4 9.8,49.8c6.5,16.5 14.6,31.1 24.3,43.8c9.6,12.8 21.1,25.2 34.5,37.2c13.3,12.1 25.7,22.1 37,30.1c11.3,8 23.1,15.5 35.4,22.6c12.3,7.1 21,11.9 26.2,14.5c5.2,2.5 9.3,4.5 12.4,5.8c2.3,1.2 4.9,1.8 7.6,1.8c2.7,0 5.3,-0.6 7.6,-1.8c3.1,-1.4 7.3,-3.3 12.4,-5.8c5.2,-2.5 13.9,-7.4 26.2,-14.5c12.3,-7.1 24.1,-14.7 35.4,-22.6c11.3,-8 23.6,-18 37,-30.1c13.3,-12.1 24.8,-24.5 34.5,-37.2c9.6,-12.8 17.7,-27.4 24.2,-43.8c6.5,-16.5 9.8,-33.1 9.8,-49.8V25.3C382,20.2 380.1,15.9 376.4,12.2zM333,251.8C333,333 195,403 195,403V54.6h138C333,54.6 333,170.6 333,251.8z"
android:fillColor="#FFFFFF"/>
</group>
</vector>

View file

@ -4,6 +4,7 @@
<style name="LaunchTheme" parent="BaseTheme"> <style name="LaunchTheme" parent="BaseTheme">
<item name="android:windowBackground">@drawable/splash_screen_dark</item> <item name="android:windowBackground">@drawable/splash_screen_dark</item>
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_screen_round</item>
</style> </style>
<style name="BaseTheme" parent="Theme.AppCompat"> <style name="BaseTheme" parent="Theme.AppCompat">

View file

@ -4,6 +4,8 @@
<style name="LaunchTheme" parent="BaseTheme"> <style name="LaunchTheme" parent="BaseTheme">
<item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/ic_launcher_background</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_screen_round</item>
</style> </style>
<style name="BaseTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="BaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">

View file

@ -5,6 +5,7 @@ using Android.Content;
using Android.OS; using Android.OS;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Droid.Receivers; using Bit.Droid.Receivers;
using Bit.Droid.Utilities;
using Plugin.CurrentActivity; using Plugin.CurrentActivity;
using Xamarin.Essentials; using Xamarin.Essentials;
@ -23,7 +24,7 @@ namespace Bit.Droid.Services
PendingIntent.GetBroadcast(CrossCurrentActivity.Current.Activity, PendingIntent.GetBroadcast(CrossCurrentActivity.Current.Activity,
0, 0,
new Intent(CrossCurrentActivity.Current.Activity, typeof(ClearClipboardAlarmReceiver)), new Intent(CrossCurrentActivity.Current.Activity, typeof(ClearClipboardAlarmReceiver)),
PendingIntentFlags.UpdateCurrent)); AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, false)));
} }
public async Task CopyTextAsync(string text, int expiresInMs = -1, bool isSensitive = true) public async Task CopyTextAsync(string text, int expiresInMs = -1, bool isSensitive = true)

View file

@ -12,7 +12,7 @@ using Java.Lang;
namespace Bit.Droid.Tile namespace Bit.Droid.Tile
{ {
[Service(Permission = Manifest.Permission.BindQuickSettingsTile, Label = "@string/AutoFillTile", [Service(Permission = Manifest.Permission.BindQuickSettingsTile, Label = "@string/AutoFillTile",
Icon = "@drawable/shield")] Icon = "@drawable/shield", Exported = true)]
[IntentFilter(new string[] { ActionQsTile })] [IntentFilter(new string[] { ActionQsTile })]
[Register("com.x8bit.bitwarden.AutofillTileService")] [Register("com.x8bit.bitwarden.AutofillTileService")]
public class AutofillTileService : TileService public class AutofillTileService : TileService

View file

@ -14,7 +14,7 @@ using Java.Lang;
namespace Bit.Droid.Tile namespace Bit.Droid.Tile
{ {
[Service(Permission = Android.Manifest.Permission.BindQuickSettingsTile, Label = "@string/PasswordGenerator", [Service(Permission = Android.Manifest.Permission.BindQuickSettingsTile, Exported = true, Label = "@string/PasswordGenerator",
Icon = "@drawable/generate")] Icon = "@drawable/generate")]
[IntentFilter(new string[] { ActionQsTile })] [IntentFilter(new string[] { ActionQsTile })]
[Register("com.x8bit.bitwarden.GeneratorTileService")] [Register("com.x8bit.bitwarden.GeneratorTileService")]

View file

@ -15,7 +15,8 @@ using Java.Lang;
namespace Bit.Droid.Tile namespace Bit.Droid.Tile
{ {
[Service(Permission = Android.Manifest.Permission.BindQuickSettingsTile, Label = "@string/MyVault", [Service(Permission = Android.Manifest.Permission.BindQuickSettingsTile, Label = "@string/MyVault",
Icon = "@drawable/shield")] Icon = "@drawable/shield",
Exported = true)]
[IntentFilter(new string[] { ActionQsTile })] [IntentFilter(new string[] { ActionQsTile })]
[Register("com.x8bit.bitwarden.MyVaultTileService")] [Register("com.x8bit.bitwarden.MyVaultTileService")]
public class MyVaultTileService : TileService public class MyVaultTileService : TileService

View file

@ -1,6 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Android.App;
using Android.Content; using Android.Content;
using Android.OS;
using Android.Provider; using Android.Provider;
using Bit.App.Utilities; using Bit.App.Utilities;
@ -47,5 +49,22 @@ namespace Bit.Droid.Utilities
await AppHelpers.SetPreconfiguredSettingsAsync(dict); await AppHelpers.SetPreconfiguredSettingsAsync(dict);
} }
} }
public static PendingIntentFlags AddPendingIntentMutabilityFlag(PendingIntentFlags pendingIntentFlags, bool isMutable)
{
//Mutable flag was added on API level 31
if (isMutable && Build.VERSION.SdkInt >= BuildVersionCodes.S)
{
return pendingIntentFlags | PendingIntentFlags.Mutable;
}
//Immutable flag was added on API level 23
if (!isMutable && Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
return pendingIntentFlags | PendingIntentFlags.Immutable;
}
return pendingIntentFlags;
}
} }
} }

View file

@ -7,7 +7,8 @@ namespace Bit.Droid
{ {
[Activity( [Activity(
NoHistory = true, NoHistory = true,
LaunchMode = LaunchMode.SingleTop)] LaunchMode = LaunchMode.SingleTop,
Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView }, [IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable }, Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "bitwarden")] DataScheme = "bitwarden")]