Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bb92d452b | ||
|
|
2bfabfd838 | ||
|
|
9876cd547f | ||
|
|
4a8d261a82 | ||
|
|
c4823f1c37 | ||
|
|
6e9238329c | ||
|
|
c86cb962b9 | ||
|
|
56935a7210 | ||
|
|
cdc08e7e8a | ||
|
|
ca7794e6f2 | ||
|
|
3b5cae01e0 | ||
|
|
edb8dc58f7 | ||
|
|
3fc69f16d5 | ||
|
|
bd3fdcab26 | ||
|
|
201191e96d | ||
|
|
f545eafa77 | ||
|
|
5583c59e96 | ||
|
|
fbcf9c900c | ||
|
|
0801dea6e6 | ||
|
|
217514af66 | ||
|
|
e0191c573d | ||
|
|
ef4b53b337 | ||
|
|
acf2e4360f | ||
|
|
3227daddaf | ||
|
|
6e40b7f25b | ||
|
|
0dd87bbf78 | ||
|
|
dcfdc7d0ea | ||
|
|
e79097603f | ||
|
|
ffd8f9951f | ||
|
|
e27370cf32 | ||
|
|
405c4d1706 | ||
|
|
f7e081ba5d | ||
|
|
c71deb5051 | ||
|
|
edab722a76 | ||
|
|
2d280bd995 | ||
|
|
27e3c6553e | ||
|
|
6258a9cff9 | ||
|
|
a72f497581 | ||
|
|
311d3dd635 | ||
|
|
e80b3e4542 | ||
|
|
82c96555dc | ||
|
|
75b6e69d34 | ||
|
|
532b5f7c33 | ||
|
|
a841419c30 | ||
|
|
730a56380a | ||
|
|
97aa974443 | ||
|
|
b2eee8bde7 | ||
|
|
3cbe932248 | ||
|
|
26d5504a2f | ||
|
|
b163a0fe77 | ||
|
|
523e713d7a | ||
|
|
c7cf634a94 | ||
|
|
c8c14396f1 | ||
|
|
e72ccaf440 | ||
|
|
0b7e07ebab | ||
|
|
37e19d9a60 | ||
|
|
8f533bc576 | ||
|
|
096a9561ed | ||
|
|
c6ac9376fc | ||
|
|
fd55cf6996 | ||
|
|
0359705361 | ||
|
|
e31a7e5236 | ||
|
|
bb477908ef | ||
|
|
26175fbe1b | ||
|
|
67bc59f6b6 | ||
|
|
7b358b1bbb | ||
|
|
0387d5bdd1 | ||
|
|
2ddf624f7d | ||
|
|
74b34661a5 | ||
|
|
dc9765ef58 | ||
|
|
a50e66faf4 | ||
|
|
0388738e02 | ||
|
|
d33e38012a | ||
|
|
785d0b21c6 | ||
|
|
db12cd92b7 |
7
.github/workflows/build.yml
vendored
@@ -30,13 +30,8 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Set up NuGet
|
||||
uses: nuget/setup-nuget@v1
|
||||
with:
|
||||
nuget-version: 'latest'
|
||||
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.0
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
|
||||
@@ -1,4 +1,31 @@
|
||||
Code contributions are welcome! Please commit any pull requests against the `master` branch.
|
||||
# How to Contribute
|
||||
|
||||
Contributions of all kinds are welcome!
|
||||
|
||||
Please visit our [Community Forums](https://community.bitwarden.com/) for general community discussion and the development roadmap.
|
||||
|
||||
Here is how you can get involved:
|
||||
|
||||
* **Request a new feature:** Go to the [Feature Requests category](https://community.bitwarden.com/c/feature-requests/) of the Community Forums. Please search existing feature requests before making a new one
|
||||
|
||||
* **Write code for a new feature:** Make a new post in the [Github Contributions category](https://community.bitwarden.com/c/github-contributions/) of the Community Forums. Include a description of your proposed contribution, screeshots, and links to any relevant feature requests. This helps get feedback from the community and Bitwarden team members before you start writing code
|
||||
|
||||
* **Report a bug or submit a bugfix:** Use Github issues and pull requests
|
||||
|
||||
* **Write documentation:** Submit a pull request to the [Bitwarden help repository](https://github.com/bitwarden/help)
|
||||
|
||||
* **Help other users:** Go to the [User-to-User Support category](https://community.bitwarden.com/c/support/) on the Community Forums
|
||||
|
||||
* **Translate:** See the localization (i10n) section below
|
||||
|
||||
## Contributor Agreement
|
||||
|
||||
Please sign the [Contributor Agreement](https://cla-assistant.io/bitwarden/mobile) if you intend on contributing to any Github repository. Pull requests cannot be accepted and merged unless the author has signed the Contributor Agreement.
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
* commit any pull requests against the `master` branch
|
||||
* include a link to your Community Forums post
|
||||
|
||||
# Localization (l10n)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ files:
|
||||
pt-PT: pt-PT
|
||||
pt-BR: pt-BR
|
||||
en-GB: en-GB
|
||||
en-IN: en-IN
|
||||
- source: /store/apple/en/copy.resx
|
||||
translation: /store/apple/%two_letters_code%/copy.resx
|
||||
update_option: update_as_unapproved
|
||||
@@ -19,6 +20,7 @@ files:
|
||||
pt-PT: pt-PT
|
||||
pt-BR: pt-BR
|
||||
en-GB: en-GB
|
||||
en-IN: en-IN
|
||||
- source: /store/google/en/copy.resx
|
||||
translation: /store/google/%two_letters_code%/copy.resx
|
||||
update_option: update_as_unapproved
|
||||
@@ -29,3 +31,4 @@ files:
|
||||
pt-BR: pt-BR
|
||||
pt-PT: pt-PT
|
||||
en-GB: en-GB
|
||||
en-IN: en-IN
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.amazon.cloud9", "url"),
|
||||
new Browser("com.android.browser", "url"),
|
||||
new Browser("com.android.chrome", "url_bar"),
|
||||
// Rem. for "com.android.htmlviewer": doesn't have a URL bar, therefore not present here.
|
||||
new Browser("com.avast.android.secure.browser", "editor"),
|
||||
new Browser("com.avg.android.secure.browser", "editor"),
|
||||
new Browser("com.brave.browser", "url_bar"),
|
||||
@@ -50,13 +51,15 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.google.android.apps.chrome_dev", "url_bar"),
|
||||
new Browser("com.kiwibrowser.browser", "url_bar"),
|
||||
new Browser("com.microsoft.emmx", "url_bar"),
|
||||
new Browser("com.mmbox.browser", "search_box"),
|
||||
new Browser("com.mmbox.xbrowser", "search_box"),
|
||||
new Browser("com.naver.whale", "url_bar"),
|
||||
new Browser("com.opera.browser", "url_field"),
|
||||
new Browser("com.opera.browser.beta", "url_field"),
|
||||
new Browser("com.opera.mini.native", "url_field"),
|
||||
new Browser("com.opera.mini.native.beta", "url_field"),
|
||||
new Browser("com.opera.touch", "addressbarEdit"),
|
||||
new Browser("com.qwant.liberty", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("com.qwant.liberty", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v4)
|
||||
new Browser("com.sec.android.app.sbrowser", "location_bar_edit_text"),
|
||||
new Browser("com.sec.android.app.sbrowser.beta", "location_bar_edit_text"),
|
||||
new Browser("com.stoutner.privacybrowser.free", "url_edittext"),
|
||||
@@ -66,7 +69,13 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.vivaldi.browser.sopranos", "url_bar"),
|
||||
new Browser("com.yandex.browser", "bro_omnibar_address_title_text,bro_omnibox_collapsed_title",
|
||||
(s) => s.Split(new char[]{' ', ' '}).FirstOrDefault()), // 0 = Regular Space, 1 = No-break space (00A0)
|
||||
new Browser("mark.via.gp", "aw"),
|
||||
new Browser("com.z28j.feel", "g2"),
|
||||
new Browser("idm.internet.download.manager", "search"),
|
||||
new Browser("idm.internet.download.manager.adm.lite", "search"),
|
||||
new Browser("idm.internet.download.manager.plus", "search"),
|
||||
new Browser("io.github.forkmaintainers.iceraven", "mozac_browser_toolbar_url_view"),
|
||||
new Browser("mark.via", "o"),
|
||||
new Browser("mark.via.gp", "o"),
|
||||
new Browser("org.adblockplus.browser", "url_bar,url_bar_title"), // 2nd = Legacy (before v2)
|
||||
new Browser("org.adblockplus.browser.beta", "url_bar,url_bar_title"), // 2nd = Legacy (before v2)
|
||||
new Browser("org.bromite.bromite", "url_bar"),
|
||||
@@ -75,18 +84,19 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("org.codeaurora.swe.browser", "url_bar"),
|
||||
new Browser("org.gnu.icecat", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("org.mozilla.fenix", "mozac_browser_toolbar_url_view"),
|
||||
new Browser("org.mozilla.fenix.nightly", "mozac_browser_toolbar_url_view"),
|
||||
new Browser("org.mozilla.fennec_aurora", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
|
||||
new Browser("org.mozilla.fennec_fdroid", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("org.mozilla.firefox", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("org.mozilla.fenix.nightly", "mozac_browser_toolbar_url_view"), // [DEPRECATED ENTRY]
|
||||
new Browser("org.mozilla.fennec_aurora", "mozac_browser_toolbar_url_view,url_bar_title"), // [DEPRECATED ENTRY]
|
||||
new Browser("org.mozilla.fennec_fdroid", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
|
||||
new Browser("org.mozilla.firefox", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
|
||||
new Browser("org.mozilla.firefox_beta", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
|
||||
new Browser("org.mozilla.focus", "display_url"),
|
||||
new Browser("org.mozilla.klar", "display_url"),
|
||||
new Browser("org.mozilla.reference.browser", "mozac_browser_toolbar_url_view"),
|
||||
new Browser("org.mozilla.rocket", "display_url"),
|
||||
new Browser("org.torproject.torbrowser", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("org.torproject.torbrowser_alpha", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
|
||||
new Browser("org.ungoogled.chromium", "url_bar"),
|
||||
new Browser("org.torproject.torbrowser", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v10.0.3)
|
||||
new Browser("org.torproject.torbrowser_alpha", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v10.0a8)
|
||||
new Browser("org.ungoogled.chromium.extensions.stable", "url_bar"),
|
||||
new Browser("org.ungoogled.chromium.stable", "url_bar"),
|
||||
|
||||
// [Section B] Entries only present here
|
||||
//
|
||||
@@ -290,6 +300,7 @@ namespace Bit.Droid.Accessibility
|
||||
|
||||
// NTT DOCOMO ——— mainly used for "My docomo".
|
||||
new KnownUsernameField("cfg.smt.docomo.ne.jp", new (string, string)[] { ("contains:/auth/", "Di_Uid") }),
|
||||
new KnownUsernameField("id.smt.docomo.ne.jp", new (string, string)[] { ("contains:/cgi7/", "Di_Uid") }),
|
||||
|
||||
/**************************************************************************************
|
||||
* SECTION D ——— Miscellaneous
|
||||
@@ -379,12 +390,12 @@ namespace Bit.Droid.Accessibility
|
||||
var hasHttpProtocol = uri.StartsWith("http://") || uri.StartsWith("https://");
|
||||
if (!hasHttpProtocol && uri.Contains("."))
|
||||
{
|
||||
if (Uri.TryCreate("http://" + uri, UriKind.Absolute, out var uri2))
|
||||
if (Uri.TryCreate("https://" + uri, UriKind.Absolute, out var _))
|
||||
{
|
||||
return string.Concat("http://", uri);
|
||||
return string.Concat("https://", uri);
|
||||
}
|
||||
}
|
||||
if (Uri.TryCreate(uri, UriKind.Absolute, out var uri3))
|
||||
if (Uri.TryCreate(uri, UriKind.Absolute, out var _))
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
@@ -668,7 +679,7 @@ namespace Bit.Droid.Accessibility
|
||||
var icon = (ImageView)view.FindViewById(Resource.Id.icon);
|
||||
text1.Text = AppResources.AutofillWithBitwarden;
|
||||
text2.Text = AppResources.GoToMyVault;
|
||||
icon.SetImageResource(Resource.Drawable.icon);
|
||||
icon.SetImageResource(Resource.Drawable.shield);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,13 +255,13 @@ namespace Bit.Droid.Accessibility
|
||||
|
||||
if (!AccessibilityHelpers.OverlayPermitted())
|
||||
{
|
||||
if (!AccessibilityHelpers.IsAutofillTileAdded)
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
|
||||
{
|
||||
// The user has the option of only using the autofill tile and leaving the overlay permission
|
||||
// disabled, so only show this toast if they're using accessibility without overlay permission and
|
||||
// have _not_ added the autofill tile
|
||||
// disabled, so only show this toast if they're using accessibility without overlay permission on
|
||||
// a version of Android without quick-action tile support
|
||||
System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted");
|
||||
Toast.MakeText(this, AppResources.AccessibilityOverlayPermissionAlert, ToastLength.Long).Show();
|
||||
Toast.MakeText(this, AppResources.AccessibilityDrawOverPermissionAlert, ToastLength.Long).Show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v11.0</TargetFrameworkVersion>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
@@ -31,6 +31,8 @@
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
<AndroidSupportedAbis />
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
@@ -77,6 +79,7 @@
|
||||
<PackageReference Include="Portable.BouncyCastle">
|
||||
<Version>1.8.6.7</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.3-beta01" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.5.3.2</Version>
|
||||
</PackageReference>
|
||||
@@ -120,6 +123,7 @@
|
||||
<Compile Include="Receivers\LockAlarmReceiver.cs" />
|
||||
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
||||
<Compile Include="Renderers\CipherViewCellRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEditorRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomPickerRenderer.cs" />
|
||||
@@ -157,32 +161,28 @@
|
||||
<None Include="upload-keystore.jks.enc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable\card.xml" />
|
||||
<AndroidResource Include="Resources\drawable\cog.xml" />
|
||||
<AndroidResource Include="Resources\drawable\icon.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_foreground.xml" />
|
||||
<AndroidResource Include="Resources\drawable\id.xml" />
|
||||
<AndroidResource Include="Resources\drawable\lock.xml" />
|
||||
<AndroidResource Include="Resources\drawable\login.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_white.xml" />
|
||||
<AndroidResource Include="Resources\drawable\pencil.xml" />
|
||||
<AndroidResource Include="Resources\drawable\plus.xml" />
|
||||
<AndroidResource Include="Resources\drawable\refresh.xml" />
|
||||
<AndroidResource Include="Resources\drawable\search.xml" />
|
||||
<AndroidResource Include="Resources\drawable\shield.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
|
||||
@@ -197,6 +197,7 @@
|
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\values-night\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\colors.xml" />
|
||||
</ItemGroup>
|
||||
@@ -234,138 +235,15 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\autofill_listitem.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\login.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\login.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\login.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\login.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\login.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\logo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values-v21\styles.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\refresh.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\lock.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\shield.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\lock.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\refresh.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\refresh.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\lock.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\lock.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\refresh.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\lock.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\id.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\card.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\id.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\card.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\id.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\card.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\id.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\card.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\card.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\id.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\plus.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\plus.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\plus.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\plus.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\plus.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\slider_thumb.xml" />
|
||||
</ItemGroup>
|
||||
@@ -375,78 +253,12 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\logo_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\cog.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\cog.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\cog.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\cog.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\cog.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\dimens.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\shield.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\shield.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\shield.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\shield.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\refresh_sm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\refresh_sm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\refresh_sm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\refresh_sm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh_sm.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\CipherViewCell.axml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Content;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Widget;
|
||||
using System.Linq;
|
||||
using Android.App;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App.Slices;
|
||||
using Android.Graphics;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Widget.Inline;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Enums;
|
||||
using Android.Views.Autofill;
|
||||
using AndroidX.AutoFill.Inline;
|
||||
using AndroidX.AutoFill.Inline.V1;
|
||||
using Bit.Core.Abstractions;
|
||||
using SaveFlags = Android.Service.Autofill.SaveFlags;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
@@ -41,6 +51,7 @@ namespace Bit.Droid.Autofill
|
||||
"com.amazon.cloud9",
|
||||
"com.android.browser",
|
||||
"com.android.chrome",
|
||||
"com.android.htmlviewer",
|
||||
"com.avast.android.secure.browser",
|
||||
"com.avg.android.secure.browser",
|
||||
"com.brave.browser",
|
||||
@@ -56,6 +67,8 @@ namespace Bit.Droid.Autofill
|
||||
"com.google.android.apps.chrome_dev",
|
||||
"com.kiwibrowser.browser",
|
||||
"com.microsoft.emmx",
|
||||
"com.mmbox.browser",
|
||||
"com.mmbox.xbrowser",
|
||||
"com.naver.whale",
|
||||
"com.opera.browser",
|
||||
"com.opera.browser.beta",
|
||||
@@ -71,6 +84,12 @@ namespace Bit.Droid.Autofill
|
||||
"com.vivaldi.browser.snapshot",
|
||||
"com.vivaldi.browser.sopranos",
|
||||
"com.yandex.browser",
|
||||
"com.z28j.feel",
|
||||
"idm.internet.download.manager",
|
||||
"idm.internet.download.manager.adm.lite",
|
||||
"idm.internet.download.manager.plus",
|
||||
"io.github.forkmaintainers.iceraven",
|
||||
"mark.via",
|
||||
"mark.via.gp",
|
||||
"org.adblockplus.browser",
|
||||
"org.adblockplus.browser.beta",
|
||||
@@ -89,7 +108,8 @@ namespace Bit.Droid.Autofill
|
||||
"org.mozilla.rocket",
|
||||
"org.torproject.torbrowser",
|
||||
"org.torproject.torbrowser_alpha",
|
||||
"org.ungoogled.chromium",
|
||||
"org.ungoogled.chromium.extensions.stable",
|
||||
"org.ungoogled.chromium.stable",
|
||||
};
|
||||
|
||||
// The URLs are blacklisted from autofilling
|
||||
@@ -121,14 +141,49 @@ namespace Bit.Droid.Autofill
|
||||
return new List<FilledItem>();
|
||||
}
|
||||
|
||||
public static FillResponse BuildFillResponse(Parser parser, List<FilledItem> items, bool locked)
|
||||
public static FillResponse BuildFillResponse(Parser parser, List<FilledItem> items, bool locked,
|
||||
bool inlineAutofillEnabled, FillRequest fillRequest = null)
|
||||
{
|
||||
// Acquire inline presentation specs on Android 11+
|
||||
IList<InlinePresentationSpec> inlinePresentationSpecs = null;
|
||||
var inlinePresentationSpecsCount = 0;
|
||||
var inlineMaxSuggestedCount = 0;
|
||||
if (inlineAutofillEnabled && fillRequest != null && (int)Build.VERSION.SdkInt >= 30)
|
||||
{
|
||||
var inlineSuggestionsRequest = fillRequest.InlineSuggestionsRequest;
|
||||
inlineMaxSuggestedCount = inlineSuggestionsRequest?.MaxSuggestionCount ?? 0;
|
||||
inlinePresentationSpecs = inlineSuggestionsRequest?.InlinePresentationSpecs;
|
||||
inlinePresentationSpecsCount = inlinePresentationSpecs?.Count ?? 0;
|
||||
}
|
||||
|
||||
// Build response
|
||||
var responseBuilder = new FillResponse.Builder();
|
||||
if (items != null && items.Count > 0)
|
||||
{
|
||||
foreach (var item in items)
|
||||
var maxItems = items.Count;
|
||||
if (inlineMaxSuggestedCount > 0)
|
||||
{
|
||||
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, item);
|
||||
// -1 to adjust for 'open vault' option
|
||||
maxItems = Math.Min(maxItems, inlineMaxSuggestedCount - 1);
|
||||
}
|
||||
for (int i = 0; i < maxItems; i++)
|
||||
{
|
||||
InlinePresentationSpec inlinePresentationSpec = null;
|
||||
if (inlinePresentationSpecs != null)
|
||||
{
|
||||
if (i < inlinePresentationSpecsCount)
|
||||
{
|
||||
inlinePresentationSpec = inlinePresentationSpecs[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the max suggestion count is larger than the number of specs in the list, then
|
||||
// the last spec is used for the remainder of the suggestions
|
||||
inlinePresentationSpec = inlinePresentationSpecs[inlinePresentationSpecsCount - 1];
|
||||
}
|
||||
}
|
||||
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, items[i],
|
||||
inlinePresentationSpec);
|
||||
if (dataset != null)
|
||||
{
|
||||
responseBuilder.AddDataset(dataset);
|
||||
@@ -136,16 +191,34 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
}
|
||||
responseBuilder.AddDataset(BuildVaultDataset(parser.ApplicationContext, parser.FieldCollection,
|
||||
parser.Uri, locked));
|
||||
AddSaveInfo(parser, responseBuilder, parser.FieldCollection);
|
||||
parser.Uri, locked, inlinePresentationSpecs));
|
||||
AddSaveInfo(parser, fillRequest, responseBuilder, parser.FieldCollection);
|
||||
responseBuilder.SetIgnoredIds(parser.FieldCollection.IgnoreAutofillIds.ToArray());
|
||||
return responseBuilder.Build();
|
||||
}
|
||||
|
||||
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem)
|
||||
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem,
|
||||
InlinePresentationSpec inlinePresentationSpec = null)
|
||||
{
|
||||
var datasetBuilder = new Dataset.Builder(
|
||||
BuildListView(filledItem.Name, filledItem.Subtitle, filledItem.Icon, context));
|
||||
var overlayPresentation = BuildOverlayPresentation(
|
||||
filledItem.Name,
|
||||
filledItem.Subtitle,
|
||||
filledItem.Icon,
|
||||
context);
|
||||
|
||||
var inlinePresentation = BuildInlinePresentation(
|
||||
inlinePresentationSpec,
|
||||
filledItem.Name,
|
||||
filledItem.Subtitle,
|
||||
filledItem.Icon,
|
||||
null,
|
||||
context);
|
||||
|
||||
var datasetBuilder = new Dataset.Builder(overlayPresentation);
|
||||
if (inlinePresentation != null)
|
||||
{
|
||||
datasetBuilder.SetInlinePresentation(inlinePresentation);
|
||||
}
|
||||
if (filledItem.ApplyToFields(fields, datasetBuilder))
|
||||
{
|
||||
return datasetBuilder.Build();
|
||||
@@ -153,7 +226,8 @@ namespace Bit.Droid.Autofill
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Dataset BuildVaultDataset(Context context, FieldCollection fields, string uri, bool locked)
|
||||
public static Dataset BuildVaultDataset(Context context, FieldCollection fields, string uri, bool locked,
|
||||
IList<InlinePresentationSpec> inlinePresentationSpecs = null)
|
||||
{
|
||||
var intent = new Intent(context, typeof(MainActivity));
|
||||
intent.PutExtra("autofillFramework", true);
|
||||
@@ -177,14 +251,26 @@ namespace Bit.Droid.Autofill
|
||||
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
|
||||
PendingIntentFlags.CancelCurrent);
|
||||
|
||||
var view = BuildListView(
|
||||
var overlayPresentation = BuildOverlayPresentation(
|
||||
AppResources.AutofillWithBitwarden,
|
||||
locked ? AppResources.VaultIsLocked : AppResources.GoToMyVault,
|
||||
Resource.Drawable.icon,
|
||||
context);
|
||||
|
||||
var datasetBuilder = new Dataset.Builder(view);
|
||||
datasetBuilder.SetAuthentication(pendingIntent.IntentSender);
|
||||
var inlinePresentation = BuildInlinePresentation(
|
||||
inlinePresentationSpecs?.Last(),
|
||||
AppResources.Bitwarden,
|
||||
locked ? AppResources.VaultIsLocked : AppResources.MyVault,
|
||||
Resource.Drawable.icon,
|
||||
pendingIntent,
|
||||
context);
|
||||
|
||||
var datasetBuilder = new Dataset.Builder(overlayPresentation);
|
||||
if (inlinePresentation != null)
|
||||
{
|
||||
datasetBuilder.SetInlinePresentation(inlinePresentation);
|
||||
}
|
||||
datasetBuilder.SetAuthentication(pendingIntent?.IntentSender);
|
||||
|
||||
// Dataset must have a value set. We will reset this in the main activity when the real item is chosen.
|
||||
foreach (var autofillId in fields.AutofillIds)
|
||||
@@ -194,7 +280,7 @@ namespace Bit.Droid.Autofill
|
||||
return datasetBuilder.Build();
|
||||
}
|
||||
|
||||
public static RemoteViews BuildListView(string text, string subtext, int iconId, Context context)
|
||||
public static RemoteViews BuildOverlayPresentation(string text, string subtext, int iconId, Context context)
|
||||
{
|
||||
var packageName = context.PackageName;
|
||||
var view = new RemoteViews(packageName, Resource.Layout.autofill_listitem);
|
||||
@@ -204,11 +290,87 @@ namespace Bit.Droid.Autofill
|
||||
return view;
|
||||
}
|
||||
|
||||
public static void AddSaveInfo(Parser parser, FillResponse.Builder responseBuilder, FieldCollection fields)
|
||||
public static InlinePresentation BuildInlinePresentation(InlinePresentationSpec inlinePresentationSpec,
|
||||
string text, string subtext, int iconId, PendingIntent pendingIntent, Context context)
|
||||
{
|
||||
if ((int)Build.VERSION.SdkInt < 30 || inlinePresentationSpec == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (pendingIntent == null)
|
||||
{
|
||||
// InlinePresentation requires nonNull pending intent (even though we only utilize one for the
|
||||
// "my vault" presentation) so we're including an empty one here
|
||||
pendingIntent = PendingIntent.GetService(context, 0, new Intent(),
|
||||
PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent);
|
||||
}
|
||||
var slice = CreateInlinePresentationSlice(
|
||||
inlinePresentationSpec,
|
||||
text,
|
||||
subtext,
|
||||
iconId,
|
||||
"Autofill option",
|
||||
pendingIntent,
|
||||
context);
|
||||
if (slice != null)
|
||||
{
|
||||
return new InlinePresentation(slice, inlinePresentationSpec, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Slice CreateInlinePresentationSlice(
|
||||
InlinePresentationSpec inlinePresentationSpec,
|
||||
string text,
|
||||
string subtext,
|
||||
int iconId,
|
||||
string contentDescription,
|
||||
PendingIntent pendingIntent,
|
||||
Context context)
|
||||
{
|
||||
var imeStyle = inlinePresentationSpec.Style;
|
||||
if (!UiVersions.GetVersions(imeStyle).Contains(UiVersions.InlineUiVersion1))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var contentBuilder = InlineSuggestionUi.NewContentBuilder(pendingIntent)
|
||||
.SetContentDescription(contentDescription);
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
contentBuilder.SetTitle(text);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(subtext))
|
||||
{
|
||||
contentBuilder.SetSubtitle(subtext);
|
||||
}
|
||||
if (iconId > 0)
|
||||
{
|
||||
var icon = Icon.CreateWithResource(context, iconId);
|
||||
if (icon != null)
|
||||
{
|
||||
if (iconId == Resource.Drawable.icon)
|
||||
{
|
||||
// Don't tint our logo
|
||||
icon.SetTintBlendMode(BlendMode.Dst);
|
||||
}
|
||||
contentBuilder.SetStartIcon(icon);
|
||||
}
|
||||
}
|
||||
return contentBuilder.Build().JavaCast<InlineSuggestionUi.Content>()?.Slice;
|
||||
}
|
||||
|
||||
public static void AddSaveInfo(Parser parser, FillRequest fillRequest, FillResponse.Builder responseBuilder,
|
||||
FieldCollection fields)
|
||||
{
|
||||
// Docs state that password fields cannot be reliably saved in Compat mode since they will show as
|
||||
// masked values.
|
||||
var compatBrowser = CompatBrowsers.Contains(parser.PackageName);
|
||||
bool? compatRequest = null;
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q && fillRequest != null)
|
||||
{
|
||||
// Attempt to automatically establish compat request mode on Android 10+
|
||||
compatRequest = (fillRequest.Flags | FillRequest.FlagCompatibilityModeRequest) == fillRequest.Flags;
|
||||
}
|
||||
var compatBrowser = compatRequest ?? CompatBrowsers.Contains(parser.PackageName);
|
||||
if (compatBrowser && fields.SaveType == SaveDataType.Password)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Bit.Droid.Autofill
|
||||
private ICipherService _cipherService;
|
||||
private IVaultTimeoutService _vaultTimeoutService;
|
||||
private IStorageService _storageService;
|
||||
private IPolicyService _policyService;
|
||||
private IUserService _userService;
|
||||
|
||||
public async override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal,
|
||||
FillCallback callback)
|
||||
@@ -46,6 +48,8 @@ namespace Bit.Droid.Autofill
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var inlineAutofillEnabled = await _storageService.GetAsync<bool?>(Constants.InlineAutofillEnabledKey) ?? true;
|
||||
|
||||
if (_vaultTimeoutService == null)
|
||||
{
|
||||
@@ -64,7 +68,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
|
||||
// build response
|
||||
var response = AutofillHelpers.BuildFillResponse(parser, items, locked);
|
||||
var response = AutofillHelpers.BuildFillResponse(parser, items, locked, inlineAutofillEnabled, request);
|
||||
callback.OnSuccess(response);
|
||||
}
|
||||
|
||||
@@ -87,6 +91,26 @@ namespace Bit.Droid.Autofill
|
||||
return;
|
||||
}
|
||||
|
||||
_policyService ??= ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
|
||||
var personalOwnershipPolicies = await _policyService.GetAll(PolicyType.PersonalOwnership);
|
||||
if (personalOwnershipPolicies != null)
|
||||
{
|
||||
_userService ??= ServiceContainer.Resolve<IUserService>("userService");
|
||||
foreach (var policy in personalOwnershipPolicies)
|
||||
{
|
||||
if (policy.Enabled)
|
||||
{
|
||||
var org = await _userService.GetOrganizationAsync(policy.OrganizationId);
|
||||
if (org != null && org.Enabled && org.UsePolicies && !org.canManagePolicies
|
||||
&& org.Status == OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var parser = new Parser(structure, ApplicationContext);
|
||||
parser.Parse();
|
||||
|
||||
|
||||
@@ -221,4 +221,4 @@ namespace Bit.Droid.Autofill
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Bit.Droid
|
||||
[Activity(
|
||||
Label = "Bitwarden",
|
||||
Icon = "@mipmap/ic_launcher",
|
||||
Theme = "@style/LightTheme.Splash",
|
||||
Theme = "@style/LaunchTheme",
|
||||
MainLauncher = true,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
[Register("com.x8bit.bitwarden.MainActivity")]
|
||||
@@ -334,7 +334,11 @@ namespace Bit.Droid
|
||||
|
||||
private void UpdateTheme(string theme)
|
||||
{
|
||||
if (theme == "dark")
|
||||
if (theme == "light")
|
||||
{
|
||||
SetTheme(Resource.Style.LightTheme);
|
||||
}
|
||||
else if (theme == "dark")
|
||||
{
|
||||
SetTheme(Resource.Style.DarkTheme);
|
||||
}
|
||||
@@ -348,7 +352,14 @@ namespace Bit.Droid
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTheme(Resource.Style.LightTheme);
|
||||
if (_deviceActionService.UsingDarkTheme())
|
||||
{
|
||||
SetTheme(Resource.Style.DarkTheme);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTheme(Resource.Style.LightTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ namespace Bit.Droid
|
||||
{
|
||||
RegisterLocalServices();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Constants.ClearCiphersCacheKey,
|
||||
Constants.AndroidAllClearCipherCacheKeys);
|
||||
}
|
||||
#if !FDROID
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
|
||||
@@ -86,7 +87,6 @@ namespace Bit.Droid
|
||||
var preferencesStorage = new PreferencesStorageService(null);
|
||||
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
|
||||
var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db"));
|
||||
liteDbStorage.InitAsync();
|
||||
var localizeService = new LocalizeService();
|
||||
var broadcasterService = new BroadcasterService();
|
||||
var messagingService = new MobileBroadcasterMessagingService(broadcasterService);
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:versionCode="1"
|
||||
android:versionName="2.6.0"
|
||||
android:versionName="2.8.1"
|
||||
android:installLocation="internalOnly"
|
||||
package="com.x8bit.bitwarden">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<application
|
||||
android:label="Bitwarden"
|
||||
android:theme="@style/LightTheme.Splash"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:allowBackup="false"
|
||||
tools:replace="android:allowBackup"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Bit.Droid.Receivers
|
||||
public override void OnReceive(Context context, Intent intent)
|
||||
{
|
||||
var clipboardManager = context.GetSystemService(Context.ClipboardService) as ClipboardManager;
|
||||
clipboardManager.PrimaryClip = ClipData.NewPlainText("bitwarden", string.Empty);
|
||||
clipboardManager.PrimaryClip = ClipData.NewPlainText("bitwarden", " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +27,15 @@ namespace Bit.Droid.Renderers
|
||||
private static Android.Graphics.Color _textColor;
|
||||
private static Android.Graphics.Color _mutedColor;
|
||||
private static Android.Graphics.Color _disabledIconColor;
|
||||
private static bool _usingLightTheme;
|
||||
|
||||
private AndroidCipherCell _cell;
|
||||
|
||||
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView,
|
||||
ViewGroup parent, Context context)
|
||||
{
|
||||
// TODO expand beyond light/dark detection once we support custom theme switching without app restart
|
||||
var themeChanged = _usingLightTheme != ThemeManager.UsingLightTheme;
|
||||
if (_faTypeface == null)
|
||||
{
|
||||
_faTypeface = Typeface.CreateFromAsset(context.Assets, "FontAwesome.ttf");
|
||||
@@ -41,18 +44,19 @@ namespace Bit.Droid.Renderers
|
||||
{
|
||||
_miTypeface = Typeface.CreateFromAsset(context.Assets, "MaterialIcons_Regular.ttf");
|
||||
}
|
||||
if (_textColor == default(Android.Graphics.Color))
|
||||
if (_textColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_textColor = ThemeManager.GetResourceColor("TextColor").ToAndroid();
|
||||
}
|
||||
if (_mutedColor == default(Android.Graphics.Color))
|
||||
if (_mutedColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_mutedColor = ThemeManager.GetResourceColor("MutedColor").ToAndroid();
|
||||
}
|
||||
if (_disabledIconColor == default(Android.Graphics.Color))
|
||||
if (_disabledIconColor == default(Android.Graphics.Color) || themeChanged)
|
||||
{
|
||||
_disabledIconColor = ThemeManager.GetResourceColor("DisabledIconColor").ToAndroid();
|
||||
}
|
||||
_usingLightTheme = ThemeManager.UsingLightTheme;
|
||||
|
||||
var cipherCell = item as CipherViewCell;
|
||||
_cell = convertView as AndroidCipherCell;
|
||||
|
||||
60
src/Android/Renderers/CustomTabbedRenderer.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.Droid.Renderers;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
using Xamarin.Forms.Platform.Android.AppCompat;
|
||||
|
||||
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomTabbedRenderer : TabbedPageRenderer, BottomNavigationView.IOnNavigationItemReselectedListener
|
||||
{
|
||||
private TabbedPage _page;
|
||||
|
||||
public CustomTabbedRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
_page = e.NewElement;
|
||||
GetBottomNavigationView()?.SetOnNavigationItemReselectedListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page = e.OldElement;
|
||||
}
|
||||
}
|
||||
|
||||
private BottomNavigationView GetBottomNavigationView()
|
||||
{
|
||||
for (var i = 0; i < ViewGroup.ChildCount; i++)
|
||||
{
|
||||
var childView = ViewGroup.GetChildAt(i);
|
||||
if (childView is ViewGroup viewGroup)
|
||||
{
|
||||
for (var j = 0; j < viewGroup.ChildCount; j++)
|
||||
{
|
||||
var childRelativeLayoutView = viewGroup.GetChildAt(j);
|
||||
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
|
||||
{
|
||||
return bottomNavigationView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async void BottomNavigationView.IOnNavigationItemReselectedListener.OnNavigationItemReselected(IMenuItem item)
|
||||
{
|
||||
if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
|
||||
{
|
||||
await _page.CurrentPage.Navigation.PopToRootAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 180 B |
|
Before Width: | Height: | Size: 775 B |
|
Before Width: | Height: | Size: 487 B |
|
Before Width: | Height: | Size: 581 B |
|
Before Width: | Height: | Size: 904 B |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 943 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 635 B |
|
Before Width: | Height: | Size: 440 B |
15
src/Android/Resources/drawable-v23/splash_screen.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
TODO: When API 23 becomes our new minimum, replace 'splash_screen.xml' in 'drawable' with this version, and delete
|
||||
all versions of 'logo_legacy.png' and 'logo_white_legacy.png'. The bitmaps only exist due to a bug in API <23 where
|
||||
vector drawables used in layer-lists (our splash screen) stretch to fill the full height of the parent.
|
||||
-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="@color/lightgray"/>
|
||||
</item>
|
||||
<item
|
||||
android:drawable="@drawable/logo"
|
||||
android:tileMode="disabled"
|
||||
android:gravity="center"/>
|
||||
</layer-list>
|
||||
15
src/Android/Resources/drawable-v23/splash_screen_dark.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
TODO: When API 23 becomes our new minimum, replace 'splash_screen_dark.xml' in 'drawable' with this version, and delete
|
||||
all versions of 'logo_legacy.png' and 'logo_white_legacy.png'. The bitmaps only exist due to a bug in API <23 where
|
||||
vector drawables used in layer-lists (our splash screen) stretch to fill the full height of the parent.
|
||||
-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="@color/darkgray"/>
|
||||
</item>
|
||||
<item
|
||||
android:drawable="@drawable/logo_white"
|
||||
android:tileMode="disabled"
|
||||
android:gravity="center"/>
|
||||
</layer-list>
|
||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 941 B |
|
Before Width: | Height: | Size: 545 B |
|
Before Width: | Height: | Size: 695 B |
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
src/Android/Resources/drawable-xhdpi/logo_legacy.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/Android/Resources/drawable-xhdpi/logo_white_legacy.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 359 B |
|
Before Width: | Height: | Size: 133 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 817 B |
|
Before Width: | Height: | Size: 607 B |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 868 B |
|
Before Width: | Height: | Size: 835 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 571 B |
|
Before Width: | Height: | Size: 140 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 772 B |
|
Before Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 807 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 681 B |
|
Before Width: | Height: | Size: 150 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 997 B |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 229 B |
9
src/Android/Resources/drawable/card.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="2048"
|
||||
android:viewportHeight="2048">
|
||||
<path
|
||||
android:fillColor="#FF777777"
|
||||
android:pathData="M1824,256C1868,256 1905.67,271.67 1937,303C1968.33,334.33 1984,372 1984,416L1984,1632C1984,1676 1968.33,1713.67 1937,1745C1905.67,1776.33 1868,1792 1824,1792L224,1792C180,1792 142.33,1776.33 111,1745C79.67,1713.67 64,1676 64,1632L64,416C64,372 79.67,334.33 111,303C142.33,271.67 180,256 224,256L1824,256ZM224,384C215.33,384 207.83,387.17 201.5,393.5C195.17,399.83 192,407.33 192,416L192,640L1856,640L1856,416C1856,407.33 1852.83,399.83 1846.5,393.5C1840.17,387.17 1832.67,384 1824,384L224,384ZM1824,1664C1832.67,1664 1840.17,1660.83 1846.5,1654.5C1852.83,1648.17 1856,1640.67 1856,1632L1856,1024L192,1024L192,1632C192,1640.67 195.17,1648.17 201.5,1654.5C207.83,1660.83 215.33,1664 224,1664L1824,1664ZM320,1536L320,1408L576,1408L576,1536L320,1536ZM704,1536L704,1408L1088,1408L1088,1536L704,1536Z" />
|
||||
</vector>
|
||||
|
Before Width: | Height: | Size: 574 B |
9
src/Android/Resources/drawable/cog.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1792"
|
||||
android:viewportHeight="1792">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M1152,896q0,-106 -75,-181t-181,-75 -181,75 -75,181 75,181 181,75 181,-75 75,-181zM1664,787v222q0,12 -8,23t-20,13l-185,28q-19,54 -39,91 35,50 107,138 10,12 10,25t-9,23q-27,37 -99,108t-94,71q-12,0 -26,-9l-138,-108q-44,23 -91,38 -16,136 -29,186 -7,28 -36,28h-222q-14,0 -24.5,-8.5t-11.5,-21.5l-28,-184q-49,-16 -90,-37l-141,107q-10,9 -25,9 -14,0 -25,-11 -126,-114 -165,-168 -7,-10 -7,-23 0,-12 8,-23 15,-21 51,-66.5t54,-70.5q-27,-50 -41,-99l-183,-27q-13,-2 -21,-12.5t-8,-23.5v-222q0,-12 8,-23t19,-13l186,-28q14,-46 39,-92 -40,-57 -107,-138 -10,-12 -10,-24 0,-10 9,-23 26,-36 98.5,-107.5t94.5,-71.5q13,0 26,10l138,107q44,-23 91,-38 16,-136 29,-186 7,-28 36,-28h222q14,0 24.5,8.5t11.5,21.5l28,184q49,16 90,37l142,-107q9,-9 24,-9 13,0 25,10 129,119 165,170 7,8 7,22 0,12 -8,23 -15,21 -51,66.5t-54,70.5q26,50 41,98l183,28q13,2 21,12.5t8,23.5z" />
|
||||
</vector>
|
||||
|
Before Width: | Height: | Size: 342 B |
9
src/Android/Resources/drawable/id.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="2048"
|
||||
android:viewportHeight="2048">
|
||||
<path
|
||||
android:fillColor="#FF777777"
|
||||
android:pathData="M896,1340C896,1376.67 885.5,1407.83 864.5,1433.5C843.5,1459.17 818.33,1472 789,1472L363,1472C333.67,1472 308.5,1459.17 287.5,1433.5C266.5,1407.83 256,1376.67 256,1340C256,1304 258.5,1270.5 263.5,1239.5C268.5,1208.5 276.67,1178.5 288,1149.5C299.33,1120.5 316.33,1097.67 339,1081C361.67,1064.33 388.67,1056 420,1056C462.67,1098.67 514.67,1120 576,1120C637.33,1120 689.33,1098.67 732,1056C763.33,1056 790.33,1064.33 813,1081C835.67,1097.67 852.67,1120.5 864,1149.5C875.33,1178.5 883.5,1208.5 888.5,1239.5C893.5,1270.5 896,1304 896,1340ZM768,896C768,949.33 749.33,994.67 712,1032C674.67,1069.33 629.33,1088 576,1088C522.67,1088 477.33,1069.33 440,1032C402.67,994.67 384,949.33 384,896C384,842.67 402.67,797.33 440,760C477.33,722.67 522.67,704 576,704C629.33,704 674.67,722.67 712,760C749.33,797.33 768,842.67 768,896ZM1792,1312L1792,1376C1792,1385.33 1789,1393 1783,1399C1777,1405 1769.33,1408 1760,1408L1056,1408C1046.67,1408 1039,1405 1033,1399C1027,1393 1024,1385.33 1024,1376L1024,1312C1024,1302.67 1027,1295 1033,1289C1039,1283 1046.67,1280 1056,1280L1760,1280C1769.33,1280 1777,1283 1783,1289C1789,1295 1792,1302.67 1792,1312ZM1408,1056L1408,1120C1408,1129.33 1405,1137 1399,1143C1393,1149 1385.33,1152 1376,1152L1056,1152C1046.67,1152 1039,1149 1033,1143C1027,1137 1024,1129.33 1024,1120L1024,1056C1024,1046.67 1027,1039 1033,1033C1039,1027 1046.67,1024 1056,1024L1376,1024C1385.33,1024 1393,1027 1399,1033C1405,1039 1408,1046.67 1408,1056ZM1792,1056L1792,1120C1792,1129.33 1789,1137 1783,1143C1777,1149 1769.33,1152 1760,1152L1568,1152C1558.67,1152 1551,1149 1545,1143C1539,1137 1536,1129.33 1536,1120L1536,1056C1536,1046.67 1539,1039 1545,1033C1551,1027 1558.67,1024 1568,1024L1760,1024C1769.33,1024 1777,1027 1783,1033C1789,1039 1792,1046.67 1792,1056ZM1792,800L1792,864C1792,873.33 1789,881 1783,887C1777,893 1769.33,896 1760,896L1056,896C1046.67,896 1039,893 1033,887C1027,881 1024,873.33 1024,864L1024,800C1024,790.67 1027,783 1033,777C1039,771 1046.67,768 1056,768L1760,768C1769.33,768 1777,771 1783,777C1789,783 1792,790.67 1792,800ZM1920,1632L1920,512L128,512L128,1632C128,1640.67 131.17,1648.17 137.5,1654.5C143.83,1660.83 151.33,1664 160,1664L1888,1664C1896.67,1664 1904.17,1660.83 1910.5,1654.5C1916.83,1648.17 1920,1640.67 1920,1632ZM2048,416L2048,1632C2048,1676 2032.33,1713.67 2001,1745C1969.67,1776.33 1932,1792 1888,1792L160,1792C116,1792 78.33,1776.33 47,1745C15.67,1713.67 0,1676 0,1632L0,416C0,372 15.67,334.33 47,303C78.33,271.67 116,256 160,256L1888,256C1932,256 1969.67,271.67 2001,303C2032.33,334.33 2048,372 2048,416Z" />
|
||||
</vector>
|
||||
|
Before Width: | Height: | Size: 405 B |
9
src/Android/Resources/drawable/lock.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1792"
|
||||
android:viewportHeight="1792">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M640,768h512v-192q0,-106 -75,-181t-181,-75 -181,75 -75,181v192zM1472,864v576q0,40 -28,68t-68,28h-960q-40,0 -68,-28t-28,-68v-576q0,-40 28,-68t68,-28h32v-192q0,-184 132,-316t316,-132 316,132 132,316v192h32q40,0 68,28t28,68z" />
|
||||
</vector>
|
||||
|
Before Width: | Height: | Size: 657 B |