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

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: Use Java enum for state/error codes 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 * This enum must match the C++ enumeration remoting::protocol::Connecti onToHost::State.
48 */
49 public enum State {
50 INITIALIZING(0),
51 CONNECTING(1),
52 AUTHENTICATED(2),
53 CONNECTED(3),
54 FAILED(4),
55 CLOSED(5);
56
57 private final int mValue;
58
59 State(int value) {
60 mValue = value;
61 }
62
63 public int value() {
64 return mValue;
65 }
66
67 public static State fromValue(int value) {
68 return values()[value];
69 }
70 }
71
72 /**
73 * This enum must match the C++ enumeration remoting::protocol::ErrorCod e.
74 */
75 public enum Error {
76 OK(0),
77 PEER_IS_OFFLINE(1),
78 SESSION_REJECTED(2),
79 INCOMPATIBLE_PROTOCOL(3),
80 AUTHENTICATION_FAILED(4),
81 CHANNEL_CONNECTION_ERROR(5),
82 SIGNALING_ERROR(6),
83 SIGNALING_TIMEOUT(7),
84 HOST_OVERLOAD(8),
85 UNKNOWN_ERROR(9);
86
87 private final int mValue;
88
89 Error(int value) {
90 mValue = value;
91 }
92
93 public int value() {
94 return mValue;
95 }
96
97 public static Error fromValue(int value) {
98 return values()[value];
99 }
100 }
101
102 /**
103 * Notified on connection state change.
104 * @param state The new connection state.
105 * @param error The error code, if state is STATE_FAILED.
106 */
107 void onConnectionState(State state, Error error);
108 }
109
48 /* 110 /*
49 * Connection-initiating state machine. 111 * Connection-initiating state machine.
50 */ 112 */
51 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ 113 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */
52 private static boolean sConnected = false; 114 private static boolean sConnected = false;
53 115
54 /** Callback to signal upon successful connection. Accessed on the UI thread . */ 116 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */
55 private static Runnable sSuccessCallback = null; 117 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 118
65 /** 119 /**
66 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and 120 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and
67 * graphics threads. 121 * graphics threads.
68 */ 122 */
69 private static Runnable sRedrawCallback = null; 123 private static Runnable sRedrawCallback = null;
70 124
71 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ 125 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */
72 private static Bitmap sFrameBitmap = null; 126 private static Bitmap sFrameBitmap = null;
73 127
(...skipping 27 matching lines...) Expand all
101 155
102 /* 156 /*
103 * API/OAuth2 keys access. 157 * API/OAuth2 keys access.
104 */ 158 */
105 public static native String nativeGetApiKey(); 159 public static native String nativeGetApiKey();
106 public static native String nativeGetClientId(); 160 public static native String nativeGetClientId();
107 public static native String nativeGetClientSecret(); 161 public static native String nativeGetClientSecret();
108 162
109 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ 163 /** 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, 164 public static void connectToHost(String username, String authToken,
111 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { 165 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) {
112 disconnectFromHost(); 166 disconnectFromHost();
113 167
114 sSuccessCallback = successCallback; 168 sConnectionListener = listener;
115 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; 169 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ;
116 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, 170 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
117 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); 171 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""));
118 sConnected = true; 172 sConnected = true;
119 } 173 }
120 174
121 /** Performs the native portion of the connection. */ 175 /** Performs the native portion of the connection. */
122 private static native void nativeConnect(String username, String authToken, String hostJid, 176 private static native void nativeConnect(String username, String authToken, String hostJid,
123 String hostId, String hostPubkey, String pairId, String pairSecret); 177 String hostId, String hostPubkey, String pairId, String pairSecret);
124 178
125 /** Severs the connection and cleans up. Called on the UI thread. */ 179 /** Severs the connection and cleans up. Called on the UI thread. */
126 public static void disconnectFromHost() { 180 public static void disconnectFromHost() {
127 if (!sConnected) return; 181 if (!sConnected) return;
128 182
129 synchronized (sProgressIndicatorLock) { 183 sConnectionListener.onConnectionState(ConnectionListener.State.CLOSED,
130 if (sProgressIndicator != null) { 184 ConnectionListener.Error.OK);
131 sProgressIndicator.dismiss();
132 sProgressIndicator = null;
133 }
134 }
135 185
136 nativeDisconnect(); 186 nativeDisconnect();
137 sSuccessCallback = null; 187 sConnectionListener = null;
138 sConnected = false; 188 sConnected = false;
139 189
140 // Drop the reference to free the Bitmap for GC. 190 // Drop the reference to free the Bitmap for GC.
141 synchronized (sFrameLock) { 191 synchronized (sFrameLock) {
142 sFrameBitmap = null; 192 sFrameBitmap = null;
143 } 193 }
144 } 194 }
145 195
146 /** Performs the native portion of the cleanup. */ 196 /** Performs the native portion of the cleanup. */
147 private static native void nativeDisconnect(); 197 private static native void nativeDisconnect();
148 198
149 /** Reports whenever the connection status changes. Called on the UI thread. */ 199 /** Reports whenever the connection status changes. Called on the UI thread. */
150 @CalledByNative 200 @CalledByNative
151 private static void reportConnectionStatus(int state, int error) { 201 private static void reportConnectionStatus(int state, int error) {
152 if (state < SUCCESSFUL_CONNECTION && error == 0) { 202 sConnectionListener.onConnectionState(ConnectionListener.State.fromValue (state),
153 // The connection is still being established, so we'll report the cu rrent progress. 203 ConnectionListener.Error.fromValue(error));
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 } 204 }
194 205
195 /** Prompts the user to enter a PIN. Called on the UI thread. */ 206 /** Prompts the user to enter a PIN. Called on the UI thread. */
196 @CalledByNative 207 @CalledByNative
197 private static void displayAuthenticationPrompt(boolean pairingSupported) { 208 private static void displayAuthenticationPrompt(boolean pairingSupported) {
198 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 209 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext);
199 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); 210 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title));
200 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); 211 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message));
201 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); 212 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
202 213
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 buffer.asIntBuffer().get(data, 0, data.length); 403 buffer.asIntBuffer().get(data, 0, data.length);
393 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); 404 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
394 } 405 }
395 406
396 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ 407 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */
397 public static Point getCursorHotspot() { return sCursorHotspot; } 408 public static Point getCursorHotspot() { return sCursorHotspot; }
398 409
399 /** Returns the current cursor shape. Called on the graphics thread. */ 410 /** Returns the current cursor shape. Called on the graphics thread. */
400 public static Bitmap getCursorBitmap() { return sCursorBitmap; } 411 public static Bitmap getCursorBitmap() { return sCursorBitmap; }
401 } 412 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698