1 /*
2  *    Copyright 2019 Kai Pastor
3  *
4  *    This file is part of OpenOrienteering.
5  *
6  *    OpenOrienteering is free software: you can redistribute it and/or modify
7  *    it under the terms of the GNU General Public License as published by
8  *    the Free Software Foundation, either version 3 of the License, or
9  *    (at your option) any later version.
10  *
11  *    OpenOrienteering is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with OpenOrienteering.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #include "app_permissions.h"
22 
23 #include <algorithm>
24 #include <QtAndroid>
25 
26 
27 namespace AppPermissions
28 {
29 
30 namespace
31 {
32 
33 /**
34  * Returns a functor that tests if the passed permission is granted.
35  */
granted()36 auto granted()
37 {
38 	return [](const QString& permission)->bool {
39 		return QtAndroid::checkPermission(permission) == QtAndroid::PermissionResult::Granted;
40 	};
41 }
42 
43 /**
44  * Returns a functor that tests if the passed permissions are granted
45  * in the actual permissions given at functor creation time.
46  */
granted(const QtAndroid::PermissionResultMap & actual_permissions)47 auto granted(const QtAndroid::PermissionResultMap& actual_permissions)
48 {
49 	return [&actual_permissions](const QString& permission)->bool {
50 		return actual_permissions.contains(permission)
51 		       && actual_permissions[permission] == QtAndroid::PermissionResult::Granted;
52 	};
53 }
54 
55 }  // namespace
56 
57 
58 
androidPermissions(AppPermission permission)59 QStringList androidPermissions(AppPermission permission)
60 {
61 	QStringList android_permissions;
62 	android_permissions.reserve(2);
63 
64 	switch (permission)
65 	{
66 	case StorageAccess:
67 		android_permissions << QStringLiteral("android.permission.READ_EXTERNAL_STORAGE")
68 		                    << QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE");
69 		break;
70 
71 	case LocationAccess:
72 		android_permissions << QStringLiteral("android.permission.ACCESS_FINE_LOCATION");
73 		break;
74 	}
75 
76 	return android_permissions;
77 }
78 
79 
permissionsGranted(const QStringList & requested_permissions,const QtAndroid::PermissionResultMap & actual_permissions)80 bool permissionsGranted(const QStringList& requested_permissions, const QtAndroid::PermissionResultMap& actual_permissions)
81 {
82 	using std::begin; using std::end;
83 	if (std::all_of(begin(requested_permissions), end(requested_permissions), granted(actual_permissions)))
84 		return Granted;
85 	return Denied;
86 }
87 
88 
checkPermission(AppPermission permission)89 PermissionResult checkPermission(AppPermission permission)
90 {
91 	using std::begin; using std::end;
92 	auto const requested_permissions = androidPermissions(permission);
93 	if (std::all_of(begin(requested_permissions), end(requested_permissions), granted()))
94 		return Granted;
95 	return Denied;
96 }
97 
98 
requestPermissionSync(AppPermission permission)99 PermissionResult requestPermissionSync(AppPermission permission)
100 {
101 	auto const requested_permissions = androidPermissions(permission);
102 	auto const actual_permissions = QtAndroid::requestPermissionsSync(requested_permissions);
103 	if (permissionsGranted(requested_permissions, actual_permissions))
104 		return Granted;
105 	return Denied;
106 }
107 
108 
109 }  // namespace AppPermissions
110