1/** 2 * Copyright (C) 2010 The Android Open Source Project 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 <v8.h> 18#include "ril.h" 19 20#include "logging.h" 21#include "status.h" 22#include "worker.h" 23#include "util.h" 24 25#include "hardware/ril/mock-ril/src/proto/ril.pb.h" 26 27#include "logging.h" 28#include "js_support.h" 29#include "node_buffer.h" 30#include "node_util.h" 31#include "protobuf_v8.h" 32#include "requests.h" 33 34#include "experiments.h" 35 36void testStlPort() { 37 // Test using STLport 38 std::queue<int *> q; 39 int data[] = {1, 2, 3}; 40 41 int *param = data; 42 ALOGD("before push q.size=%d", q.size()); 43 q.push(param); 44 ALOGD("after push q.size=%d", q.size()); 45 void *p = q.front(); 46 if (p == param) { 47 ALOGD("q.push succeeded"); 48 } else { 49 ALOGD("q.push failed"); 50 } 51 q.pop(); 52 ALOGD("after pop q.size=%d", q.size()); 53} 54 55v8::Handle<v8::Value> GetReqScreenState(v8::Local<v8::String> property, 56 const v8::AccessorInfo &info) { 57 v8::Local<v8::Object> self = info.Holder(); 58 v8::Local<v8::External> wrap = 59 v8::Local<v8::External>::Cast(self->GetInternalField(0)); 60 void *p = wrap->Value(); 61 int state = static_cast<int *>(p)[0]; 62 ALOGD("GetReqScreenState state=%d", state); 63 return v8::Integer::New(state); 64} 65 66bool callOnRilRequest(v8::Handle<v8::Context> context, int request, 67 void *data, size_t datalen, RIL_Token t) { 68 v8::HandleScope handle_scope; 69 v8::TryCatch try_catch; 70 71 // Get the onRilRequestFunction, making sure its a function 72 v8::Handle<v8::String> name = v8::String::New("onRilRequest"); 73 v8::Handle<v8::Value> onRilRequestFunctionValue = context->Global()->Get(name); 74 if(!onRilRequestFunctionValue->IsFunction()) { 75 // Wasn't a function 76 ALOGD("callOnRilRequest X wasn't a function"); 77 return false; 78 } 79 v8::Handle<v8::Function> onRilRequestFunction = 80 v8::Handle<v8::Function>::Cast(onRilRequestFunctionValue); 81 82 // Create the request 83 v8::Handle<v8::Value> v8RequestValue = v8::Number::New(request); 84 85 // Create the parameter for the request 86 v8::Handle<v8::Object> params_obj = 87 v8::ObjectTemplate::New()->NewInstance(); 88 switch(request) { 89 case(RIL_REQUEST_SCREEN_STATE): { 90 ALOGD("callOnRilRequest RIL_REQUEST_SCREEN_STATE"); 91 if (datalen < sizeof(int)) { 92 ALOGD("callOnRilRequest err size < sizeof int"); 93 } else { 94 v8::Handle<v8::ObjectTemplate> params_obj_template = 95 v8::ObjectTemplate::New(); 96 params_obj_template->SetInternalFieldCount(1); 97 params_obj_template->SetAccessor(v8::String::New( 98 "ReqScreenState"), GetReqScreenState, NULL); 99 // How to not leak this pointer!!! 100 int *p = new int; 101 *p = ((int *)data)[0]; 102 params_obj = params_obj_template->NewInstance(); 103 params_obj->SetInternalField(0, v8::External::New(p)); 104 } 105 break; 106 } 107 default: { 108 ALOGD("callOnRilRequest X unknown request"); 109 break; 110 } 111 } 112 113 // Invoke onRilRequest 114 bool retValue; 115 const int argc = 2; 116 v8::Handle<v8::Value> argv[argc] = { v8RequestValue, params_obj }; 117 v8::Handle<v8::Value> result = 118 onRilRequestFunction->Call(context->Global(), argc, argv); 119 if (try_catch.HasCaught()) { 120 ALOGD("callOnRilRequest error"); 121 ReportException(&try_catch); 122 retValue = false; 123 } else { 124 v8::String::Utf8Value result_string(result); 125 ALOGD("callOnRilRequest result=%s", ToCString(result_string)); 126 retValue = true; 127 } 128 return retValue; 129} 130 131void testOnRilRequestUsingCppRequestObjs(v8::Handle<v8::Context> context) { 132 ALOGD("testOnRilRequestUsingCppRequestObjs E:"); 133 v8::HandleScope handle_scope; 134 135 v8::TryCatch try_catch; 136 try_catch.SetVerbose(true); 137 138 runJs(context, &try_catch, "local-string", 139 "function onRilRequest(reqNum, params) {\n" 140 " print(\"reqNum=\" + reqNum);\n" 141 " if (reqNum == 61) {\n" 142 " print(\"params.ReqScreenState=\" + params.ReqScreenState);\n" 143 " }\n" 144 " return \"Hello World\";\n" 145 "}\n"); 146 if (!try_catch.HasCaught()) { 147 // Call the onRilRequest function 148 int data[1] = { 0 }; 149 callOnRilRequest(context, RIL_REQUEST_SCREEN_STATE, data, 150 sizeof(data), NULL); 151 } 152 ALOGD("testOnRilRequestUsingCppRequestObjs X:"); 153} 154 155void testReqScreenStateProtobuf() { 156 v8::HandleScope handle_scope; 157 v8::TryCatch try_catch; 158 159 ALOGD("testReqScreenStateProtobuf E"); 160 161 ALOGD("create ReqScreenState"); 162 ril_proto::ReqScreenState* ss = new ril_proto::ReqScreenState(); 163 ss->set_state(true); 164 bool state = ss->state(); 165 ALOGD("state=%d", state); 166 ss->set_state(false); 167 state = ss->state(); 168 ALOGD("state=%d", state); 169 int len = ss->ByteSize(); 170 ALOGD("create buffer len=%d", len); 171 char *buffer = new char[len]; 172 ALOGD("serialize"); 173 bool ok = ss->SerializeToArray(buffer, len); 174 if (!ok) { 175 ALOGD("testReqScreenStateProtobuf X: Could not serialize ss"); 176 return; 177 } 178 ALOGD("ReqScreenState serialized ok"); 179 ril_proto::ReqScreenState *newSs = new ril_proto::ReqScreenState(); 180 ok = newSs->ParseFromArray(buffer, len); 181 if (!ok) { 182 ALOGD("testReqScreenStateProtobuf X: Could not deserialize ss"); 183 return; 184 } 185 ALOGD("newSs->state=%d", newSs->state()); 186 187 delete [] buffer; 188 delete ss; 189 delete newSs; 190 ALOGD("testReqScreenStateProtobuf X"); 191} 192 193void testReqHangUpProtobuf() { 194 v8::HandleScope handle_scope; 195 v8::TryCatch try_catch; 196 197 ALOGD("testReqHangUpProtobuf E"); 198 199 ALOGD("create ReqHangUp"); 200 ril_proto::ReqHangUp* hu = new ril_proto::ReqHangUp(); 201 hu->set_connection_index(3); 202 bool connection_index = hu->connection_index(); 203 ALOGD("connection_index=%d", connection_index); 204 hu->set_connection_index(2); 205 connection_index = hu->connection_index(); 206 ALOGD("connection_index=%d", connection_index); 207 ALOGD("create buffer"); 208 int len = hu->ByteSize(); 209 char *buffer = new char[len]; 210 ALOGD("serialize"); 211 bool ok = hu->SerializeToArray(buffer, len); 212 if (!ok) { 213 ALOGD("testReqHangUpProtobuf X: Could not serialize hu"); 214 return; 215 } 216 ALOGD("ReqHangUp serialized ok"); 217 ril_proto::ReqHangUp *newHu = new ril_proto::ReqHangUp(); 218 ok = newHu->ParseFromArray(buffer, len); 219 if (!ok) { 220 ALOGD("testReqHangUpProtobuf X: Could not deserialize hu"); 221 return; 222 } 223 ALOGD("newHu->connection_index=%d", newHu->connection_index()); 224 225 delete [] buffer; 226 delete hu; 227 delete newHu; 228 ALOGD("testReqHangUpProtobuf X"); 229} 230 231void testProtobufV8(v8::Handle<v8::Context> context) { 232 ALOGD("testProtobufV8 E:"); 233 v8::HandleScope handle_scope; 234 235 v8::TryCatch try_catch; 236 try_catch.SetVerbose(true); 237 238 if (try_catch.HasCaught()) { 239 ALOGD("TryCatch.hasCaught is true after protobuf_v8::init"); 240 ReportException(&try_catch); 241 } 242 runJs(context, &try_catch, "local-string", 243 "fileContents = readFileToString('mock_ril.js');\n" 244 "print('fileContents:\\n' + fileContents);\n" 245 "\n" 246 "buffer = readFileToBuffer('ril.desc');\n" 247 "var schema = new Schema(buffer);\n" 248 "\n" 249 "var originalReqEnterSimPin = { pin : 'hello-the-pin' };\n" 250 "print('originalReqEnterSimPin: pin=' + originalReqEnterSimPin.pin);\n" 251 "var ReqEnterSimPinSchema = schema['ril_proto.ReqEnterSimPin'];\n" 252 "serializedOriginalReqEnterSimPin = ReqEnterSimPinSchema.serialize(originalReqEnterSimPin);\n" 253 "print('serializedOriginalReqEnterSimPin.length=' + serializedOriginalReqEnterSimPin.length);\n" 254 "newReqEnterSimPin = ReqEnterSimPinSchema.parse(serializedOriginalReqEnterSimPin);\n" 255 "print('newReqEnterSimPin: pin=' + newReqEnterSimPin.pin);\n" 256 "\n" 257 "var originalReqScreenState = { state : true };\n" 258 "print('originalReqScreenState: state=' + originalReqScreenState.state);\n" 259 "var ReqScreenStateSchema = schema['ril_proto.ReqScreenState'];\n" 260 "var serializedOriginalReqScreenState = ReqScreenStateSchema.serialize(originalReqScreenState);\n" 261 "print('serializedOriginalReqScreenState.length=' + serializedOriginalReqScreenState.length);\n" 262 "var newReqScreenState = ReqScreenStateSchema.parse(serializedOriginalReqScreenState);\n" 263 "print('newReqScreenState: state=' + newReqScreenState.state);\n" 264 "\n" 265 "originalReqScreenState.state = false;\n" 266 "print('originalReqScreenState: state=' + originalReqScreenState.state);\n" 267 "serializedOriginalReqScreenState = ReqScreenStateSchema.serialize(originalReqScreenState);\n" 268 "print('serializedOriginalReqScreenState.length=' + serializedOriginalReqScreenState.length);\n" 269 "newReqScreenState = ReqScreenStateSchema.parse(serializedOriginalReqScreenState);\n" 270 "print('newReqScreenState: state=' + newReqScreenState.state);\n"); 271 ALOGD("testProtobufV8 X"); 272} 273 274void experiments(v8::Handle<v8::Context> context) { 275 ALOGD("experiments E: ********"); 276 testStlPort(); 277 testReqScreenStateProtobuf(); 278 testOnRilRequestUsingCppRequestObjs(context); 279 testProtobufV8(context); 280 ALOGD("experiments X: ********\n"); 281} 282