| /** |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <v8.h> |
| #include <telephony/ril.h> |
| |
| #include "logging.h" |
| #include "status.h" |
| #include "worker.h" |
| #include "util.h" |
| |
| #include "ril.pb.h" |
| |
| #include "logging.h" |
| #include "js_support.h" |
| #include "node_buffer.h" |
| #include "node_util.h" |
| #include "protobuf_v8.h" |
| #include "requests.h" |
| |
| #include "experiments.h" |
| |
| void testStlPort() { |
| // Test using STLport |
| std::queue<int *> q; |
| int data[] = {1, 2, 3}; |
| |
| int *param = data; |
| LOGD("before push q.size=%d", q.size()); |
| q.push(param); |
| LOGD("after push q.size=%d", q.size()); |
| void *p = q.front(); |
| if (p == param) { |
| LOGD("q.push succeeded"); |
| } else { |
| LOGD("q.push failed"); |
| } |
| q.pop(); |
| LOGD("after pop q.size=%d", q.size()); |
| } |
| |
| v8::Handle<v8::Value> GetReqScreenState(v8::Local<v8::String> property, |
| const v8::AccessorInfo &info) { |
| v8::Local<v8::Object> self = info.Holder(); |
| v8::Local<v8::External> wrap = |
| v8::Local<v8::External>::Cast(self->GetInternalField(0)); |
| void *p = wrap->Value(); |
| int state = static_cast<int *>(p)[0]; |
| LOGD("GetReqScreenState state=%d", state); |
| return v8::Integer::New(state); |
| } |
| |
| bool callOnRilRequest(v8::Handle<v8::Context> context, int request, |
| void *data, size_t datalen, RIL_Token t) { |
| v8::HandleScope handle_scope; |
| v8::TryCatch try_catch; |
| |
| // Get the onRilRequestFunction, making sure its a function |
| v8::Handle<v8::String> name = v8::String::New("onRilRequest"); |
| v8::Handle<v8::Value> onRilRequestFunctionValue = context->Global()->Get(name); |
| if(!onRilRequestFunctionValue->IsFunction()) { |
| // Wasn't a function |
| LOGD("callOnRilRequest X wasn't a function"); |
| return false; |
| } |
| v8::Handle<v8::Function> onRilRequestFunction = |
| v8::Handle<v8::Function>::Cast(onRilRequestFunctionValue); |
| |
| // Create the request |
| v8::Handle<v8::Value> v8RequestValue = v8::Number::New(request); |
| |
| // Create the parameter for the request |
| v8::Handle<v8::Object> params_obj = |
| v8::ObjectTemplate::New()->NewInstance(); |
| switch(request) { |
| case(RIL_REQUEST_SCREEN_STATE): { |
| LOGD("callOnRilRequest RIL_REQUEST_SCREEN_STATE"); |
| if (datalen < sizeof(int)) { |
| LOGD("callOnRilRequest err size < sizeof int"); |
| } else { |
| v8::Handle<v8::ObjectTemplate> params_obj_template = |
| v8::ObjectTemplate::New(); |
| params_obj_template->SetInternalFieldCount(1); |
| params_obj_template->SetAccessor(v8::String::New( |
| "ReqScreenState"), GetReqScreenState, NULL); |
| // How to not leak this pointer!!! |
| int *p = new int; |
| *p = ((int *)data)[0]; |
| params_obj = params_obj_template->NewInstance(); |
| params_obj->SetInternalField(0, v8::External::New(p)); |
| } |
| break; |
| } |
| default: { |
| LOGD("callOnRilRequest X unknown request"); |
| break; |
| } |
| } |
| |
| // Invoke onRilRequest |
| bool retValue; |
| const int argc = 2; |
| v8::Handle<v8::Value> argv[argc] = { v8RequestValue, params_obj }; |
| v8::Handle<v8::Value> result = |
| onRilRequestFunction->Call(context->Global(), argc, argv); |
| if (try_catch.HasCaught()) { |
| LOGD("callOnRilRequest error"); |
| ReportException(&try_catch); |
| retValue = false; |
| } else { |
| v8::String::Utf8Value result_string(result); |
| LOGD("callOnRilRequest result=%s", ToCString(result_string)); |
| retValue = true; |
| } |
| return retValue; |
| } |
| |
| void testOnRilRequestUsingCppRequestObjs(v8::Handle<v8::Context> context) { |
| LOGD("testOnRilRequestUsingCppRequestObjs E:"); |
| v8::HandleScope handle_scope; |
| |
| v8::TryCatch try_catch; |
| try_catch.SetVerbose(true); |
| |
| runJs(context, &try_catch, "local-string", |
| "function onRilRequest(reqNum, params) {\n" |
| " print(\"reqNum=\" + reqNum);\n" |
| " if (reqNum == 61) {\n" |
| " print(\"params.ReqScreenState=\" + params.ReqScreenState);\n" |
| " }\n" |
| " return \"Hello World\";\n" |
| "}\n"); |
| if (!try_catch.HasCaught()) { |
| // Call the onRilRequest function |
| int data[1] = { 0 }; |
| callOnRilRequest(context, RIL_REQUEST_SCREEN_STATE, data, |
| sizeof(data), NULL); |
| } |
| LOGD("testOnRilRequestUsingCppRequestObjs X:"); |
| } |
| |
| void testReqScreenStateProtobuf() { |
| v8::HandleScope handle_scope; |
| v8::TryCatch try_catch; |
| |
| LOGD("testReqScreenStateProtobuf E"); |
| |
| LOGD("create ReqScreenState"); |
| ril_proto::ReqScreenState* ss = new ril_proto::ReqScreenState(); |
| ss->set_state(true); |
| bool state = ss->state(); |
| LOGD("state=%d", state); |
| ss->set_state(false); |
| state = ss->state(); |
| LOGD("state=%d", state); |
| int len = ss->ByteSize(); |
| LOGD("create buffer len=%d", len); |
| char *buffer = new char[len]; |
| LOGD("serialize"); |
| bool ok = ss->SerializeToArray(buffer, len); |
| if (!ok) { |
| LOGD("testReqScreenStateProtobuf X: Could not serialize ss"); |
| return; |
| } |
| LOGD("ReqScreenState serialized ok"); |
| ril_proto::ReqScreenState *newSs = new ril_proto::ReqScreenState(); |
| ok = newSs->ParseFromArray(buffer, len); |
| if (!ok) { |
| LOGD("testReqScreenStateProtobuf X: Could not deserialize ss"); |
| return; |
| } |
| LOGD("newSs->state=%d", newSs->state()); |
| |
| delete [] buffer; |
| delete ss; |
| delete newSs; |
| LOGD("testReqScreenStateProtobuf X"); |
| } |
| |
| void testReqHangUpProtobuf() { |
| v8::HandleScope handle_scope; |
| v8::TryCatch try_catch; |
| |
| LOGD("testReqHangUpProtobuf E"); |
| |
| LOGD("create ReqHangUp"); |
| ril_proto::ReqHangUp* hu = new ril_proto::ReqHangUp(); |
| hu->set_connection_index(3); |
| bool connection_index = hu->connection_index(); |
| LOGD("connection_index=%d", connection_index); |
| hu->set_connection_index(2); |
| connection_index = hu->connection_index(); |
| LOGD("connection_index=%d", connection_index); |
| LOGD("create buffer"); |
| int len = hu->ByteSize(); |
| char *buffer = new char[len]; |
| LOGD("serialize"); |
| bool ok = hu->SerializeToArray(buffer, len); |
| if (!ok) { |
| LOGD("testReqHangUpProtobuf X: Could not serialize hu"); |
| return; |
| } |
| LOGD("ReqHangUp serialized ok"); |
| ril_proto::ReqHangUp *newHu = new ril_proto::ReqHangUp(); |
| ok = newHu->ParseFromArray(buffer, len); |
| if (!ok) { |
| LOGD("testReqHangUpProtobuf X: Could not deserialize hu"); |
| return; |
| } |
| LOGD("newHu->connection_index=%d", newHu->connection_index()); |
| |
| delete [] buffer; |
| delete hu; |
| delete newHu; |
| LOGD("testReqHangUpProtobuf X"); |
| } |
| |
| void testProtobufV8(v8::Handle<v8::Context> context) { |
| LOGD("testProtobufV8 E:"); |
| v8::HandleScope handle_scope; |
| |
| v8::TryCatch try_catch; |
| try_catch.SetVerbose(true); |
| |
| if (try_catch.HasCaught()) { |
| LOGD("TryCatch.hasCaught is true after protobuf_v8::init"); |
| ReportException(&try_catch); |
| } |
| runJs(context, &try_catch, "local-string", |
| "fileContents = readFileToString('mock_ril.js');\n" |
| "print('fileContents:\\n' + fileContents);\n" |
| "\n" |
| "buffer = readFileToBuffer('ril.desc');\n" |
| "var schema = new Schema(buffer);\n" |
| "\n" |
| "var originalReqEnterSimPin = { pin : 'hello-the-pin' };\n" |
| "print('originalReqEnterSimPin: pin=' + originalReqEnterSimPin.pin);\n" |
| "var ReqEnterSimPinSchema = schema['ril_proto.ReqEnterSimPin'];\n" |
| "serializedOriginalReqEnterSimPin = ReqEnterSimPinSchema.serialize(originalReqEnterSimPin);\n" |
| "print('serializedOriginalReqEnterSimPin.length=' + serializedOriginalReqEnterSimPin.length);\n" |
| "newReqEnterSimPin = ReqEnterSimPinSchema.parse(serializedOriginalReqEnterSimPin);\n" |
| "print('newReqEnterSimPin: pin=' + newReqEnterSimPin.pin);\n" |
| "\n" |
| "var originalReqScreenState = { state : true };\n" |
| "print('originalReqScreenState: state=' + originalReqScreenState.state);\n" |
| "var ReqScreenStateSchema = schema['ril_proto.ReqScreenState'];\n" |
| "var serializedOriginalReqScreenState = ReqScreenStateSchema.serialize(originalReqScreenState);\n" |
| "print('serializedOriginalReqScreenState.length=' + serializedOriginalReqScreenState.length);\n" |
| "var newReqScreenState = ReqScreenStateSchema.parse(serializedOriginalReqScreenState);\n" |
| "print('newReqScreenState: state=' + newReqScreenState.state);\n" |
| "\n" |
| "originalReqScreenState.state = false;\n" |
| "print('originalReqScreenState: state=' + originalReqScreenState.state);\n" |
| "serializedOriginalReqScreenState = ReqScreenStateSchema.serialize(originalReqScreenState);\n" |
| "print('serializedOriginalReqScreenState.length=' + serializedOriginalReqScreenState.length);\n" |
| "newReqScreenState = ReqScreenStateSchema.parse(serializedOriginalReqScreenState);\n" |
| "print('newReqScreenState: state=' + newReqScreenState.state);\n"); |
| LOGD("testProtobufV8 X"); |
| } |
| |
| void experiments(v8::Handle<v8::Context> context) { |
| LOGD("experiments E: ********"); |
| testStlPort(); |
| testReqScreenStateProtobuf(); |
| testOnRilRequestUsingCppRequestObjs(context); |
| testProtobufV8(context); |
| LOGD("experiments X: ********\n"); |
| } |