Replace MethodCallHandler::setCaller() with a parameterized constructor
[platform/core/context/sensor-recorder.git] / src / server / MethodCallHandler.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <ServerUtil.h>
18 #include <Tuple.h>
19 #include "MethodCallHandler.h"
20 #include "legacy/SensorProvider.h"
21
22 #define IDX_SUBJECT     0
23 #define IDX_OPTION      1
24
25 using namespace ctx;
26
27 MethodCallHandler::MethodCallHandler(IClient* client) :
28         __caller(client)
29 {
30 }
31
32 MethodCallHandler::~MethodCallHandler()
33 {
34 }
35
36 void MethodCallHandler::onMethodCalled(IMethodCall* methodCall)
37 {
38         try {
39                 __verifyUid(methodCall->getUid());
40                 std::string subject = __extractParameter(methodCall->getParam(), IDX_SUBJECT);
41                 _D("%s(%s)", methodCall->getMethodName().c_str(), subject.c_str());
42
43                 SensorProvider* provider = SensorProvider::getInstance(subject);
44
45                 if (methodCall->getMethodName() == METHOD_IS_SUPPORTED) {
46                         methodCall->reply(E_NONE);
47
48                 } else if (methodCall->getMethodName() == METHOD_START_REC) {
49                         __startRecording(*provider, *methodCall);
50
51                 } else if (methodCall->getMethodName() == METHOD_STOP_REC) {
52                         __stopRecording(*provider, *methodCall);
53
54                 } else if (methodCall->getMethodName() == METHOD_READ_REC) {
55                         __readRecords(*provider, *methodCall);
56                 }
57
58         } catch (const int error) {
59                 _W("Catch: %s", CTX_ERROR_STR(error));
60                 methodCall->reply(error);
61         }
62
63         delete methodCall;
64 }
65
66 void MethodCallHandler::onDisconnected()
67 {
68 }
69
70 void MethodCallHandler::__verifyUid(uid_t uid)
71 {
72         if (!util::isSystemUid(uid) && uid != util::getActiveUid()) {
73                 _E("Invalid Uid: %u != %u (ActiveUser)", uid, util::getActiveUid());
74                 throw static_cast<int>(E_ACCESS);
75         }
76 }
77
78 std::string MethodCallHandler::__extractParameter(GVariant* param, unsigned int idx)
79 {
80         const char* val = NULL;
81         g_variant_get_child(param, idx, "&s", &val);
82
83         if (!val)
84                 throw static_cast<int>(E_PARAM);
85
86         return val;
87 }
88
89 void MethodCallHandler::__startRecording(SensorProvider& provider, IMethodCall& methodCall)
90 {
91         if (!methodCall.hasPrivilege(provider.getPrivilege()))
92                 throw static_cast<int>(E_ACCESS);
93
94         // TODO: use the 'real' package id, instead of the smack label
95         std::string pkgId = methodCall.getCallerId();
96         std::string option = __extractParameter(methodCall.getParam(), IDX_OPTION);
97         _D("Option: %s", option.c_str());
98
99         int error = provider.startRecording(pkgId, option);
100         methodCall.reply(error);
101 }
102
103 void MethodCallHandler::__stopRecording(SensorProvider& provider, IMethodCall& methodCall)
104 {
105         // TODO: use the 'real' package id, instead of the smack label
106         std::string pkgId = methodCall.getCallerId();
107
108         int error = provider.stopRecording(pkgId);
109         methodCall.reply(error);
110 }
111
112 void MethodCallHandler::__readRecords(SensorProvider& provider, IMethodCall& methodCall)
113 {
114         if (!methodCall.hasPrivilege(provider.getPrivilege()))
115                 throw static_cast<int>(E_ACCESS);
116
117         // TODO: use the 'real' package id, instead of the smack label
118         std::string pkgId = methodCall.getCallerId();
119         std::string option = __extractParameter(methodCall.getParam(), IDX_OPTION);
120         _D("Option: %s", option.c_str());
121
122         std::string projection;
123         std::vector<std::shared_ptr<Tuple>> tuples;
124
125         int error = provider.readRecords(option, &projection, &tuples);
126         if (error != E_NONE)
127                 throw error;
128         if (tuples.empty())
129                 throw static_cast<int>(E_NO_DATA);
130
131         methodCall.reply(g_variant_new("(sv)", projection.c_str(), Tuple::toGVariant(tuples)));
132 }