--- /dev/null
+/**
+ * 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");
+}