Skip to content

[Security.PrivacyPrivilegeManager] CheckPermissionsAsync(), RequestPermissionsAsync()#7732

Open
wiertel wants to merge 1 commit into
Samsung:API14from
wiertel:new-ppm3
Open

[Security.PrivacyPrivilegeManager] CheckPermissionsAsync(), RequestPermissionsAsync()#7732
wiertel wants to merge 1 commit into
Samsung:API14from
wiertel:new-ppm3

Conversation

@wiertel

@wiertel wiertel commented Jul 3, 2026

Copy link
Copy Markdown
Member

Description of Change

A replacement for deprecated privilege requesting API.

API Changes

  • ACR: TCSACR-657
    public static class Tizen.Security.PrivacyPrivilegeManager
    {
        static Task<PermissionResult> CheckPermissionsAsync(IEnumerable<string> privileges)
        static Task<PermissionResult> RequestPermissionsAsync(IEnumerable<string> required = null, IEnumerable<string> optional = null)
        static Task<IEnumerable<string>> LoadPrivilegesFromManifestAsync()
    }

@wiertel wiertel requested a review from terry2000s as a code owner July 3, 2026 10:27
@github-actions github-actions Bot added the API14 Platform : Tizen 11.0 / TFM: net8.0-tizen11.0 label Jul 3, 2026
@gemini-code-assist

Copy link
Copy Markdown

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@TizenAPI-Bot

Copy link
Copy Markdown
Collaborator

Public API Changed

Please follow the ACR process for the changed API below.

Added: 21, Removed: 0, Changed: 1

Added

+ /// <since_tizen>14</since_tizen
+ Tizen.Security.PermissionDeniedException

+ /// <since_tizen>14</since_tizen
+ System.Collections.Generic.IEnumerable`1<System.String> Tizen.Security.PermissionDeniedException::DeniedPrivileges()

+ /// <since_tizen>14</since_tizen
+ System.Void Tizen.Security.PermissionDeniedException::.ctor(System.Collections.Generic.IDictionary`2<System.String,Tizen.Security.PermissionStatus>)

+ /// <since_tizen>14</since_tizen
+ Tizen.Security.PermissionStatus Tizen.Security.PermissionDeniedException::GetStatus(System.String)

+ /// <since_tizen>14</since_tizen
+ Tizen.Security.PermissionResult

+ /// <since_tizen>14</since_tizen
+ System.Boolean Tizen.Security.PermissionResult::AreAllGranted()

+ /// <since_tizen>14</since_tizen
+ System.Boolean Tizen.Security.PermissionResult::IsGranted(System.String)

+ /// <since_tizen>none</since_tizen
+ System.Void Tizen.Security.PermissionResult::.ctor()

+ /// <since_tizen>14</since_tizen
+ Tizen.Security.PermissionStateExtensions

+ /// <since_tizen>14</since_tizen
+ static System.Boolean Tizen.Security.PermissionStateExtensions::IsGranted(Tizen.Security.PermissionStatus)

+ /// <since_tizen>14</since_tizen
+ Tizen.Security.PermissionStatus

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::Ask

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::Deferred

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::Denied

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::DeniedSession

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::Granted

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::GrantedInUse

+ /// <since_tizen>none</since_tizen
+ static Tizen.Security.PermissionStatus Tizen.Security.PermissionStatus::GrantedSession

+ /// <since_tizen>14</since_tizen
+ static System.Threading.Tasks.Task`1<System.Collections.Generic.IEnumerable`1<System.String>> Tizen.Security.PrivacyPrivilegeManager::LoadPrivilegesFromManifestAsync()

+ /// <since_tizen>14</since_tizen
+ static System.Threading.Tasks.Task`1<Tizen.Security.PermissionResult> Tizen.Security.PrivacyPrivilegeManager::CheckPermissionsAsync(System.Collections.Generic.IEnumerable`1<System.String>)

