This source file includes following definitions.
- RegisterJni
- LoadNative
- GetApiKey
- GetClientId
- GetClientSecret
- Connect
- Disconnect
- AuthenticationResponse
- ScheduleRedraw
- SendMouseEvent
- SendMouseWheelEvent
- SendKeyEvent
- SendTextEvent
- GetInstance
- ConnectToHost
- DisconnectFromHost
- ReportConnectionStatus
- DisplayAuthenticationPrompt
- CommitPairingCredentials
- NewBitmap
- UpdateFrameBitmap
- UpdateCursorShape
- RedrawCanvas
- DetachFromVmAndSignal
#include "remoting/client/jni/chromoting_jni_runtime.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/memory/singleton.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "google_apis/google_api_keys.h"
#include "jni/JniInterface_jni.h"
#include "media/base/yuv_convert.h"
#include "remoting/base/url_request_context.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
using base::android::ToJavaByteArray;
namespace {
const int kBytesPerPixel = 4;
}
namespace remoting {
bool RegisterJni(JNIEnv* env) {
return remoting::RegisterNativesImpl(env);
}
static void LoadNative(JNIEnv* env, jclass clazz, jobject context) {
base::android::ScopedJavaLocalRef<jobject> context_activity(env, context);
base::android::InitApplicationContext(env, context_activity);
CommandLine::Init(0, NULL);
remoting::ChromotingJniRuntime::GetInstance();
}
static jstring GetApiKey(JNIEnv* env, jclass clazz) {
return env->NewStringUTF(google_apis::GetAPIKey().c_str());
}
static jstring GetClientId(JNIEnv* env, jclass clazz) {
return env->NewStringUTF(
google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING).c_str());
}
static jstring GetClientSecret(JNIEnv* env, jclass clazz) {
return env->NewStringUTF(
google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING).c_str());
}
static void Connect(JNIEnv* env,
jclass clazz,
jstring username,
jstring authToken,
jstring hostJid,
jstring hostId,
jstring hostPubkey,
jstring pairId,
jstring pairSecret) {
remoting::ChromotingJniRuntime::GetInstance()->ConnectToHost(
ConvertJavaStringToUTF8(env, username).c_str(),
ConvertJavaStringToUTF8(env, authToken).c_str(),
ConvertJavaStringToUTF8(env, hostJid).c_str(),
ConvertJavaStringToUTF8(env, hostId).c_str(),
ConvertJavaStringToUTF8(env, hostPubkey).c_str(),
ConvertJavaStringToUTF8(env, pairId).c_str(),
ConvertJavaStringToUTF8(env, pairSecret).c_str());
}
static void Disconnect(JNIEnv* env, jclass clazz) {
remoting::ChromotingJniRuntime::GetInstance()->DisconnectFromHost();
}
static void AuthenticationResponse(JNIEnv* env,
jclass clazz,
jstring pin,
jboolean createPair,
jstring deviceName) {
remoting::ChromotingJniRuntime::GetInstance()->session()->ProvideSecret(
ConvertJavaStringToUTF8(env, pin).c_str(), createPair,
ConvertJavaStringToUTF8(env, deviceName));
}
static void ScheduleRedraw(JNIEnv* env, jclass clazz) {
remoting::ChromotingJniRuntime::GetInstance()->session()->RedrawDesktop();
}
static void SendMouseEvent(JNIEnv* env,
jclass clazz,
jint x,
jint y,
jint whichButton,
jboolean buttonDown) {
DCHECK(whichButton >= 0 && whichButton < 5);
remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseEvent(
x, y,
static_cast<remoting::protocol::MouseEvent_MouseButton>(whichButton),
buttonDown);
}
static void SendMouseWheelEvent(JNIEnv* env,
jclass clazz,
jint delta_x,
jint delta_y) {
remoting::ChromotingJniRuntime::GetInstance()->session()->SendMouseWheelEvent(
delta_x, delta_y);
}
static void SendKeyEvent(JNIEnv* env,
jclass clazz,
jint keyCode,
jboolean keyDown) {
remoting::ChromotingJniRuntime::GetInstance()->session()->SendKeyEvent(
keyCode, keyDown);
}
static void SendTextEvent(JNIEnv* env,
jclass clazz,
jstring text) {
remoting::ChromotingJniRuntime::GetInstance()->session()->SendTextEvent(
ConvertJavaStringToUTF8(env, text));
}
ChromotingJniRuntime* ChromotingJniRuntime::GetInstance() {
return Singleton<ChromotingJniRuntime>::get();
}
ChromotingJniRuntime::ChromotingJniRuntime() {
at_exit_manager_.reset(new base::AtExitManager());
ui_loop_.reset(new base::MessageLoopForUI());
ui_loop_->Start();
ui_task_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(),
base::MessageLoop::QuitClosure());
network_task_runner_ = AutoThread::CreateWithType("native_net",
ui_task_runner_,
base::MessageLoop::TYPE_IO);
display_task_runner_ = AutoThread::Create("native_disp",
ui_task_runner_);
url_requester_ = new URLRequestContextGetter(network_task_runner_);
media::InitializeCPUSpecificYUVConversions();
}
ChromotingJniRuntime::~ChromotingJniRuntime() {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DisconnectFromHost();
base::WaitableEvent done_event(false, false);
network_task_runner_->PostTask(FROM_HERE, base::Bind(
&ChromotingJniRuntime::DetachFromVmAndSignal,
base::Unretained(this),
&done_event));
done_event.Wait();
display_task_runner_->PostTask(FROM_HERE, base::Bind(
&ChromotingJniRuntime::DetachFromVmAndSignal,
base::Unretained(this),
&done_event));
done_event.Wait();
base::android::DetachFromVM();
}
void ChromotingJniRuntime::ConnectToHost(const char* username,
const char* auth_token,
const char* host_jid,
const char* host_id,
const char* host_pubkey,
const char* pairing_id,
const char* pairing_secret) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(!session_);
session_ = new ChromotingJniInstance(this,
username,
auth_token,
host_jid,
host_id,
host_pubkey,
pairing_id,
pairing_secret);
}
void ChromotingJniRuntime::DisconnectFromHost() {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
if (session_) {
session_->Cleanup();
session_ = NULL;
}
}
void ChromotingJniRuntime::ReportConnectionStatus(
protocol::ConnectionToHost::State state,
protocol::ErrorCode error) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
JNIEnv* env = base::android::AttachCurrentThread();
Java_JniInterface_reportConnectionStatus(env, state, error);
}
void ChromotingJniRuntime::DisplayAuthenticationPrompt(bool pairing_supported) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
JNIEnv* env = base::android::AttachCurrentThread();
Java_JniInterface_displayAuthenticationPrompt(env, pairing_supported);
}
void ChromotingJniRuntime::CommitPairingCredentials(const std::string& host,
const std::string& id,
const std::string& secret) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_host = ConvertUTF8ToJavaString(env, host);
ScopedJavaLocalRef<jbyteArray> j_id = ToJavaByteArray(
env, reinterpret_cast<const uint8*>(id.data()), id.size());
ScopedJavaLocalRef<jbyteArray> j_secret = ToJavaByteArray(
env, reinterpret_cast<const uint8*>(secret.data()), secret.size());
Java_JniInterface_commitPairingCredentials(
env, j_host.obj(), j_id.obj(), j_secret.obj());
}
base::android::ScopedJavaLocalRef<jobject> ChromotingJniRuntime::NewBitmap(
webrtc::DesktopSize size) {
JNIEnv* env = base::android::AttachCurrentThread();
return Java_JniInterface_newBitmap(env, size.width(), size.height());
}
void ChromotingJniRuntime::UpdateFrameBitmap(jobject bitmap) {
DCHECK(display_task_runner_->BelongsToCurrentThread());
JNIEnv* env = base::android::AttachCurrentThread();
Java_JniInterface_setVideoFrame(env, bitmap);
}
void ChromotingJniRuntime::UpdateCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {
DCHECK(display_task_runner_->BelongsToCurrentThread());
char* data = string_as_array(const_cast<std::string*>(&cursor_shape.data()));
int cursor_total_bytes =
cursor_shape.width() * cursor_shape.height() * kBytesPerPixel;
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> buffer(env,
env->NewDirectByteBuffer(data, cursor_total_bytes));
Java_JniInterface_updateCursorShape(env,
cursor_shape.width(),
cursor_shape.height(),
cursor_shape.hotspot_x(),
cursor_shape.hotspot_y(),
buffer.obj());
}
void ChromotingJniRuntime::RedrawCanvas() {
DCHECK(display_task_runner_->BelongsToCurrentThread());
JNIEnv* env = base::android::AttachCurrentThread();
Java_JniInterface_redrawGraphicsInternal(env);
}
void ChromotingJniRuntime::DetachFromVmAndSignal(base::WaitableEvent* waiter) {
base::android::DetachFromVM();
waiter->Signal();
}
}