blob: 317fd9d12160fc4760930ae59674327a61b4b371 [file] [log] [blame]
/**
* 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");
}