+ /// <since_tizen>14</since_tizen
+ static System.Threading.Tasks.Task`1<Tizen.Security.PermissionResult> Tizen.Security.PrivacyPrivilegeManager::RequestPermissionsAsync(System.Collections.Generic.IEnumerable`1<System.String>,System.Collections.Generic.IEnumerable`1<System.String>)

Changed

/// <since_tizen>4</since_tizen
- [Obsolete]
Tizen.Security.PrivacyPrivilegeManager

var requiredList = required != null ? new List<string>(required) : new List<string>();

// Remove from required any privileges that are also in optional (they become optional)
var actualRequired = requiredList.Where(p => !optionalSet.Contains(p)).ToList();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🔴 Critical: If required contains duplicate entries, a denied privilege appears twice in actualRequired and the ToDictionary call below throws ArgumentException (duplicate key) instead of the documented PermissionDeniedException.

Suggested change
var actualRequired = requiredList.Where(p => !optionalSet.Contains(p)).ToList();
var actualRequired = requiredList.Where(p => !optionalSet.Contains(p)).Distinct().ToList();

Comment on lines +433 to +435
/// List<string> manifestPrivileges = await PrivacyPrivilegeManager.LoadPrivilegesFromManifestAsync();
/// PermissionResult states = await PrivacyPrivilegeManager.CheckPermissionsAsync(manifestPrivileges);
/// bool allGranted = states.AllGranted();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🟡 Suggestion: This example doesn't compile — LoadPrivilegesFromManifestAsync returns Task<IEnumerable<string>> (not assignable to List<string>), and the method on PermissionResult is AreAllGranted(), not AllGranted(). The example on LoadPrivilegesFromManifestAsync has the same List<string> issue.

Suggested change
/// List<string> manifestPrivileges = await PrivacyPrivilegeManager.LoadPrivilegesFromManifestAsync();
/// PermissionResult states = await PrivacyPrivilegeManager.CheckPermissionsAsync(manifestPrivileges);
/// bool allGranted = states.AllGranted();
/// IEnumerable<string> manifestPrivileges = await PrivacyPrivilegeManager.LoadPrivilegesFromManifestAsync();
/// PermissionResult states = await PrivacyPrivilegeManager.CheckPermissionsAsync(manifestPrivileges);
/// bool allGranted = states.AreAllGranted();

/// bool isGranted = permissions.IsGranted("http://tizen.org/privilege/account.read");
///
/// // Check if all privileges are granted
/// bool allGranted = permissions.AllGranted();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🟡 Suggestion: AllGranted() doesn't exist on this class — the method declared below is AreAllGranted().

Suggested change
/// bool allGranted = permissions.AllGranted();
/// bool allGranted = permissions.AreAllGranted();

Comment on lines +55 to +59
/// <summary>
/// Extension methods for PermissionState.
/// </summary>
/// <since_tizen> 14 </since_tizen>
public static class PermissionStateExtensions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🟡 Suggestion: This new public class is named after a PermissionState type that doesn't exist — the enum it extends is PermissionStatus, and the name becomes permanent public API once approved.

Suggested change
/// <summary>
/// Extension methods for PermissionState.
/// </summary>
/// <since_tizen> 14 </since_tizen>
public static class PermissionStateExtensions
/// <summary>
/// Extension methods for PermissionStatus.
/// </summary>
/// <since_tizen> 14 </since_tizen>
public static class PermissionStatusExtensions

Comment on lines +61 to +62
public PermissionDeniedException(IDictionary<string, PermissionStatus> denied)
: base("Required permissions denied: " + string.Join(", ", denied.Keys))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🟡 Suggestion: denied is dereferenced in the base-constructor call, so a null argument surfaces as NullReferenceException; throw ArgumentNullException explicitly for the new public API.

Suggested change
public PermissionDeniedException(IDictionary<string, PermissionStatus> denied)
: base("Required permissions denied: " + string.Join(", ", denied.Keys))
public PermissionDeniedException(IDictionary<string, PermissionStatus> denied)
: base("Required permissions denied: " + string.Join(", ", (denied ?? throw new ArgumentNullException(nameof(denied))).Keys))

@JoonghyunCho

Copy link
Copy Markdown
Member

🤖 [AI Review]
Left 5 inline comments (🔴 1, 🟡 4). See inline for details.


Automated review by AI assistant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ACR Required API14 Platform : Tizen 11.0 / TFM: net8.0-tizen11.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants