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

Side by Side Diff: blimp/client/app/android/java/src/org/chromium/blimp/BlimpRendererActivity.java

Issue 2493333002: Move Java Blimp shell code to app subpackage (Closed)
Patch Set: Merge branch 'refs/heads/master' into blimp-shell-integration Created 4 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.blimp;
6
7 import android.annotation.SuppressLint;
8 import android.app.Activity;
9 import android.content.Intent;
10 import android.os.Bundle;
11 import android.os.Handler;
12 import android.text.TextUtils;
13 import android.view.View;
14 import android.widget.TextView;
15
16 import org.chromium.base.CommandLine;
17 import org.chromium.base.Log;
18 import org.chromium.base.annotations.SuppressFBWarnings;
19 import org.chromium.base.library_loader.ProcessInitException;
20 import org.chromium.blimp.auth.RetryingTokenSource;
21 import org.chromium.blimp.auth.TokenSource;
22 import org.chromium.blimp.auth.TokenSourceImpl;
23 import org.chromium.blimp.core.BlimpClientSwitches;
24 import org.chromium.blimp.preferences.PreferencesUtil;
25 import org.chromium.blimp.session.BlimpClientSession;
26 import org.chromium.blimp.session.EngineInfo;
27 import org.chromium.blimp.session.TabControlFeature;
28 import org.chromium.blimp.toolbar.Toolbar;
29 import org.chromium.blimp.toolbar.ToolbarMenu;
30 import org.chromium.ui.base.WindowAndroid;
31 import org.chromium.ui.widget.Toast;
32
33 /**
34 * The {@link Activity} for rendering the main Blimp client. This loads the Bli mp rendering stack
35 * and displays it.
36 */
37 public class BlimpRendererActivity
38 extends Activity implements BlimpLibraryLoader.Callback, TokenSource.Cal lback,
39 BlimpClientSession.ConnectionObserver,
40 ToolbarMenu.ToolbarMenuDelegate, Toolbar.Too lbarDelegate {
41 private static final int ACCOUNT_CHOOSER_INTENT_REQUEST_CODE = 100;
42 private static final String TAG = "BlimpRendererActivity";
43
44 // Refresh interval for the debug view in milliseconds.
45 private static final int DEBUG_VIEW_REFRESH_INTERVAL = 1000;
46 private static final int BYTES_PER_KILO = 1024;
47
48 /** Provides user authentication tokens that can be used to query for engine assignments. This
49 * can potentially query GoogleAuthUtil for an OAuth2 authentication token with userinfo.email
50 * privileges for a chosen Android account. */
51 private TokenSource mTokenSource;
52
53 private BlimpView mBlimpView;
54 private Toolbar mToolbar;
55 private BlimpClientSession mBlimpClientSession;
56 private TabControlFeature mTabControlFeature;
57 private WindowAndroid mWindowAndroid;
58
59 private Handler mHandler = new Handler();
60
61 private boolean mFirstUrlLoadDone = false;
62
63 // Flag to record the base value of the metrics when the debug view is turne d on.
64 private boolean mStatsBaseRecorded = false;
65 private int mSentBase;
66 private int mReceivedBase;
67 private int mCommitsBase;
68 private int mSent;
69 private int mReceived;
70 private int mCommits;
71 private String mToken = null;
72
73 @Override
74 @SuppressFBWarnings("DM_EXIT") // FindBugs doesn't like System.exit().
75 protected void onCreate(Bundle savedInstanceState) {
76 super.onCreate(savedInstanceState);
77 buildAndTriggerTokenSourceIfNeeded();
78 try {
79 BlimpLibraryLoader.startAsync(this);
80 } catch (ProcessInitException e) {
81 Log.e(TAG, "Native startup exception", e);
82 System.exit(-1);
83 return;
84 }
85 }
86
87 @Override
88 protected void onDestroy() {
89 if (mTabControlFeature != null) {
90 mTabControlFeature.destroy();
91 mTabControlFeature = null;
92 }
93
94 if (mBlimpView != null) {
95 mBlimpView.destroyRenderer();
96 mBlimpView = null;
97 }
98
99 if (mToolbar != null) {
100 mToolbar.destroy();
101 mToolbar = null;
102 }
103
104 if (mTokenSource != null) {
105 mTokenSource.destroy();
106 mTokenSource = null;
107 }
108
109 // Destroy the BlimpClientSession last, as all other features may rely o n it.
110 if (mBlimpClientSession != null) {
111 mBlimpClientSession.removeObserver(this);
112 mBlimpClientSession.destroy();
113 mBlimpClientSession = null;
114 }
115
116 super.onDestroy();
117 }
118
119 @Override
120 protected void onActivityResult(int requestCode, int resultCode, Intent data ) {
121 switch (requestCode) {
122 case ACCOUNT_CHOOSER_INTENT_REQUEST_CODE:
123 if (resultCode == RESULT_OK) {
124 mTokenSource.onAccountSelected(data);
125 mTokenSource.getToken();
126 } else {
127 onTokenUnavailable(false);
128 }
129 break;
130 default:
131 break;
132 }
133 }
134
135 @Override
136 public void onBackPressed() {
137 // Check if the toolbar can handle the back navigation.
138 if (mToolbar != null && mToolbar.onBackPressed()) return;
139
140 // If not, use the default Activity behavior.
141 super.onBackPressed();
142 }
143
144 // BlimpLibraryLoader.Callback implementation.
145 @Override
146 public void onStartupComplete(boolean success) {
147 if (!success) {
148 Log.e(TAG, "Native startup failed");
149 finish();
150 return;
151 }
152
153 setContentView(R.layout.blimp_main);
154
155 mWindowAndroid = new WindowAndroid(BlimpRendererActivity.this);
156 mBlimpClientSession =
157 new BlimpClientSession(PreferencesUtil.findAssignerUrl(this), mW indowAndroid);
158 mBlimpClientSession.addObserver(this);
159
160 mBlimpView = (BlimpView) findViewById(R.id.renderer);
161 mBlimpView.initializeRenderer(mBlimpClientSession);
162
163 mToolbar = (Toolbar) findViewById(R.id.toolbar);
164 mToolbar.initialize(mBlimpClientSession, this);
165
166 mTabControlFeature = new TabControlFeature(mBlimpClientSession, mBlimpVi ew);
167
168 handleUrlFromIntent(getIntent());
169
170 // If Blimp client has command line flag "engine-ip", client will use th e command line token
171 // to connect. See GetAssignmentFromCommandLine() in
172 // blimp/client/session/assignment_source.cc
173 // In normal cases, where client uses the engine ip given by the Assigne r,
174 // connection to the engine is triggered by the successful retrieval of a token as
175 // TokenSource.Callback.
176 if (CommandLine.getInstance().hasSwitch(BlimpClientSwitches.ENGINE_IP)) {
177 mBlimpClientSession.connect(null);
178 } else {
179 if (mToken != null) {
180 mBlimpClientSession.connect(mToken);
181 mToken = null;
182 }
183 }
184 }
185
186 // ToolbarMenu.ToolbarMenuDelegate implementation.
187 @Override
188 public void showDebugView(boolean show) {
189 View debugView = findViewById(R.id.debug_stats);
190 debugView.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
191 if (show) {
192 Runnable debugStatsRunnable = new Runnable() {
193 @Override
194 public void run() {
195 if (mToolbar.getToolbarMenu().isDebugInfoEnabled()) {
196 int[] metrics = mBlimpClientSession.getDebugStats();
197 updateDebugStats(metrics);
198 mHandler.postDelayed(this, DEBUG_VIEW_REFRESH_INTERVAL);
199 }
200 }
201 };
202 debugStatsRunnable.run();
203 } else {
204 mStatsBaseRecorded = false;
205 }
206 }
207
208 @Override
209 protected void onNewIntent(Intent intent) {
210 super.onNewIntent(intent);
211 handleUrlFromIntent(intent);
212 }
213
214 /**
215 * Retrieve the URL from the Intent.
216 * @param intent Intent to examine.
217 * @return URL from the Intent, or null if a valid URL couldn't be found.
218 */
219 private String getUrlFromIntent(Intent intent) {
220 if (intent == null) return null;
221
222 String url = intent.getDataString();
223 if (url == null) return null;
224
225 url = url.trim();
226 return TextUtils.isEmpty(url) ? null : url;
227 }
228
229 /**
230 * Retrieves an URL from an Intent and loads it in the browser.
231 * If the toolbar already has an URL and the new intent doesn't have an URL (e.g. bringing back
232 * from background), the intent gets ignored.
233 * @param intent Intent that contains the URL.
234 */
235 private void handleUrlFromIntent(Intent intent) {
236 // TODO(shaktisahu): On a slow device, this might happen. Load the corre ct URL once the
237 // toolbar loading is complete (crbug/601226)
238 if (mToolbar == null) return;
239
240 String url = getUrlFromIntent(intent);
241 if (mFirstUrlLoadDone && url == null) return;
242 mFirstUrlLoadDone = true;
243
244 mToolbar.loadUrl(url == null ? "http://www.google.com/" : url);
245 }
246
247 // TokenSource.Callback implementation.
248 @Override
249 public void onTokenReceived(String token) {
250 if (mBlimpClientSession != null) {
251 mBlimpClientSession.connect(token);
252 } else {
253 mToken = token;
254 }
255 }
256
257 @Override
258 public void onTokenUnavailable(boolean isTransient) {
259 // Ignore isTransient here because we're relying on the auto-retry Token Source.
260 // TODO(dtrainor): Show a better error dialog/message.
261 Toast.makeText(this, R.string.signin_get_token_failed, Toast.LENGTH_LONG ).show();
262 }
263
264 @Override
265 public void onNeedsAccountToBeSelected(Intent suggestedIntent) {
266 startActivityForResult(suggestedIntent, ACCOUNT_CHOOSER_INTENT_REQUEST_C ODE);
267 }
268
269 // BlimpClientSession.ConnectionObserver interface.
270 @Override
271 public void onAssignmentReceived(
272 int result, int suggestedMessageResourceId, EngineInfo engineInfo) {
273 Toast.makeText(this, suggestedMessageResourceId, Toast.LENGTH_LONG).show ();
274 }
275
276 @Override
277 public void onConnected() {
278 Toast.makeText(this, R.string.network_connected, Toast.LENGTH_SHORT).sho w();
279 }
280
281 /**
282 * Displays debug metrics up to one decimal place.
283 */
284 @Override
285 @SuppressLint("DefaultLocale")
286 public void updateDebugStatsUI(int received, int sent, int commits) {
287 TextView tv = (TextView) findViewById(R.id.bytes_received_client);
288 tv.setText(String.format("%.1f", (float) received / BYTES_PER_KILO));
289 tv = (TextView) findViewById(R.id.bytes_sent_client);
290 tv.setText(String.format("%.1f", (float) sent / BYTES_PER_KILO));
291 tv = (TextView) findViewById(R.id.commit_count);
292 tv.setText(String.valueOf(commits));
293 }
294
295 private void updateDebugStats(int[] metrics) {
296 assert metrics.length == 3;
297 mReceived = metrics[0];
298 mSent = metrics[1];
299 mCommits = metrics[2];
300 if (!mStatsBaseRecorded) {
301 mReceivedBase = mReceived;
302 mSentBase = mSent;
303 mCommitsBase = mCommits;
304 mStatsBaseRecorded = true;
305 }
306 updateDebugStatsUI(mReceived - mReceivedBase, mSent - mSentBase, mCommit s - mCommitsBase);
307 }
308
309 // Toolbar.ToolbarDelegate interface.
310 @Override
311 public void resetDebugStats() {
312 mReceivedBase = mReceived;
313 mSentBase = mSent;
314 mCommitsBase = mCommits;
315 }
316
317 @Override
318 public void onDisconnected(String reason) {
319 Toast.makeText(this,
320 String.format(getResources().getString(R.string.network_dis connected), reason),
321 Toast.LENGTH_LONG)
322 .show();
323 }
324
325 private void buildAndTriggerTokenSourceIfNeeded() {
326 // If Blimp client is given the engine ip by the command line, then ther e is no need to
327 // build a TokenSource, because token, engine ip, engine port, and trans port protocol are
328 // all given by command line.
329 if (CommandLine.getInstance().hasSwitch(BlimpClientSwitches.ENGINE_IP)) return;
330
331 // Build a TokenSource that will internally retry accessing the underlyi ng
332 // TokenSourceImpl. This will exponentially backoff while it tries to ge t the access
333 // token. See {@link RetryingTokenSource} for more information. The un derlying
334 // TokenSourceImpl will attempt to query GoogleAuthUtil, but might fail if there is no
335 // account selected, in which case it will ask this Activity to show an account chooser
336 // and notify it of the selection result.
337 mTokenSource = new RetryingTokenSource(new TokenSourceImpl(this));
338 mTokenSource.setCallback(this);
339 mTokenSource.getToken();
340 }
341 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698