46ec01aa5967c66fcbab46b33776c87bead4acd4
[platform/upstream/iotivity.git] / service / resource-container / android / resource-container / src / main / jni / AndroidResource.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21
22 #include "AndroidResource.h"
23 #include "JniRcsResourceAttributes.h"
24 #include "JavaClasses.h"
25 #include "JavaLocalRef.h"
26 #include "JNIEnvWrapper.h"
27 #include "JniRcsValue.h"
28
29 #include <jni.h>
30 #include <string.h>
31 #include <iostream>
32 #include "Log.h"
33
34 #define LOG_TAG "JNI-AndroidResource"
35
36 using namespace OIC::Service;
37 using namespace std;
38
39 namespace
40 {
41     jclass g_cls_RCSBundleInfo;
42     jfieldID g_field_mNativeHandle;
43 }
44
45 void initRCSAndroidResource(JNIEnvWrapper *env)
46 {
47     auto clsAndroidBundleResource = env->FindClass(PACKAGE_NAME "/AndroidBundleResource");
48
49     g_field_mNativeHandle = env->GetFieldID(clsAndroidBundleResource, "mNativeHandle", "J");
50 }
51
52 AndroidResource::AndroidResource()
53 {
54
55 }
56
57 void AndroidResource::initAttributes()
58 {
59
60 }
61
62 AndroidResource::AndroidResource(JNIEnv *env, jobject obj, jobject bundleResource,
63                                        string bundleId, jobjectArray attributes)
64 {
65     LOGD("Creating android resource, bundleId: %s", bundleId.c_str());
66     (void) obj;
67     m_env = env;
68     int stringCount = m_env->GetArrayLength(attributes);
69     LOGD("string count is %d", stringCount);
70
71     for (int i = 0; i < stringCount; i++)
72     {
73         jstring str = (jstring) m_env->GetObjectArrayElement(attributes, i);
74         const char *rawString = m_env->GetStringUTFChars(str, 0);
75         string s(rawString, strlen(rawString));
76         BundleResource::setAttribute(s, "");
77     }
78
79     m_bundleId = bundleId;
80
81     this->m_bundleResource = m_env->NewGlobalRef(bundleResource);
82
83     m_bundleResourceClass = m_env->GetObjectClass(bundleResource);
84     LOGD("Looking for setter.");
85     m_attributeSetRequestHandler = m_env->GetMethodID(m_bundleResourceClass,
86             "handleSetAttributesRequest", "(Lorg/iotivity/service/resourcecontainer/RcsResourceAttributes;)V");
87     LOGD("Looking for getter.");
88     m_attributeGetRequestHandler = m_env->GetMethodID(m_bundleResourceClass,
89             "handleGetAttributesRequest", "()Lorg/iotivity/service/resourcecontainer/RcsResourceAttributes;");
90     //LOGD("Looking for softSensorResource class.");
91     //jclass androidBundleSoftSensorResourceClass = m_env->FindClass("org/iotivity/service/resourcecontainer/AndroidBundleSoftSensorResource");
92     LOGD("Looking for onUpdatedInputResource2.");
93     jclass superclass = m_env->GetSuperclass(m_bundleResourceClass);
94
95     jclass classClass = m_env->FindClass("java/lang/Class");
96
97     // Find the getName() method on the class object
98     jmethodID mid = env->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
99
100     // Call the getName() to get a jstring object back
101     jstring strObj = (jstring)env->CallObjectMethod(superclass, mid);
102
103     // Now get the c string from the java jstring object
104     const char* str = env->GetStringUTFChars(strObj, NULL);
105
106     LOGD("Name of super class is %s", str);
107
108     //check for softsensor resource
109     if(strcmp("org.iotivity.service.resourcecontainer.AndroidBundleSoftSensorResource", str) == 0){
110        m_onUpdatedInputResource = m_env->GetMethodID(m_bundleResourceClass, "onUpdatedInputResource", "(Ljava/lang/String;Ljava/util/Vector;)V");
111        if (env->ExceptionCheck()) {
112            env->ExceptionDescribe();
113        }
114        LOGD("Looking up vector.");
115        m_vectorClazz = m_env->FindClass("java/util/Vector");
116        if (env->ExceptionCheck()) {
117                env->ExceptionDescribe();
118        }
119        LOGD("Looking up vector add method.");
120        m_vectorAddMethod =  m_env->GetMethodID(m_vectorClazz, "add", "(Ljava/lang/Object;)Z");
121        if (env->ExceptionCheck()) {
122               env->ExceptionDescribe();
123        }
124     }
125
126
127     LOGD("Get java vm.");
128     int jvmAccess = m_env->GetJavaVM(&m_jvm);
129     LOGD("JVM: %s", (jvmAccess ? "false" : "true") );
130
131
132 }
133
134 AndroidResource::~AndroidResource()
135 {
136
137 }
138
139 RCSResourceAttributes::Value AndroidResource::handleGetAttributeRequest(
140         const std::string &attributeName)
141 {
142     LOGD("handleGetAttributeRequest called2");
143     LOGD("Attaching thread now");
144     int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
145     if(attached>0)
146     {
147         LOGE("Failed to attach thread to JavaVM");
148     }
149     else{
150         jstring attrName = m_env->NewStringUTF(attributeName.c_str());
151         auto responseObj =  m_env->CallObjectMethod(m_bundleResource,
152                 m_attributeGetRequestHandler, attrName);
153
154         if (responseObj)
155         {
156             LOGD("parsing attributes");
157             RCSResourceAttributes attrs = toNativeAttributes(m_env, responseObj);
158             LOGD("Received attributes %d", attrs.size());
159         }
160         /*const char *js = m_env->GetStringUTFChars(returnString, NULL);
161         std::string val(js);
162         RCSResourceAttributes::Value newVal = val;
163         m_env->ReleaseStringUTFChars(returnString, js);
164         m_jvm->DetachCurrentThread();*/
165         //BundleResource::setAttribute(attributeName, newVal.toString());
166     }
167     return BundleResource::getAttribute(attributeName);
168 }
169
170 void AndroidResource::handleSetAttributeRequest(const std::string &attributeName,
171                                       RCSResourceAttributes::Value &&value)
172 {
173     jstring attrName = m_env->NewStringUTF(attributeName.c_str());
174     jstring val = m_env->NewStringUTF(value.toString().c_str());
175
176     //LOGD("handleSetAttributeRequest calling object method %d", &m_attributeSetRequestHandler);
177     m_env->CallObjectMethod(m_bundleResource, m_attributeSetRequestHandler, attrName, val);
178     BundleResource::setAttribute(attributeName, std::move(value));
179 }
180
181
182 void AndroidResource::handleSetAttributesRequest(RCSResourceAttributes &attrs){
183     LOGD("handleSetAttributesRequest called %d", attrs.size());
184
185     //m_env->CallObjectMethod(m_bundleResource, m_attributeSetRequestHandler, attrName, val);
186     //BundleResource::setAttribute(attributeName, std::move(value));
187
188     int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
189     if(attached>0)
190     {
191         LOGE("Failed to attach thread to JavaVM");
192     }
193     else{
194         LOGD("Creating resource attributes for JNI.");
195         auto jniRcsAttributes = newAttributesObject(m_env, attrs);
196         LOGD("jobject created. calling");
197         m_env->CallVoidMethod(m_bundleResource,
198                 m_attributeSetRequestHandler, jniRcsAttributes);
199         BundleResource::setAttributes(attrs);
200         m_jvm->DetachCurrentThread();
201     }
202 }
203
204 RCSResourceAttributes & AndroidResource::handleGetAttributesRequest()
205 {
206     LOGD("handleGetAttributesRequest");
207     /*std::list<string> attrsNames = getAttributeNames();
208     for(std::list<string>::iterator iterator = attrsNames.begin();
209             iterator != attrsNames.end(); ++iterator )
210     {
211         handleGetAttributeRequest(*iterator);
212     }*/
213     int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
214     if(attached>0)
215     {
216         LOGE("Failed to attach thread to JavaVM");
217     }
218     else{
219         auto responseObj =  m_env->CallObjectMethod(m_bundleResource,
220                 m_attributeGetRequestHandler);
221
222         if (responseObj)
223         {
224             LOGD("parsing attributes");
225
226             RCSResourceAttributes attrs = toNativeAttributes(m_env, responseObj);
227             LOGD("Received attributes %d", attrs.size());
228             BundleResource::setAttributes(attrs, false);
229         }
230
231         m_jvm->DetachCurrentThread();
232     }
233     LOGD("BundleResource::getAttributes().size() %d", BundleResource::getAttributes().size());
234     return BundleResource::getAttributes();
235 }
236
237 void AndroidResource::executeLogic(){
238     LOGD("executeLogic");
239
240 }
241
242 void AndroidResource::onUpdatedInputResource(const std::string attributeName,
243         std::vector<RCSResourceAttributes::Value> values){
244     LOGD("onUpdatedInputResource");
245
246     int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
247     jobject valueObj;
248     if(attached>0)
249     {
250         LOGE("Failed to attach thread to JavaVM");
251     }
252     else{
253         jobject obj = m_env->NewObject(m_vectorClazz, m_env->GetMethodID(m_vectorClazz, "<init>", "()V"));
254
255         for (int n=0;n<values.size();n++)
256         {
257            valueObj  = newRCSValueObject(m_env, values[n]);
258            m_env->CallVoidMethod(obj, m_vectorAddMethod, valueObj);
259         }
260         m_env->CallObjectMethod(m_bundleResource,
261                 m_onUpdatedInputResource, obj);
262         m_jvm->DetachCurrentThread();
263     }
264     LOGD("BundleResource::getAttributes().size() %d", BundleResource::getAttributes().size());
265 }
266
267 JNIEXPORT void JNICALL Java_org_iotivity_service_resourcecontainer_AndroidBundleResource_updateNativeInstance
268 (JNIEnv* env, jobject obj, jobject updates)
269 {
270     LOGD("updateNativeInstance");
271     BundleResource* androidResource = reinterpret_cast<BundleResource*>(env->GetLongField(obj, g_field_mNativeHandle));
272     RCSResourceAttributes attrs = toNativeAttributes(env, updates);
273     LOGD("Received attributes %d", attrs.size());
274     androidResource->setAttributes(attrs, true);
275 }