OLD | NEW |
---|---|
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; | 9 import android.app.ProgressDialog; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 27 matching lines...) Expand all Loading... | |
38 | 38 |
39 /* | 39 /* |
40 * Library-loading state machine. | 40 * Library-loading state machine. |
41 */ | 41 */ |
42 /** Whether the library has been loaded. Accessed on the UI thread. */ | 42 /** Whether the library has been loaded. Accessed on the UI thread. */ |
43 private static boolean sLoaded = false; | 43 private static boolean sLoaded = false; |
44 | 44 |
45 /** The application context. Accessed on the UI thread. */ | 45 /** The application context. Accessed on the UI thread. */ |
46 private static Activity sContext = null; | 46 private static Activity sContext = null; |
47 | 47 |
48 /** Interface used for connection state notifications. */ | |
49 public interface ConnectionListener { | |
50 /** Notified on successful connection. */ | |
51 void onConnected(); | |
52 | |
53 /** | |
54 * Notified when the connection is disconnected due to host or network e rror. This is not | |
55 * called if disconnection is initiated by the client. | |
56 */ | |
57 void onDisconnected(); | |
Sergey Ulanov
2013/12/28 02:51:49
I think it's not enough to have just these two met
Lambros
2013/12/31 00:05:05
Done.
| |
58 } | |
59 | |
48 /* | 60 /* |
49 * Connection-initiating state machine. | 61 * Connection-initiating state machine. |
50 */ | 62 */ |
51 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ | 63 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ |
52 private static boolean sConnected = false; | 64 private static boolean sConnected = false; |
53 | 65 |
54 /** Callback to signal upon successful connection. Accessed on the UI thread . */ | 66 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */ |
55 private static Runnable sSuccessCallback = null; | 67 private static ConnectionListener sConnectionListener = null; |
56 | 68 |
57 /** Dialog for reporting connection progress. Accessed on the UI thread. */ | 69 /** Dialog for reporting connection progress. Accessed on the UI thread. */ |
58 private static ProgressDialog sProgressIndicator = null; | 70 private static ProgressDialog sProgressIndicator = null; |
59 | 71 |
60 // Protects access to |sProgressIndicator|. Used only to silence FindBugs wa rnings - the | 72 // Protects access to |sProgressIndicator|. Used only to silence FindBugs wa rnings - the |
61 // variable it protects is only accessed on a single thread. | 73 // variable it protects is only accessed on a single thread. |
62 // TODO(lambroslambrou): Refactor the ProgressIndicator into a separate clas s. | 74 // TODO(lambroslambrou): Refactor the ProgressIndicator into a separate clas s. |
63 private static Object sProgressIndicatorLock = new Object(); | 75 private static Object sProgressIndicatorLock = new Object(); |
64 | 76 |
65 /** | 77 /** |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 | 113 |
102 /* | 114 /* |
103 * API/OAuth2 keys access. | 115 * API/OAuth2 keys access. |
104 */ | 116 */ |
105 public static native String nativeGetApiKey(); | 117 public static native String nativeGetApiKey(); |
106 public static native String nativeGetClientId(); | 118 public static native String nativeGetClientId(); |
107 public static native String nativeGetClientSecret(); | 119 public static native String nativeGetClientSecret(); |
108 | 120 |
109 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ | 121 /** 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, | 122 public static void connectToHost(String username, String authToken, |
111 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { | 123 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) { |
112 disconnectFromHost(); | 124 disconnectFromHost(); |
113 | 125 |
114 sSuccessCallback = successCallback; | 126 sConnectionListener = listener; |
115 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; | 127 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; |
116 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, | 128 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, |
117 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); | 129 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); |
118 sConnected = true; | 130 sConnected = true; |
119 } | 131 } |
120 | 132 |
121 /** Performs the native portion of the connection. */ | 133 /** Performs the native portion of the connection. */ |
122 private static native void nativeConnect(String username, String authToken, String hostJid, | 134 private static native void nativeConnect(String username, String authToken, String hostJid, |
123 String hostId, String hostPubkey, String pairId, String pairSecret); | 135 String hostId, String hostPubkey, String pairId, String pairSecret); |
124 | 136 |
125 /** Severs the connection and cleans up. Called on the UI thread. */ | 137 /** Severs the connection and cleans up. Called on the UI thread. */ |
126 public static void disconnectFromHost() { | 138 public static void disconnectFromHost() { |
127 if (!sConnected) return; | 139 if (!sConnected) return; |
128 | 140 |
129 synchronized (sProgressIndicatorLock) { | 141 synchronized (sProgressIndicatorLock) { |
130 if (sProgressIndicator != null) { | 142 if (sProgressIndicator != null) { |
131 sProgressIndicator.dismiss(); | 143 sProgressIndicator.dismiss(); |
132 sProgressIndicator = null; | 144 sProgressIndicator = null; |
133 } | 145 } |
134 } | 146 } |
135 | 147 |
136 nativeDisconnect(); | 148 nativeDisconnect(); |
137 sSuccessCallback = null; | 149 sConnectionListener = null; |
138 sConnected = false; | 150 sConnected = false; |
139 | 151 |
140 // Drop the reference to free the Bitmap for GC. | 152 // Drop the reference to free the Bitmap for GC. |
141 synchronized (sFrameLock) { | 153 synchronized (sFrameLock) { |
142 sFrameBitmap = null; | 154 sFrameBitmap = null; |
143 } | 155 } |
144 } | 156 } |
145 | 157 |
146 /** Performs the native portion of the cleanup. */ | 158 /** Performs the native portion of the cleanup. */ |
147 private static native void nativeDisconnect(); | 159 private static native void nativeDisconnect(); |
148 | 160 |
149 /** Reports whenever the connection status changes. Called on the UI thread. */ | 161 /** Reports whenever the connection status changes. Called on the UI thread. */ |
150 @CalledByNative | 162 @CalledByNative |
151 private static void reportConnectionStatus(int state, int error) { | 163 private static void reportConnectionStatus(int state, int error) { |
152 if (state < SUCCESSFUL_CONNECTION && error == 0) { | 164 if (state < SUCCESSFUL_CONNECTION && error == 0) { |
153 // The connection is still being established, so we'll report the cu rrent progress. | 165 // The connection is still being established, so we'll report the cu rrent progress. |
154 synchronized (sProgressIndicatorLock) { | 166 synchronized (sProgressIndicatorLock) { |
155 if (sProgressIndicator == null) { | 167 if (sProgressIndicator == null) { |
156 sProgressIndicator = ProgressDialog.show(sContext, sContext. | 168 sProgressIndicator = ProgressDialog.show(sContext, sContext. |
Sergey Ulanov
2013/12/28 02:51:49
It's not right that the JNI layer handles UI. I th
Lambros
2013/12/31 00:05:05
Done.
| |
157 getString(R.string.progress_title), sContext.getReso urces(). | 169 getString(R.string.progress_title), sContext.getReso urces(). |
158 getStringArray(R.array.protoc_states)[state], true, true, | 170 getStringArray(R.array.protoc_states)[state], true, true, |
159 new DialogInterface.OnCancelListener() { | 171 new DialogInterface.OnCancelListener() { |
160 @Override | 172 @Override |
161 public void onCancel(DialogInterface dialog) { | 173 public void onCancel(DialogInterface dialog) { |
162 Log.i("jniiface", "User canceled connection initiation"); | 174 Log.i("jniiface", "User canceled connection initiation"); |
163 disconnectFromHost(); | 175 disconnectFromHost(); |
164 } | 176 } |
165 }); | 177 }); |
166 } else { | 178 } else { |
167 sProgressIndicator.setMessage( | 179 sProgressIndicator.setMessage( |
168 sContext.getResources().getStringArray(R.array.proto c_states)[state]); | 180 sContext.getResources().getStringArray(R.array.proto c_states)[state]); |
169 } | 181 } |
170 } | 182 } |
171 } else { | 183 } else { |
172 // The connection is complete or has failed, so we can lose the prog ress indicator. | 184 // The connection is complete or has failed, so we can lose the prog ress indicator. |
173 synchronized (sProgressIndicatorLock) { | 185 synchronized (sProgressIndicatorLock) { |
174 if (sProgressIndicator != null) { | 186 if (sProgressIndicator != null) { |
175 sProgressIndicator.dismiss(); | 187 sProgressIndicator.dismiss(); |
176 sProgressIndicator = null; | 188 sProgressIndicator = null; |
177 } | 189 } |
178 } | 190 } |
179 | 191 |
180 if (state == SUCCESSFUL_CONNECTION) { | 192 if (state == SUCCESSFUL_CONNECTION) { |
181 Toast.makeText(sContext, sContext.getResources(). | 193 Toast.makeText(sContext, sContext.getResources(). |
182 getStringArray(R.array.protoc_states)[state], Toast.LENG TH_SHORT).show(); | 194 getStringArray(R.array.protoc_states)[state], Toast.LENG TH_SHORT).show(); |
183 | 195 |
184 // Actually display the remote desktop. | 196 // Actually display the remote desktop. |
185 sSuccessCallback.run(); | 197 sConnectionListener.onConnected(); |
186 } else { | 198 } else { |
187 Toast.makeText(sContext, sContext.getResources().getStringArray( | 199 Toast.makeText(sContext, sContext.getResources().getStringArray( |
Sergey Ulanov
2013/12/28 02:51:49
Same here. JNI layer shouldn't handle UI. Let's mo
Lambros
2013/12/31 00:05:05
Done.
| |
188 R.array.protoc_states)[state] + (error == 0 ? "" : ": " + | 200 R.array.protoc_states)[state] + (error == 0 ? "" : ": " + |
189 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]), | 201 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]), |
190 Toast.LENGTH_LONG).show(); | 202 Toast.LENGTH_LONG).show(); |
203 sConnectionListener.onDisconnected(); | |
191 } | 204 } |
192 } | 205 } |
193 } | 206 } |
194 | 207 |
195 /** Prompts the user to enter a PIN. Called on the UI thread. */ | 208 /** Prompts the user to enter a PIN. Called on the UI thread. */ |
196 @CalledByNative | 209 @CalledByNative |
197 private static void displayAuthenticationPrompt(boolean pairingSupported) { | 210 private static void displayAuthenticationPrompt(boolean pairingSupported) { |
198 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); | 211 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); |
199 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); | 212 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); |
200 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); | 213 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 buffer.asIntBuffer().get(data, 0, data.length); | 405 buffer.asIntBuffer().get(data, 0, data.length); |
393 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); | 406 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); |
394 } | 407 } |
395 | 408 |
396 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ | 409 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ |
397 public static Point getCursorHotspot() { return sCursorHotspot; } | 410 public static Point getCursorHotspot() { return sCursorHotspot; } |
398 | 411 |
399 /** Returns the current cursor shape. Called on the graphics thread. */ | 412 /** Returns the current cursor shape. Called on the graphics thread. */ |
400 public static Bitmap getCursorBitmap() { return sCursorBitmap; } | 413 public static Bitmap getCursorBitmap() { return sCursorBitmap; } |
401 } | 414 } |
OLD | NEW |