Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(680)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java

Issue 105943010: Android Chromoting - Close the Desktop view on disconnection (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add enum constants to Java Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting.jni; 5 package org.chromium.chromoting.jni;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.app.AlertDialog; 8 import android.app.AlertDialog;
9 import android.app.ProgressDialog;
10 import android.content.Context; 9 import android.content.Context;
11 import android.content.DialogInterface; 10 import android.content.DialogInterface;
12 import android.content.SharedPreferences; 11 import android.content.SharedPreferences;
13 import android.graphics.Bitmap; 12 import android.graphics.Bitmap;
14 import android.graphics.Point; 13 import android.graphics.Point;
15 import android.os.Looper; 14 import android.os.Looper;
16 import android.util.Log; 15 import android.util.Log;
17 import android.view.KeyEvent; 16 import android.view.KeyEvent;
18 import android.view.View; 17 import android.view.View;
19 import android.widget.CheckBox; 18 import android.widget.CheckBox;
20 import android.widget.TextView; 19 import android.widget.TextView;
21 import android.widget.Toast; 20 import android.widget.Toast;
22 21
23 import org.chromium.base.CalledByNative; 22 import org.chromium.base.CalledByNative;
24 import org.chromium.base.JNINamespace; 23 import org.chromium.base.JNINamespace;
25 import org.chromium.chromoting.R; 24 import org.chromium.chromoting.R;
26 25
27 import java.nio.ByteBuffer; 26 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder; 27 import java.nio.ByteOrder;
29 28
30 /** 29 /**
31 * Initializes the Chromium remoting library, and provides JNI calls into it. 30 * Initializes the Chromium remoting library, and provides JNI calls into it.
32 * All interaction with the native code is centralized in this class. 31 * All interaction with the native code is centralized in this class.
33 */ 32 */
34 @JNINamespace("remoting") 33 @JNINamespace("remoting")
35 public class JniInterface { 34 public class JniInterface {
36 /** The status code indicating successful connection. */
37 private static final int SUCCESSFUL_CONNECTION = 3;
38
39 /* 35 /*
40 * Library-loading state machine. 36 * Library-loading state machine.
41 */ 37 */
42 /** Whether the library has been loaded. Accessed on the UI thread. */ 38 /** Whether the library has been loaded. Accessed on the UI thread. */
43 private static boolean sLoaded = false; 39 private static boolean sLoaded = false;
44 40
45 /** The application context. Accessed on the UI thread. */ 41 /** The application context. Accessed on the UI thread. */
46 private static Activity sContext = null; 42 private static Activity sContext = null;
47 43
44 /** Interface used for connection state notifications. */
45 public interface ConnectionListener {
46 /**
47 * These values must match the C++ enumeration remoting::protocol::Conne ctionToHost::State.
48 */
49 int STATE_INITIALIZING = 0;
Sergey Ulanov 2014/01/08 20:30:45 Can we use Java enums here? In the past it was rec
Lambros 2014/01/08 22:30:01 Done.
50 int STATE_CONNECTING = 1;
51 int STATE_AUTHENTICATED = 2;
52 int STATE_CONNECTED = 3;
53 int STATE_FAILED = 4;
54 int STATE_CLOSED = 5;
55
56 /**
57 * These values must match the C++ enumeration remoting::protocol::Error Code.
58 */
59 int ERROR_OK = 0;
60 int ERROR_PEER_IS_OFFLINE = 1;
61 int ERROR_SESSION_REJECTED = 2;
62 int ERROR_INCOMPATIBLE_PROTOCOL = 3;
63 int ERROR_AUTHENTICATION_FAILED = 4;
64 int ERROR_CHANNEL_CONNECTION_ERROR = 5;
65 int ERROR_SIGNALING_ERROR = 6;
66 int ERROR_SIGNALING_TIMEOUT = 7;
67 int ERROR_HOST_OVERLOAD = 8;
68 int ERROR_UNKNOWN_ERROR = 9;
69
70 /**
71 * Notified on connection state change.
72 * @param state The new connection state.
73 * @param error The error code, if state is STATE_FAILED.
74 */
75 void onConnectionState(int state, int error);
76 }
77
48 /* 78 /*
49 * Connection-initiating state machine. 79 * Connection-initiating state machine.
50 */ 80 */
51 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ 81 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */
52 private static boolean sConnected = false; 82 private static boolean sConnected = false;
53 83
54 /** Callback to signal upon successful connection. Accessed on the UI thread . */ 84 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */
55 private static Runnable sSuccessCallback = null; 85 private static ConnectionListener sConnectionListener = null;
56
57 /** Dialog for reporting connection progress. Accessed on the UI thread. */
58 private static ProgressDialog sProgressIndicator = null;
59
60 // Protects access to |sProgressIndicator|. Used only to silence FindBugs wa rnings - the
61 // variable it protects is only accessed on a single thread.
62 // TODO(lambroslambrou): Refactor the ProgressIndicator into a separate clas s.
63 private static Object sProgressIndicatorLock = new Object();
64 86
65 /** 87 /**
66 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and 88 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and
67 * graphics threads. 89 * graphics threads.
68 */ 90 */
69 private static Runnable sRedrawCallback = null; 91 private static Runnable sRedrawCallback = null;
70 92
71 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ 93 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */
72 private static Bitmap sFrameBitmap = null; 94 private static Bitmap sFrameBitmap = null;
73 95
(...skipping 27 matching lines...) Expand all
101 123
102 /* 124 /*
103 * API/OAuth2 keys access. 125 * API/OAuth2 keys access.
104 */ 126 */
105 public static native String nativeGetApiKey(); 127 public static native String nativeGetApiKey();
106 public static native String nativeGetClientId(); 128 public static native String nativeGetClientId();
107 public static native String nativeGetClientSecret(); 129 public static native String nativeGetClientSecret();
108 130
109 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ 131 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */
110 public static void connectToHost(String username, String authToken, 132 public static void connectToHost(String username, String authToken,
111 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { 133 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) {
112 disconnectFromHost(); 134 disconnectFromHost();
113 135
114 sSuccessCallback = successCallback; 136 sConnectionListener = listener;
115 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; 137 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ;
116 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, 138 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
117 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); 139 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""));
118 sConnected = true; 140 sConnected = true;
119 } 141 }
120 142
121 /** Performs the native portion of the connection. */ 143 /** Performs the native portion of the connection. */
122 private static native void nativeConnect(String username, String authToken, String hostJid, 144 private static native void nativeConnect(String username, String authToken, String hostJid,
123 String hostId, String hostPubkey, String pairId, String pairSecret); 145 String hostId, String hostPubkey, String pairId, String pairSecret);
124 146
125 /** Severs the connection and cleans up. Called on the UI thread. */ 147 /** Severs the connection and cleans up. Called on the UI thread. */
126 public static void disconnectFromHost() { 148 public static void disconnectFromHost() {
127 if (!sConnected) return; 149 if (!sConnected) return;
128 150
129 synchronized (sProgressIndicatorLock) { 151 sConnectionListener.onConnectionState(ConnectionListener.STATE_CLOSED, 0 );
130 if (sProgressIndicator != null) {
131 sProgressIndicator.dismiss();
132 sProgressIndicator = null;
133 }
134 }
135 152
136 nativeDisconnect(); 153 nativeDisconnect();
137 sSuccessCallback = null; 154 sConnectionListener = null;
138 sConnected = false; 155 sConnected = false;
139 156
140 // Drop the reference to free the Bitmap for GC. 157 // Drop the reference to free the Bitmap for GC.
141 synchronized (sFrameLock) { 158 synchronized (sFrameLock) {
142 sFrameBitmap = null; 159 sFrameBitmap = null;
143 } 160 }
144 } 161 }
145 162
146 /** Performs the native portion of the cleanup. */ 163 /** Performs the native portion of the cleanup. */
147 private static native void nativeDisconnect(); 164 private static native void nativeDisconnect();
148 165
149 /** Reports whenever the connection status changes. Called on the UI thread. */ 166 /** Reports whenever the connection status changes. Called on the UI thread. */
150 @CalledByNative 167 @CalledByNative
151 private static void reportConnectionStatus(int state, int error) { 168 private static void reportConnectionStatus(int state, int error) {
152 if (state < SUCCESSFUL_CONNECTION && error == 0) { 169 sConnectionListener.onConnectionState(state, error);
153 // The connection is still being established, so we'll report the cu rrent progress.
154 synchronized (sProgressIndicatorLock) {
155 if (sProgressIndicator == null) {
156 sProgressIndicator = ProgressDialog.show(sContext, sContext.
157 getString(R.string.progress_title), sContext.getReso urces().
158 getStringArray(R.array.protoc_states)[state], true, true,
159 new DialogInterface.OnCancelListener() {
160 @Override
161 public void onCancel(DialogInterface dialog) {
162 Log.i("jniiface", "User canceled connection initiation");
163 disconnectFromHost();
164 }
165 });
166 } else {
167 sProgressIndicator.setMessage(
168 sContext.getResources().getStringArray(R.array.proto c_states)[state]);
169 }
170 }
171 } else {
172 // The connection is complete or has failed, so we can lose the prog ress indicator.
173 synchronized (sProgressIndicatorLock) {
174 if (sProgressIndicator != null) {
175 sProgressIndicator.dismiss();
176 sProgressIndicator = null;
177 }
178 }
179
180 if (state == SUCCESSFUL_CONNECTION) {
181 Toast.makeText(sContext, sContext.getResources().
182 getStringArray(R.array.protoc_states)[state], Toast.LENG TH_SHORT).show();
183
184 // Actually display the remote desktop.
185 sSuccessCallback.run();
186 } else {
187 Toast.makeText(sContext, sContext.getResources().getStringArray(
188 R.array.protoc_states)[state] + (error == 0 ? "" : ": " +
189 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]),
190 Toast.LENGTH_LONG).show();
191 }
192 }
193 } 170 }
194 171
195 /** Prompts the user to enter a PIN. Called on the UI thread. */ 172 /** Prompts the user to enter a PIN. Called on the UI thread. */
196 @CalledByNative 173 @CalledByNative
197 private static void displayAuthenticationPrompt(boolean pairingSupported) { 174 private static void displayAuthenticationPrompt(boolean pairingSupported) {
198 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 175 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext);
199 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); 176 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title));
200 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); 177 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message));
201 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); 178 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
202 179
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 buffer.asIntBuffer().get(data, 0, data.length); 369 buffer.asIntBuffer().get(data, 0, data.length);
393 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); 370 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
394 } 371 }
395 372
396 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ 373 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */
397 public static Point getCursorHotspot() { return sCursorHotspot; } 374 public static Point getCursorHotspot() { return sCursorHotspot; }
398 375
399 /** Returns the current cursor shape. Called on the graphics thread. */ 376 /** Returns the current cursor shape. Called on the graphics thread. */
400 public static Bitmap getCursorBitmap() { return sCursorBitmap; } 377 public static Bitmap getCursorBitmap() { return sCursorBitmap; }
401 } 378 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698