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

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: Move connection status UI out of JniInterface 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 * The status code indicating successful connection. States less than th is indicate
48 * stages of establishing a connection. States greater than this indicat e disconnection
Sergey Ulanov 2014/01/03 00:01:51 Why not declare constant for all states, not only
Lambros 2014/01/04 01:59:46 Done.
49 * or connection failure. These constants must match the corresponding C ++ enumeration.
50 */
51 int SUCCESSFUL_CONNECTION = 3;
52
53 /** The status code indicating disconnection. */
54 int CONNECTION_CLOSED = 5;
55
56 /**
57 * Notified on connection state change.
58 * @param state The new connection state, as defined in the C++ enumerat ion
59 * remoting::protocol::ConnectionToHost::State.
60 * @param error The error code, as defined in the C++ enumeration
61 * remoting::protocol::ErrorCode.
62 */
63 void onConnectionState(int state, int error);
Sergey Ulanov 2014/01/03 00:01:51 Also please copy enum values for the errors from r
Lambros 2014/01/04 01:59:46 Second argument is used in an array lookup, loaded
64 }
65
48 /* 66 /*
49 * Connection-initiating state machine. 67 * Connection-initiating state machine.
50 */ 68 */
51 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ 69 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */
52 private static boolean sConnected = false; 70 private static boolean sConnected = false;
53 71
54 /** Callback to signal upon successful connection. Accessed on the UI thread . */ 72 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */
55 private static Runnable sSuccessCallback = null; 73 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 74
65 /** 75 /**
66 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and 76 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and
67 * graphics threads. 77 * graphics threads.
68 */ 78 */
69 private static Runnable sRedrawCallback = null; 79 private static Runnable sRedrawCallback = null;
70 80
71 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ 81 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */
72 private static Bitmap sFrameBitmap = null; 82 private static Bitmap sFrameBitmap = null;
73 83
(...skipping 27 matching lines...) Expand all
101 111
102 /* 112 /*
103 * API/OAuth2 keys access. 113 * API/OAuth2 keys access.
104 */ 114 */
105 public static native String nativeGetApiKey(); 115 public static native String nativeGetApiKey();
106 public static native String nativeGetClientId(); 116 public static native String nativeGetClientId();
107 public static native String nativeGetClientSecret(); 117 public static native String nativeGetClientSecret();
108 118
109 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ 119 /** 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, 120 public static void connectToHost(String username, String authToken,
111 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { 121 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) {
112 disconnectFromHost(); 122 disconnectFromHost();
113 123
114 sSuccessCallback = successCallback; 124 sConnectionListener = listener;
115 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; 125 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ;
116 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, 126 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
117 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); 127 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""));
118 sConnected = true; 128 sConnected = true;
119 } 129 }
120 130
121 /** Performs the native portion of the connection. */ 131 /** Performs the native portion of the connection. */
122 private static native void nativeConnect(String username, String authToken, String hostJid, 132 private static native void nativeConnect(String username, String authToken, String hostJid,
123 String hostId, String hostPubkey, String pairId, String pairSecret); 133 String hostId, String hostPubkey, String pairId, String pairSecret);
124 134
125 /** Severs the connection and cleans up. Called on the UI thread. */ 135 /** Severs the connection and cleans up. Called on the UI thread. */
126 public static void disconnectFromHost() { 136 public static void disconnectFromHost() {
127 if (!sConnected) return; 137 if (!sConnected) return;
128 138
129 synchronized (sProgressIndicatorLock) { 139 sConnectionListener.onConnectionState(ConnectionListener.CONNECTION_CLOS ED, 0);
130 if (sProgressIndicator != null) {
131 sProgressIndicator.dismiss();
132 sProgressIndicator = null;
133 }
134 }
135 140
136 nativeDisconnect(); 141 nativeDisconnect();
137 sSuccessCallback = null; 142 sConnectionListener = null;
138 sConnected = false; 143 sConnected = false;
139 144
140 // Drop the reference to free the Bitmap for GC. 145 // Drop the reference to free the Bitmap for GC.
141 synchronized (sFrameLock) { 146 synchronized (sFrameLock) {
142 sFrameBitmap = null; 147 sFrameBitmap = null;
143 } 148 }
144 } 149 }
145 150
146 /** Performs the native portion of the cleanup. */ 151 /** Performs the native portion of the cleanup. */
147 private static native void nativeDisconnect(); 152 private static native void nativeDisconnect();
148 153
149 /** Reports whenever the connection status changes. Called on the UI thread. */ 154 /** Reports whenever the connection status changes. Called on the UI thread. */
150 @CalledByNative 155 @CalledByNative
151 private static void reportConnectionStatus(int state, int error) { 156 private static void reportConnectionStatus(int state, int error) {
152 if (state < SUCCESSFUL_CONNECTION && error == 0) { 157 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 } 158 }
194 159
195 /** Prompts the user to enter a PIN. Called on the UI thread. */ 160 /** Prompts the user to enter a PIN. Called on the UI thread. */
196 @CalledByNative 161 @CalledByNative
197 private static void displayAuthenticationPrompt(boolean pairingSupported) { 162 private static void displayAuthenticationPrompt(boolean pairingSupported) {
198 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 163 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext);
199 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); 164 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title));
200 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); 165 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message));
201 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); 166 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
202 167
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 buffer.asIntBuffer().get(data, 0, data.length); 357 buffer.asIntBuffer().get(data, 0, data.length);
393 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); 358 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
394 } 359 }
395 360
396 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ 361 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */
397 public static Point getCursorHotspot() { return sCursorHotspot; } 362 public static Point getCursorHotspot() { return sCursorHotspot; }
398 363
399 /** Returns the current cursor shape. Called on the graphics thread. */ 364 /** Returns the current cursor shape. Called on the graphics thread. */
400 public static Bitmap getCursorBitmap() { return sCursorBitmap; } 365 public static Bitmap getCursorBitmap() { return sCursorBitmap; }
401 } 366 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698