Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
jfversluis authored May 2, 2022
2 parents dc8e32c + bc74dce commit e759d5e
Show file tree
Hide file tree
Showing 18 changed files with 401 additions and 197 deletions.
7 changes: 4 additions & 3 deletions .openpublishing.publish.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,17 @@
}
],
"notification_subscribers": [],
"sync_notification_subscribers": null,
"branches_to_filter": [],
"skip_source_output_uploading": false,
"need_preview_pull_request": false,
"contribution_branch_mappings": {},
"need_pr_comments": false,
"contribution_branch_mappings": {},
"dependent_repositories": [
{
"path_to_root": "_themes",
"url": "https://github.com/Microsoft/templates.docs.msft",
"branch": "master",
"branch": "main",
"branch_mapping": {}
}
],
Expand All @@ -84,4 +85,4 @@
"docs_build_engine": {
"name": "docfx_v3"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<queries>
<!-- Email -->
Expand Down
146 changes: 146 additions & 0 deletions DeviceTests/DeviceTests.Shared/VersionTracking_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Diagnostics;
using Xamarin.Essentials;
using Xunit;
using Xunit.Abstractions;

namespace DeviceTests
{
public class VersionTracking_Tests
{
/// <summary>
/// We cannot mock the app version but it should be constant value
/// </summary>
const string currentVersion = "1.0.1.0";
const string currentBuild = "1";

const string versionTrailKey = "VersionTracking.Trail";
const string versionsKey = "VersionTracking.Versions";
const string buildsKey = "VersionTracking.Builds";
static readonly string sharedName = Preferences.GetPrivatePreferencesSharedName("versiontracking");

readonly ITestOutputHelper output;

public VersionTracking_Tests(ITestOutputHelper output)
{
this.output = output;
}

[Fact]
public void First_Launch_Ever()
{
VersionTracking.Track();
Preferences.Clear(sharedName);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.True(VersionTracking.IsFirstLaunchEver);
Assert.True(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.True(VersionTracking.IsFirstLaunchForCurrentBuild);
}

[Fact]
public void First_Launch_For_Version()
{
VersionTracking.Track();
Preferences.Set(versionsKey, string.Join("|", new string[] { "0.8.0", "0.9.0", "1.0.0" }), sharedName);
Preferences.Set(buildsKey, string.Join("|", new string[] { currentBuild }), sharedName);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("1.0.0", VersionTracking.PreviousVersion);
Assert.Equal("0.8.0", VersionTracking.FirstInstalledVersion);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.True(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.False(VersionTracking.IsFirstLaunchForCurrentBuild);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("1.0.0", VersionTracking.PreviousVersion);
Assert.Equal("0.8.0", VersionTracking.FirstInstalledVersion);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.False(VersionTracking.IsFirstLaunchForCurrentBuild);
}

[Fact]
public void First_Launch_For_Build()
{
VersionTracking.Track();
Preferences.Set(versionsKey, string.Join("|", new string[] { currentVersion }), sharedName);
Preferences.Set(buildsKey, string.Join("|", new string[] { "10", "20" }), sharedName);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("20", VersionTracking.PreviousBuild);
Assert.Equal("10", VersionTracking.FirstInstalledBuild);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.True(VersionTracking.IsFirstLaunchForCurrentBuild);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("20", VersionTracking.PreviousBuild);
Assert.Equal("10", VersionTracking.FirstInstalledBuild);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.False(VersionTracking.IsFirstLaunchForCurrentBuild);
}

[Fact]
public void First_Launch_After_Downgrade()
{
VersionTracking.Track();
Preferences.Set(versionsKey, string.Join("|", new string[] { currentVersion, "1.0.2", "1.0.3" }), sharedName);

VersionTracking.InitVersionTracking();
output.WriteLine(VersionTracking.GetStatus());

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("1.0.3", VersionTracking.PreviousVersion);
Assert.Equal("1.0.2", VersionTracking.FirstInstalledVersion);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.True(VersionTracking.IsFirstLaunchForCurrentVersion);

VersionTracking.InitVersionTracking();

Assert.Equal(currentVersion, VersionTracking.CurrentVersion);
Assert.Equal("1.0.3", VersionTracking.PreviousVersion);
Assert.Equal("1.0.2", VersionTracking.FirstInstalledVersion);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
}

[Fact]
public void First_Launch_After_Build_Downgrade()
{
VersionTracking.Track();
Preferences.Set(versionsKey, string.Join("|", new string[] { currentVersion }), sharedName);
Preferences.Set(buildsKey, string.Join("|", new string[] { currentBuild, "10", "20" }), sharedName);

VersionTracking.InitVersionTracking();
output.WriteLine(VersionTracking.GetStatus());

Assert.Equal(currentBuild, VersionTracking.CurrentBuild);
Assert.Equal("20", VersionTracking.PreviousBuild);
Assert.Equal("10", VersionTracking.FirstInstalledBuild);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.True(VersionTracking.IsFirstLaunchForCurrentBuild);

VersionTracking.InitVersionTracking();

Assert.Equal(currentBuild, VersionTracking.CurrentBuild);
Assert.Equal("20", VersionTracking.PreviousBuild);
Assert.Equal("10", VersionTracking.FirstInstalledBuild);
Assert.False(VersionTracking.IsFirstLaunchEver);
Assert.False(VersionTracking.IsFirstLaunchForCurrentVersion);
Assert.False(VersionTracking.IsFirstLaunchForCurrentBuild);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
</ItemGroup>

</Project>
2 changes: 0 additions & 2 deletions Samples/Samples.Android/Properties/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<queries>
Expand Down
1 change: 1 addition & 0 deletions Xamarin.Essentials/AppActions/AppActions.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static AppAction ToAppAction(this ShortcutInfo shortcutInfo) =>
const string extraAppActionTitle = "EXTRA_XE_APP_ACTION_TITLE";
const string extraAppActionSubtitle = "EXTRA_XE_APP_ACTION_SUBTITLE";
const string extraAppActionIcon = "EXTRA_XE_APP_ACTION_ICON";
internal const string extraAppActionHandled = "EXTRA_XE_APP_ACTION_HANDLED";

internal static AppAction ToAppAction(this Intent intent)
=> new AppAction(
Expand Down
3 changes: 3 additions & 0 deletions Xamarin.Essentials/AppInfo/AppInfo.ios.tvos.watchos.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ static void PlatformShowSettingsUI()
{
MainThread.BeginInvokeOnMainThread(() =>
{
// Ignore obsolete for the time being. Will be updated in a future release.
#pragma warning disable CS0618 // Type or member is obsolete
var prefsApp = ScriptingBridge.SBApplication.FromBundleIdentifier("com.apple.systempreferences");
#pragma warning restore CS0618 // Type or member is obsolete
prefsApp.SendMode = ScriptingBridge.AESendMode.NoReply;
prefsApp.Activate();
});
Expand Down
4 changes: 0 additions & 4 deletions Xamarin.Essentials/FilePicker/FilePicker.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ public static partial class FilePicker
{
static async Task<IEnumerable<FileResult>> PlatformPickAsync(PickOptions options, bool allowMultiple = false)
{
// we only need the permission when accessing the file, but it's more natural
// to ask the user first, then show the picker.
await Permissions.EnsureGrantedAsync<Permissions.StorageRead>();

// Essentials supports >= API 19 where this action is available
var action = Intent.ActionOpenDocument;

Expand Down
4 changes: 2 additions & 2 deletions Xamarin.Essentials/Geolocation/Geolocation.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static partial class Geolocation

static async Task<Location> PlatformLastKnownLocationAsync()
{
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedOrRestrictedAsync<Permissions.LocationWhenInUse>();

var lm = Platform.LocationManager;
AndroidLocation bestLocation = null;
Expand All @@ -37,7 +37,7 @@ static async Task<Location> PlatformLastKnownLocationAsync()

static async Task<Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedOrRestrictedAsync<Permissions.LocationWhenInUse>();

var locationManager = Platform.LocationManager;

Expand Down
4 changes: 0 additions & 4 deletions Xamarin.Essentials/MediaPicker/MediaPicker.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ static Task<FileResult> PlatformPickVideoAsync(MediaPickerOptions options)

static async Task<FileResult> PlatformPickAsync(MediaPickerOptions options, bool photo)
{
// We only need the permission when accessing the file, but it's more natural
// to ask the user first, then show the picker.
await Permissions.EnsureGrantedAsync<Permissions.StorageRead>();

var intent = new Intent(Intent.ActionGetContent);
intent.SetType(photo ? FileSystem.MimeTypes.ImageAll : FileSystem.MimeTypes.VideoAll);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ void LocationAuthCallback(object sender, CLAuthorizationChangedEventArgs e)
}

del.AuthorizationStatusChanged -= LocationAuthCallback;
tcs.TrySetResult(GetLocationStatus(whenInUse));
locationManager?.Dispose();
locationManager = null;
tcs.TrySetResult(GetLocationStatus(whenInUse));
}
catch (Exception ex)
{
Expand Down
9 changes: 9 additions & 0 deletions Xamarin.Essentials/Permissions/Permissions.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ internal static async Task EnsureGrantedAsync<TPermission>()
throw new PermissionException($"{typeof(TPermission).Name} permission was not granted: {status}");
}

internal static async Task EnsureGrantedOrRestrictedAsync<TPermission>()
where TPermission : BasePermission, new()
{
var status = await RequestAsync<TPermission>();

if (status != PermissionStatus.Granted && status != PermissionStatus.Restricted)
throw new PermissionException($"{typeof(TPermission).Name} permission was not granted or restricted: {status}");
}

public abstract partial class BasePermission
{
[Preserve]
Expand Down
4 changes: 2 additions & 2 deletions Xamarin.Essentials/PhoneDialer/PhoneDialer.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public static partial class PhoneDialer

internal static bool IsSupported => UIApplication.SharedApplication.CanOpenUrl(CreateNsUrl(new string('0', 10)));

static async void PlatformOpen(string number)
static void PlatformOpen(string number)
{
ValidateOpen(number);

var nsUrl = CreateNsUrl(number);
await Launcher.PlatformOpenAsync(nsUrl);
Launcher.PlatformOpenAsync(nsUrl);
}

static NSUrl CreateNsUrl(string number) => new NSUrl(new Uri($"tel:{number}").AbsoluteUri);
Expand Down
5 changes: 4 additions & 1 deletion Xamarin.Essentials/Platform/Platform.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ public static void OnResume(Activity activity = null)

static void CheckAppActions(AndroidIntent intent)
{
if (intent?.Action == Intent.ActionAppAction)
if (intent?.Action == Intent.ActionAppAction && !intent.GetBooleanExtra(AppActions.extraAppActionHandled, false))
{
// prevent launch intent getting handled on activity resume
intent.PutExtra(AppActions.extraAppActionHandled, true);

var appAction = intent.ToAppAction();

if (!string.IsNullOrEmpty(appAction?.Id))
Expand Down
25 changes: 22 additions & 3 deletions Xamarin.Essentials/VersionTracking/VersionTracking.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,20 @@ public static class VersionTracking

static readonly string sharedName = Preferences.GetPrivatePreferencesSharedName("versiontracking");

static readonly Dictionary<string, List<string>> versionTrail;
static Dictionary<string, List<string>> versionTrail;

static VersionTracking()
{
InitVersionTracking();
}

/// <summary>
/// Initialize VersionTracking module, load data and track current version
/// </summary>
/// <remarks>
/// For internal use. Usually only called once in production code, but multiple times in unit tests
/// </remarks>
internal static void InitVersionTracking()
{
IsFirstLaunchEver = !Preferences.ContainsKey(versionsKey, sharedName) || !Preferences.ContainsKey(buildsKey, sharedName);
if (IsFirstLaunchEver)
Expand All @@ -35,15 +46,19 @@ static VersionTracking()
};
}

IsFirstLaunchForCurrentVersion = !versionTrail[versionsKey].Contains(CurrentVersion);
IsFirstLaunchForCurrentVersion = !versionTrail[versionsKey].Contains(CurrentVersion) || CurrentVersion != LastInstalledVersion;
if (IsFirstLaunchForCurrentVersion)
{
// Avoid duplicates and move current version to end of list if already present
versionTrail[versionsKey].RemoveAll(v => v == CurrentVersion);
versionTrail[versionsKey].Add(CurrentVersion);
}

IsFirstLaunchForCurrentBuild = !versionTrail[buildsKey].Contains(CurrentBuild);
IsFirstLaunchForCurrentBuild = !versionTrail[buildsKey].Contains(CurrentBuild) || CurrentBuild != LastInstalledBuild;
if (IsFirstLaunchForCurrentBuild)
{
// Avoid duplicates and move current build to end of list if already present
versionTrail[buildsKey].RemoveAll(b => b == CurrentBuild);
versionTrail[buildsKey].Add(CurrentBuild);
}

Expand Down Expand Up @@ -119,5 +134,9 @@ static string GetPrevious(string key)
var trail = versionTrail[key];
return (trail.Count >= 2) ? trail[trail.Count - 2] : null;
}

static string LastInstalledVersion => versionTrail[versionsKey].LastOrDefault();

static string LastInstalledBuild => versionTrail[buildsKey].LastOrDefault();
}
}
Loading

0 comments on commit e759d5e

Please sign in to comment.