[TCSACR-88] Add guide for Tizen.Security.PrivacyPrivilegeManager 74/153974/6
authorPiotr Sawicki <p.sawicki2@partner.samsung.com>
Wed, 4 Oct 2017 11:35:17 +0000 (13:35 +0200)
committerEditor Lionbridge <TizenEditor.SEL@lionbridge.com>
Fri, 6 Oct 2017 05:45:34 +0000 (08:45 +0300)
PS6: Reviewed.

Change-Id: Ia602d976a1a7ff8a53aaf0682b88426be854cd3a

org.tizen.guides/html/dotnet/privacy-related-permissions.htm [new file with mode: 0755]

diff --git a/org.tizen.guides/html/dotnet/privacy-related-permissions.htm b/org.tizen.guides/html/dotnet/privacy-related-permissions.htm
new file mode 100755 (executable)
index 0000000..e961c94
--- /dev/null
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+    <head>
+        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+        <meta http-equiv="X-UA-Compatible" content="IE=9" />
+        <link rel="stylesheet" type="text/css" href="../css/styles.css" />
+        <link rel="stylesheet" type="text/css" href="../css/snippet.css" />
+        <script type="text/javascript" src="../scripts/snippet.js"></script>
+        <script type="text/javascript" src="../scripts/jquery.util.js" charset="utf-8"></script>
+        <script type="text/javascript" src="../scripts/common.js" charset="utf-8"></script>
+        <script type="text/javascript" src="../scripts/core.js" charset="utf-8"></script>
+        <script type="text/javascript" src="../scripts/search.js" charset="utf-8"></script>
+
+        <title>Privacy-related Permissions</title>
+    </head>
+
+    <body onload="prettyPrint()" style="overflow: auto;">
+
+        <div id="toc-navigation">
+            <div id="toc_border">
+                <div id="toc">
+                    <p class="toc-title">Dependencies</p>
+                    <ul class="toc">
+                        <li>Tizen 4.0 and Higher</li>
+                    </ul>
+
+                    <p class="toc-title">Content</p>
+                    <ul class="toc">
+                        <li><a href="#prerequisites">Prerequisites</a></li>
+                        <li><a href="#requesting">Requesting Permissions</a></li>
+                    </ul>
+
+                    <p class="toc-title">Related Info</p>
+                    <ul class="toc">
+                        <li><a href="https://developer.tizen.org/dev-guide/csapi/classTizen_1_1Security_1_1PrivacyPrivilegeManager.html">Tizen.Security.PrivacyPrivilegeManager Class</a></li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+
+        <div id="container">
+            <div id="contents">
+                <div class="content">
+                    <h1>Privacy-related Permissions</h1>
+
+                    <p>You can check current permissions for privacy-related privileges and request user permission to use specified privileges.</p>
+                    <p>Before Tizen 4.0, the pop-up requesting the user's consent to use privacy-related privileges was triggered by first access to protected resources or functionality. Since Tizen 4.0, you can decide the moment in the application life-cycle when permissions are granted. It can be at the application startup, or at the moment when some additional functionality is to be used. For example, a notepad application where the user can enter both text notes and photographs does not automatically require camera access in order to be used (maybe the user only wants to add text notes). Optimally, the application requests the user to grant camera access permission only when the user needs the camera.</p>
+
+                    <p>The main features of the <code>Tizen.Security.PrivacyPrivilegeManager</code> class include:</p>
+                    <ul>
+                        <li>Checking privilege status
+                            <p>If the application declares privacy-related privileges in its manifest file, you must <a href="#requesting">determine the current status</a> of a privacy-related privilege during the application runtime. This allows the application to make sure that the user has granted permission to use the needed privileges.</p></li>
+                        <li>Requesting privileges
+                            <p>If a required permission is missing, you can <a href="#requesting">request the user to grant it</a> to be able to use privileged features.</p></li>
+                    </ul>
+                    <p>For a list of privacy-related privileges, see <a href="../../../org.tizen.training/html/native/details/sec_privileges_n.htm">Security and API Privileges</a>.</p>
+
+                    <h2 id="prerequisites">Prerequisites</h2>
+                    <p>To enable your application to use the privacy-related privileges functionality:</p>
+                    <ol>
+                        <li>To use the methods and properties of the <a href="https://developer.tizen.org/dev-guide/csapi/namespaceTizen_1_1Security.html">Tizen.Security</a> namespace, include it in your application:
+<pre class="prettyprint">
+using Tizen.Security;
+</pre>
+                        </li>
+                        <li>Call the <code>Tizen.Security.PrivacyPrivilegeManager</code> methods from the context of the application's main event loop.
+                            <p>It means that the methods can be employed in any UI event handler (such as button click, timer event, system event, and application state change event). If you want to resolve privileges during application startup, call these methods from the Xamarin.Forms resume and start life-cycle methods (<code>Xamarin.Forms.Application.OnResume()</code> and <code>Xamarin.Forms.Application.OnStart()</code>).</p>
+
+                            <div class="note">
+                                <strong>Note</strong>
+                                The <code>Tizen.Security.PrivacyPrivilegeManager</code> class is not thread-safe.
+                            </div>
+                        </li>
+                    </ol>
+                    <h2 id="requesting">Requesting Permissions</h2>
+
+                    <p>To check whether an application has permission to use a privilege, and to request permission if required:</p>
+                    <ol>
+                        <li>To check whether an application has permission to use a particular privilege, use the <code>CheckPermission()</code> method of the <a href="https://developer.tizen.org/dev-guide/csapi/classTizen_1_1Security_1_1PrivacyPrivilegeManager.html">Tizen.Security.PrivacyPrivilegeManager</a> class:
+<pre class="prettyprint">
+const string cameraPrivilege = "http://tizen.org/privilege/camera";
+
+void CheckAndRequestCameraPermission()
+{
+    try
+    {
+        CheckResult result = PrivacyPrivilegeManager.CheckPermission(cameraPrivilege);
+</pre>
+
+                            <p>The result of the call is returned as a value of the <code>Tizen.Security.CheckResult</code> enumeration.</p>
+                        </li>
+                        <li>React to the permission check appropriately:
+                            <ul>
+                                <li>If the result value is <code>Allow</code>, the application is allowed to perform operations related to the privilege. For example, the application can enable additional UI elements or functionalities.
+<pre class="prettyprint">
+        switch (result)
+        {
+            case CheckResult.Allow:
+                /// Update UI and start accessing protected functionality
+                break;
+</pre>
+                                </li>
+                                <li>If the result value is <code>Deny</code>, the application is not allowed to perform operations related to the privilege. Any attempt to use such functionality without the user's consent fails. Usually, this means that invoking any method that involves the privilege results in an error.
+<pre class="prettyprint">
+            case CheckResult.Deny:
+                /// Show a message and terminate the application
+                break;
+</pre>
+                                </li>
+                                <li>If the result value is <code>Ask</code>, the application must request permission from the user with the <code>RequestPermission()</code> method, which displays a dialog box. When the user makes a decision, an event handler is invoked (the event handler must have been <a href="#handler">previously registered</a>).
+
+                                    <p>The dialog box asking for user permission is shown only if the <code>RequestPermission()</code> method does not throw an exception.</p>
+<pre class="prettyprint">
+            case CheckResult.Ask:
+                PrivacyPrivilegeManager.RequestPermission(cameraPrivilege);
+                break;
+        }
+</pre>
+                                </li>
+                            </ul>
+<pre class="prettyprint">
+    }
+    catch (Exception e)
+    {
+        /// Handle exception
+    }
+}
+</pre>
+                        </li>
+
+                        <li id="handler">If you need to request user permission, handle the user decision within an event handler registered for the <code>ResponseFetched</code> event of the <a href="https://developer.tizen.org/dev-guide/csapi/classTizen_1_1Security_1_1ResponseContext.html">Tizen.Security.ResponseContext</a> class.
+                            <p>The user decision is returned in the event handler as the <code>result</code> property of the <a href="https://developer.tizen.org/dev-guide/csapi/classTizen_1_1Security_1_1RequestResponseEventArgs.html">Tizen.Security.RequestResponseEventArgs</a> class.</p>
+                                                       <p>Make sure the event handler is registered before calling the <code>RequestPermission()</code> method of the <code>Tizen.Security.PrivacyPrivilegeManager</code> class. For a Xamarin.Forms application, the best place to register the event handler is the <code>Xamarin.Forms.Application.OnStart()</code> life-cycle method.</p>
+
+<pre class="prettyprint">
+private void SetupPPMHandler(string privilege)
+{
+    PrivacyPrivilegeManager.ResponseContext context = null;
+    if (PrivacyPrivilegeManager.GetResponseContext(privilege).TryGetTarget(out context))
+    {
+        context.ResponseFetched += PPMResponseHandler;
+    }
+}
+
+protected override void OnStart()
+{
+    SetupPPMHandler(cameraPrivilege);
+}
+
+void PPMResponseHandler(object sender, RequestResponseEventArgs e)
+{
+    if (e.cause == CallCause.Error)
+    {
+        /// Handle errors
+        return;
+    }
+
+    switch (e.result)
+    {
+        case RequestResult.AllowForever:
+            /// Update UI and start accessing protected functionality
+            break;
+        case RequestResult.DenyForever:
+            /// Show a message and terminate the application
+            break;
+        case RequestResult.DenyOnce:
+            /// Show a message with explanation
+            break;
+    }
+}
+</pre>
+                            <ul>
+                                <li>If the user decision is <code>AllowForever</code> or <code>DenyForever</code>, the decision is definitive and the application can react appropriately. It can finish its execution (if denied permission) or start to use protected methods (if granted permission).</li>
+                                <li>If the user decision is <code>DenyOnce</code>, the decision is not definitive. In this case, access to protected functionality is still prohibited. This decision can be interpreted as a cancel action on behalf of the user, indicating that the user is not sure what the purpose of the request is. Therefore, consider providing some additional information to explain why the permission is required.</li>
+                            </ul>
+                            <p>If the decision is definitive, any subsequent <code>RequestPermission()</code> calls result in an immediate response with an appropriate result: <code>AllowForever</code> or <code>DenyForever</code>. However, the user can change the status of privacy-related privileges later by modifying the privacy settings on the device. For this reason, the application must always check the status of privacy-related privileges before using protected functionality.</p>
+                        </li>
+                    </ol>
+
+                    <div class="note">
+                        <strong>Note</strong>
+                        Since the privileges are grouped, the user's decision regarding 1 privilege applies to the whole group of related privileges. For example, if the user has granted permission to use the <code>http://tizen.org/privilege/account.read</code> privilege, permission is automatically granted to the <code>http://tizen.org/privilege/account.write</code> privilege also. Be aware that both privileges need to be declared in the application manifest file. If you declare only 1 of them, the above rule does not apply.
+                    </div>
+                    <script type="text/javascript" src="../scripts/jquery.zclip.min.js"></script>
+                    <script type="text/javascript" src="../scripts/showhide.js"></script>
+                </div>
+            </div>
+        </div>
+
+        <a class="top sms" href="#"><img src="../images/btn_top.gif" alt="Go to top"/></a>
+
+        <div id="footer">
+            <p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+        </div>
+
+        <script type="text/javascript">
+        var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-25976949-1']);
+        _gaq.push(['_trackPageview']);
+        (function () {
+            var ga = document.createElement('script');
+            ga.type = 'text/javascript';
+            ga.async = true;
+            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+            var s = document.getElementsByTagName('script')[0];
+            s.parentNode.insertBefore(ga, s);
+        })();
+        </script>
+
+    </body>
+</html>