-
Notifications
You must be signed in to change notification settings - Fork 278
[Security.PrivacyPrivilegeManager] CheckPermissionsAsync(), RequestPermissionsAsync() #7732
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
base: API14
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /* | ||
| * Copyright (c) 2026 Samsung Electronics Co., Ltd All Rights Reserved | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the License); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an AS IS BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
|
|
||
| namespace Tizen.Security | ||
| { | ||
| /// <summary> | ||
| /// Exception thrown when one or more required permissions are denied. | ||
| /// </summary> | ||
| /// <since_tizen> 14 </since_tizen> | ||
| /// <example> | ||
| /// <code> | ||
| /// <![CDATA[ | ||
| /// try | ||
| /// { | ||
| /// await PrivacyPrivilegeManager.RequestPermissionsAsync(required: privileges); | ||
| /// } | ||
| /// catch (PermissionDeniedException ex) | ||
| /// { | ||
| /// foreach (var privilege in ex.DeniedPrivileges) | ||
| /// { | ||
| /// var status = ex.GetStatus(privilege); | ||
| /// var name = Tizen.Security.Privilege.GetDisplayName("12", privilege); | ||
| /// Console.WriteLine($"{name}: {status}"); | ||
| /// } | ||
| /// } | ||
| /// ]]> | ||
| /// </code> | ||
| /// </example> | ||
| public class PermissionDeniedException : Exception | ||
| { | ||
| private readonly IDictionary<string, PermissionStatus> _map; | ||
|
|
||
| /// <summary> | ||
| /// Gets the list of denied privilege names. | ||
| /// </summary> | ||
| /// <since_tizen> 14 </since_tizen> | ||
| public IEnumerable<string> DeniedPrivileges => _map.Keys; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the PermissionDeniedException class with denied privileges and their statuses. | ||
| /// </summary> | ||
| /// <param name="denied">A dictionary mapping denied privilege names to their statuses.</param> | ||
| /// <since_tizen> 14 </since_tizen> | ||
| public PermissionDeniedException(IDictionary<string, PermissionStatus> denied) | ||
| : base("Required permissions denied: " + string.Join(", ", denied.Keys)) | ||
| { | ||
| _map = new Dictionary<string, PermissionStatus>(denied); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the permission status for a specific denied privilege. | ||
| /// </summary> | ||
| /// <param name="privilege">The privilege name.</param> | ||
| /// <returns>The permission status of the denied privilege.</returns> | ||
| /// <exception cref="ArgumentException">Thrown when the privilege is not found in the denied list.</exception> | ||
| /// <since_tizen> 14 </since_tizen> | ||
| public PermissionStatus GetStatus(string privilege) | ||
| { | ||
| if (!_map.TryGetValue(privilege, out var status)) | ||
| { | ||
| throw new ArgumentException($"Privilege '{privilege}' is not in the denied list.", nameof(privilege)); | ||
| } | ||
| return status; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||
| /* | ||||||
| * Copyright (c) 2026 Samsung Electronics Co., Ltd All Rights Reserved | ||||||
| * | ||||||
| * Licensed under the Apache License, Version 2.0 (the License); | ||||||
| * you may not use this file except in compliance with the License. | ||||||
| * You may obtain a copy of the License at | ||||||
| * | ||||||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||||||
| * | ||||||
| * Unless required by applicable law or agreed to in writing, software | ||||||
| * distributed under the License is distributed on an AS IS BASIS, | ||||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
| * See the License for the specific language governing permissions and | ||||||
| * limitations under the License. | ||||||
| */ | ||||||
|
|
||||||
| using System; | ||||||
| using System.Collections.Generic; | ||||||
| using System.Linq; | ||||||
|
|
||||||
| namespace Tizen.Security | ||||||
| { | ||||||
| /// <summary> | ||||||
| /// Represents the result of permission checks, implementing IDictionary<string, PermissionState>. | ||||||
| /// Provides methods to check if privileges are granted. | ||||||
| /// </summary> | ||||||
| /// <since_tizen>14</since_tizen> | ||||||
| /// <example> | ||||||
| /// <code><![CDATA[ | ||||||
| /// PermissionResult permissions = await PrivacyPrivilegeManager.CheckPermissionsAsync(privileges); | ||||||
| /// | ||||||
| /// // Check if a specific privilege is granted (returns false for unknown privileges) | ||||||
| /// bool isGranted = permissions.IsGranted("http://tizen.org/privilege/account.read"); | ||||||
| /// | ||||||
| /// // Check if all privileges are granted | ||||||
| /// bool allGranted = permissions.AllGranted(); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [AI Review]
Suggested change
|
||||||
| /// ]]></code> | ||||||
| /// </example> | ||||||
| public class PermissionResult : Dictionary<string, PermissionStatus> | ||||||
| { | ||||||
| /// <summary> | ||||||
| /// Checks if a specific privilege is granted. | ||||||
| /// Returns false for unknown privileges without throwing an exception. | ||||||
| /// </summary> | ||||||
| /// <param name="privilege">The privilege to check.</param> | ||||||
| /// <returns>True if the privilege is granted; otherwise, false.</returns> | ||||||
| /// <since_tizen>14</since_tizen> | ||||||
| public bool IsGranted(string privilege) => | ||||||
| TryGetValue(privilege, out var status) && status.IsGranted(); | ||||||
|
|
||||||
| /// <summary> | ||||||
| /// Checks if all privileges in this result are granted. | ||||||
| /// </summary> | ||||||
| /// <returns>True if all privileges are granted; otherwise, false.</returns> | ||||||
| /// <since_tizen>14</since_tizen> | ||||||
| public bool AreAllGranted() => Values.All(status => status.IsGranted()); | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,102 @@ | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * Copyright (c) 2026 Samsung Electronics Co., Ltd All Rights Reserved | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * Licensed under the Apache License, Version 2.0 (the License); | ||||||||||||||||||||||
| * you may not use this file except in compliance with the License. | ||||||||||||||||||||||
| * You may obtain a copy of the License at | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * Unless required by applicable law or agreed to in writing, software | ||||||||||||||||||||||
| * distributed under the License is distributed on an AS IS BASIS, | ||||||||||||||||||||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||||||||||||
| * See the License for the specific language governing permissions and | ||||||||||||||||||||||
| * limitations under the License. | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| namespace Tizen.Security | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Enumeration for the status of a permission. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| /// <since_tizen> 14 </since_tizen> | ||||||||||||||||||||||
| public enum PermissionStatus | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is granted. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| Granted = 0, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is denied. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| Denied = 1, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The permission is denied until user grants it. Use RequestPermissionAsync() to ask the user for the permission. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| Ask = 2, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is granted for the current session only. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| GrantedSession = 3, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is denied for the current session only. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| DeniedSession = 4, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is granted only while the application is in foreground. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| GrantedInUse = 5, | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// The privilege is denied once - user did not allow the permission this time and chose to be asked again later. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| Deferred = 90, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Extension methods for PermissionState. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| /// <since_tizen> 14 </since_tizen> | ||||||||||||||||||||||
| public static class PermissionStateExtensions | ||||||||||||||||||||||
|
Comment on lines
+55
to
+59
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 [AI Review]
Suggested change
|
||||||||||||||||||||||
| { | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Checks if the permission state indicates that the privilege is granted. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| /// <param name="state">The permission state to check.</param> | ||||||||||||||||||||||
| /// <returns>True if the privilege is granted (Granted, GrantedSession, or GrantedInUse); otherwise, false.</returns> | ||||||||||||||||||||||
| /// <since_tizen> 14 </since_tizen> | ||||||||||||||||||||||
| public static bool IsGranted(this PermissionStatus state) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| return state == PermissionStatus.Granted || | ||||||||||||||||||||||
| state == PermissionStatus.GrantedSession || | ||||||||||||||||||||||
| state == PermissionStatus.GrantedInUse; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Internal helper class for converting between interop enums and PermissionStatus. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| internal static class PermissionStatusConverter | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Converts Interop.CheckResult to PermissionState. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| internal static PermissionStatus ToPermissionStatus(this Interop.PrivacyPrivilegeManager.CheckResult checkResult) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| // Values match directly for all cases. | ||||||||||||||||||||||
| return (PermissionStatus)checkResult; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||
| /// Converts RequestResult to PermissionState. | ||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||
| internal static PermissionStatus ToPermissionStatus(this RequestResult requestResult) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| // Value DenyOnce maps to Deferred (90). Others match directly. | ||||||||||||||||||||||
| if (requestResult == RequestResult.DenyOnce) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| return PermissionStatus.Deferred; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return (PermissionStatus)requestResult; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 [AI Review]
🟡 Suggestion:
deniedis dereferenced in the base-constructor call, so a null argument surfaces asNullReferenceException; throwArgumentNullExceptionexplicitly for the new public API.