Wink Saville | 3d6d348 | 2010-07-19 20:37:44 -0700 | [diff] [blame] | 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> |
Wink Saville | 9a9fbd2 | 2011-02-15 17:13:10 -0800 | [diff] [blame^] | 18 | #include "ril.h" |
Wink Saville | 3d6d348 | 2010-07-19 20:37:44 -0700 | [diff] [blame] | 19 | |
| 20 | #include "logging.h" |
| 21 | #include "status.h" |
| 22 | #include "worker.h" |
| 23 | #include "util.h" |
| 24 | |
Ying Wang | 44662d0 | 2010-11-02 18:45:27 -0700 | [diff] [blame] | 25 | #include "hardware/ril/mock-ril/src/proto/ril.pb.h" |
Wink Saville | 3d6d348 | 2010-07-19 20:37:44 -0700 | [diff] [blame] | 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 | |
| 36 | void testStlPort() { |
| 37 | // Test using STLport |
| 38 | std::queue<int *> q; |
| 39 | int data[] = {1, 2, 3}; |
| 40 | |
| 41 | int *param = data; |
| 42 | LOGD("before push q.size=%d", q.size()); |
| 43 | q.push(param); |
| 44 | LOGD("after push q.size=%d", q.size()); |
| 45 | void *p = q.front(); |
| 46 | if (p == param) { |
| 47 | LOGD("q.push succeeded"); |
| 48 | } else { |
| 49 | LOGD("q.push failed"); |
| 50 | } |
| 51 | q.pop(); |
| 52 | LOGD("after pop q.size=%d", q.size()); |
| 53 | } |
| 54 | |
| 55 | v8::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 | LOGD("GetReqScreenState state=%d", state); |
| 63 | return v8::Integer::New(state); |
| 64 | } |
| 65 | |
| 66 | bool 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 | LOGD("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 | LOGD("callOnRilRequest RIL_REQUEST_SCREEN_STATE"); |
| 91 | if (datalen < sizeof(int)) { |
| 92 | LOGD("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 | LOGD("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 | LOGD("callOnRilRequest error"); |
| 121 | ReportException(&try_catch); |
| 122 | retValue = false; |
| 123 | } else { |
| 124 | v8::String::Utf8Value result_string(result); |
| 125 | LOGD("callOnRilRequest result=%s", ToCString(result_string)); |
| 126 | retValue = true; |
| 127 | } |
| 128 | return retValue; |
| 129 | } |
| 130 | |
| 131 | void testOnRilRequestUsingCppRequestObjs(v8::Handle<v8::Context> context) { |
| 132 | LOGD("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 | LOGD("testOnRilRequestUsingCppRequestObjs X:"); |
| 153 | } |
| 154 | |
| 155 | void testReqScreenStateProtobuf() { |
| 156 | v8::HandleScope handle_scope; |
| 157 | v8::TryCatch try_catch; |
| 158 | |
| 159 | LOGD("testReqScreenStateProtobuf E"); |
| 160 | |
| 161 | LOGD("create ReqScreenState"); |
| 162 | ril_proto::ReqScreenState* ss = new ril_proto::ReqScreenState(); |
| 163 | ss->set_state(true); |
| 164 | bool state = ss->state(); |
| 165 | LOGD("state=%d", state); |
| 166 | ss->set_state(false); |
| 167 | state = ss->state(); |
| 168 | LOGD("state=%d", state); |
| 169 | int len = ss->ByteSize(); |
| 170 | LOGD("create buffer len=%d", len); |
| 171 | char *buffer = new char[len]; |
| 172 | LOGD("serialize"); |
| 173 | bool ok = ss->SerializeToArray(buffer, len); |
| 174 | if (!ok) { |
| 175 | LOGD("testReqScreenStateProtobuf X: Could not serialize ss"); |
| 176 | return; |
| 177 | } |
| 178 | LOGD("ReqScreenState serialized ok"); |
| 179 | ril_proto::ReqScreenState *newSs = new ril_proto::ReqScreenState(); |
| 180 | ok = newSs->ParseFromArray(buffer, len); |
| 181 | if (!ok) { |
| 182 | LOGD("testReqScreenStateProtobuf X: Could not deserialize ss"); |
| 183 | return; |
| 184 | } |
| 185 | LOGD("newSs->state=%d", newSs->state()); |
| 186 | |
| 187 | delete [] buffer; |
| 188 | delete ss; |
| 189 | delete newSs; |
| 190 | LOGD("testReqScreenStateProtobuf X"); |
| 191 | } |
| 192 | |
| 193 | void testReqHangUpProtobuf() { |
| 194 | v8::HandleScope handle_scope; |
| 195 | v8::TryCatch try_catch; |
| 196 | |
| 197 | LOGD("testReqHangUpProtobuf E"); |
| 198 | |
| 199 | LOGD("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 | LOGD("connection_index=%d", connection_index); |
| 204 | hu->set_connection_index(2); |
| 205 | connection_index = hu->connection_index(); |
| 206 | LOGD("connection_index=%d", connection_index); |
| 207 | LOGD("create buffer"); |
| 208 | int len = hu->ByteSize(); |
| 209 | char *buffer = new char[len]; |
| 210 | LOGD("serialize"); |
| 211 | bool ok = hu->SerializeToArray(buffer, len); |
| 212 | if (!ok) { |
| 213 | LOGD("testReqHangUpProtobuf X: Could not serialize hu"); |
| 214 | return; |
| 215 | } |
| 216 | LOGD("ReqHangUp serialized ok"); |
| 217 | ril_proto::ReqHangUp *newHu = new ril_proto::ReqHangUp(); |
| 218 | ok = newHu->ParseFromArray(buffer, len); |
| 219 | if (!ok) { |
| 220 | LOGD("testReqHangUpProtobuf X: Could not deserialize hu"); |
| 221 | return; |
| 222 | } |
| 223 | LOGD("newHu->connection_index=%d", newHu->connection_index()); |
| 224 | |
| 225 | delete [] buffer; |
| 226 | delete hu; |
| 227 | delete newHu; |
| 228 | LOGD("testReqHangUpProtobuf X"); |
| 229 | } |
| 230 | |
| 231 | void testProtobufV8(v8::Handle<v8::Context> context) { |
| 232 | LOGD("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 | LOGD("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 | LOGD("testProtobufV8 X"); |
| 272 | } |
| 273 | |
| 274 | void experiments(v8::Handle<v8::Context> context) { |
| 275 | LOGD("experiments E: ********"); |
| 276 | testStlPort(); |
| 277 | testReqScreenStateProtobuf(); |
| 278 | testOnRilRequestUsingCppRequestObjs(context); |
| 279 | testProtobufV8(context); |
| 280 | LOGD("experiments X: ********\n"); |
| 281 | } |