Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

System.Obsolete attribute used instead of ObsoletedOSPlatform attribute #7558

Closed
tipa opened this issue Nov 16, 2022 · 8 comments
Closed

System.Obsolete attribute used instead of ObsoletedOSPlatform attribute #7558

tipa opened this issue Nov 16, 2022 · 8 comments
Assignees
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll).
Milestone

Comments

@tipa
Copy link

tipa commented Nov 16, 2022

Android application type

Android for .NET (net6.0-android, etc.)

Affected platform version

VS 2022 17.4.1, .NET 7

Description

I am using this property to get the installed app version:

public static string VersionString => (OperatingSystem.IsAndroidVersionAtLeast(33) ?
   Application.Context.PackageManager.GetPackageInfo(PackageName, PackageManager.PackageInfoFlags.Of(0)) :
   Application.Context.PackageManager.GetPackageInfo(PackageName, 0)).VersionName;

The old (now deprecated) GetPackageInfo method still emits this warning, even though OperatingSystem.IsAndroidVersionAtLeast is used:
Warning CS0618 'PackageManager.GetPackageInfo(string, PackageInfoFlags)' is obsolete: 'deprecated'

This is because of this attribute:
[System.Obsolete("deprecated")]

I think this attribute should be used instead:
[ObsoletedOSPlatform("android30.0")]

I know this is rather nitpicking, but there might be other usages of the old Obsolete attribute that could be replaced with the ObsoletedOSPlatform attribute. In the PackageManager class alone there are also these methods currently annotated with the old attribute:
https://developer.android.com/reference/android/content/pm/PackageManager#addPreferredActivity(android.content.IntentFilter,%20int,%20android.content.ComponentName[],%20android.content.ComponentName)
https://developer.android.com/reference/android/content/pm/PackageManager#getPackageGids(java.lang.String,%20int)
https://developer.android.com/reference/android/content/pm/PackageManager#removePackageFromPreferred(java.lang.String)
https://developer.android.com/reference/android/content/pm/PackageManager#addPackageToPreferred(java.lang.String)

Steps to Reproduce

  1. Create new .NET 6 project
  2. Add property as shown above
  3. Build app / check warnings window

Did you find any workaround?

No response

Relevant log output

No response

@tipa tipa added Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). needs-triage Issues that need to be assigned. labels Nov 16, 2022
@jpobst
Copy link
Contributor

jpobst commented Nov 16, 2022

[ObsoletedOSPlatform] was added in .NET 7, so if using net7.0-android this should be working. 😁

Implemented in #7234

@jpobst jpobst removed the needs-triage Issues that need to be assigned. label Nov 16, 2022
@tipa
Copy link
Author

tipa commented Nov 16, 2022

I am using net7.0-android33.0 but still see the warning.
As I mentioned, some methods are annotated with ObsoletedOSPlatform while others aren't (they are annotated with System.Obsolete).
I basically right-click on the method (GetPackageInfo) in VS22 and select "Go to Definition". It shows me this:
image

When I do the same for other methods (GetInstallerPackageName), I see this:
image

The file appears to be this:
image

@jpobst
Copy link
Contributor

jpobst commented Nov 16, 2022

Some of them were deprecated before our minimum API level (21), so they are just marked with the regular [Obsolete] since they are deprecated in all of our versions:

  • removePackageFromPreferred (String packageName) - deprecated in API-15
  • addPackageToPreferred (String packageName) - deprecated in API-15
  • addPreferredActivity (IntentFilter filter, int match, ComponentName[] set, ComponentName activity) deprecated in API-15

The others were obsoleted in API-33, so they should have the new attribute. Maybe there is something messed up because we have converted the int flags to enumerations. I will investigate.

@jpobst jpobst added this to the .NET 8 milestone Nov 16, 2022
@jahmai-ca
Copy link

This causes a compile error in our Xamarin.Forms apps on Azure DevOps windows-2022 images.

Error CS0618: 'PackageManager.GetPackageInfo(string, PackageInfoFlags)' is obsolete: 'deprecated'

This is weird since that signature should be the one that isn't deprecated:

https://developer.android.com/reference/android/content/pm/PackageManager#getPackageInfo(java.lang.String,%20android.content.pm.PackageManager.PackageInfoFlags)

The deprecated one is the int flags overload:

https://developer.android.com/reference/android/content/pm/PackageManager#getPackageInfo(java.lang.String,%20int)

But there appears to be no overload for (int flags) in the Xamarin.Android references.

So this is surely something that needs to be addressed as early as Xamarin.Android, let along NET6/7/8.

@jpobst
Copy link
Contributor

jpobst commented Nov 17, 2022

But there appears to be no overload for (int flags) in the Xamarin.Android references.

This appears to be a case of us making an unfortunate name choice a long time ago.

The original methods from Google are:

  • public abstract PackageInfo GetPackageInfo(VersionedPackage versionedPackage, int flags)
  • public abstract PackageInfo GetPackageInfo(string packageName, int flags)

We want our APIs to be a little easier to use, so we converted the int flags parameter to an enum called PackageInfoFlags, so they now look like this:

  • public abstract PackageInfo GetPackageInfo(VersionedPackage versionedPackage, [GeneratedEnum] PackageInfoFlags flags)
  • public abstract PackageInfo GetPackageInfo(string packageName, [GeneratedEnum] PackageInfoFlags flags)

In API-33, it looks like Google has done the same thing we did and introduced new overloads that take an "enum-like" Java type:

  • public virtual PackageInfo GetPackageInfo(VersionedPackage versionedPackage, PackageManager.PackageInfoFlags flags)
  • public virtual PackageInfo GetPackageInfo(string packageName, PackageManager.PackageInfoFlags flags)

Note that instead of our enum PackageInfoFlags these use a Java class PackageManager.PackageInfoFlags which has the same name as our enum but is a different type.

Thus you have to look closer to see that methods that take the enum PackageInfoFlags (the int flags Java methods) are the ones that are deprecated, and the new methods that take the Java type PackageManager.PackageInfoFlags are not deprecated.

This causes a compile error in our Xamarin.Forms apps on Azure DevOps windows-2022 images.

[Obsolete] does not produce an error, it produces a warning. You likely have some form of <TreatWarningsAsErrors> or <WarningsAsErrors> in your project file. You will need to suppress the warning using the regular C# mechanisms so your project does not treat it as an error.

@jahmai-ca
Copy link

[Obsolete] does not produce an error, it produces a warning. You likely have some form of <TreatWarningsAsErrors> or <WarningsAsErrors> in your project file. You will need to suppress the warning using the regular C# mechanisms so your project does not treat it as an error.

We don't. We actually use [Obsolete] ourselves, which generates warning CS0618 without any errors. This specific one gets converted to Error CS0618: 'PackageManager.GetPackageInfo(string, PackageInfoFlags)' is obsolete: 'deprecated' and I don't know why.

We're going to suppress it in code with #pragma, but ultimately we want to be able to call the appropriate version of GetPackageInfo since we target API 33 but support down to 23, and don't want to have to upgrade to NET8 to do that...

@jahmai-ca
Copy link

This may also apply to PackageManager.QueryIntentActivities with a similar issue of enum/int flags.

@ghost ghost locked as resolved and limited conversation to collaborators Feb 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll).
Projects
None yet
Development

No branches or pull requests

3 participants