Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/org/adblockplus/android/Preferences.java

Issue 8493083: ABP/Android UI (Closed)
Patch Set: Created Oct. 5, 2012, 9:42 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 package org.adblockplus.android;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.util.Calendar;
7 import java.util.Date;
8 import java.util.List;
9
10 import android.app.ActivityManager;
11 import android.app.ActivityManager.RunningServiceInfo;
12 import android.app.AlertDialog;
13 import android.content.BroadcastReceiver;
14 import android.content.Context;
15 import android.content.DialogInterface;
16 import android.content.DialogInterface.OnDismissListener;
17 import android.content.Intent;
18 import android.content.IntentFilter;
19 import android.content.SharedPreferences;
20 import android.content.pm.PackageManager.NameNotFoundException;
21 import android.content.res.AssetManager;
22 import android.net.Uri;
23 import android.os.Bundle;
24 import android.preference.CheckBoxPreference;
25 import android.preference.ListPreference;
26 import android.preference.PreferenceManager;
27 import android.text.format.DateFormat;
28 import android.util.Log;
29 import android.view.Menu;
30 import android.view.MenuInflater;
31 import android.view.MenuItem;
32 import android.view.View;
33 import android.view.Window;
34 import android.widget.TextView;
35
36 /**
37 * Main settings UI.
38 */
39 public class Preferences extends SummarizedPreferences
40 {
41 private final static String TAG = "Preferences";
Felix Dahlke 2012/10/09 14:27:29 As in AdvancedPreferences, "static final"?
Andrey Novikov 2012/10/12 13:19:14 Done.
42
43 private AboutDialog aboutDialog;
44 private boolean showAbout = false;
45 private String configurationMsg;
46 private String subscriptionSummary;
47
48 @Override
49 public void onCreate(Bundle savedInstanceState)
50 {
51 requestWindowFeature(Window.FEATURE_NO_TITLE);
52
53 super.onCreate(savedInstanceState);
54
55 PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
56 PreferenceManager.setDefaultValues(this, R.xml.preferences_advanced, false);
57 setContentView(R.layout.preferences);
58 addPreferencesFromResource(R.xml.preferences);
59
60 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this );
61
62 // Check if we need to update assets
63 int lastVersion = prefs.getInt(getString(R.string.pref_version), 0);
64 try
65 {
66 int thisVersion = getPackageManager().getPackageInfo(getPackageName(), 0). versionCode;
67 if (lastVersion != thisVersion)
68 {
69 copyAssets();
70 SharedPreferences.Editor editor = prefs.edit();
71 editor.putInt(getString(R.string.pref_version), thisVersion);
72 editor.commit();
73 }
74 }
75 catch (NameNotFoundException e)
76 {
77 copyAssets();
Felix Dahlke 2012/10/09 14:27:29 Why can this getPackageInfo fail while those in Ab
Andrey Novikov 2012/10/12 13:19:14 It can not. But I prefer to be reinsured in this c
78 }
79 }
80
81 @Override
82 protected void onStart()
83 {
84 super.onStart();
85 AdblockPlus application = AdblockPlus.getApplication();
86 application.startEngine();
87 application.startInteractive();
88 }
89
90 @Override
91 public void onResume()
Felix Dahlke 2012/10/09 14:27:29 Another long method, same comment as for AdvancedP
Andrey Novikov 2012/10/12 13:19:14 Same comment :) See code comments - they are for y
92 {
93 super.onResume();
94 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this );
95
96 final AdblockPlus application = AdblockPlus.getApplication();
97
98 // Construct subscription list
99 RefreshableListPreference subscriptionList = (RefreshableListPreference) fin dPreference(getString(R.string.pref_subscription));
100 List<Subscription> subscriptions = application.getSubscriptions();
101 String[] entries = new String[subscriptions.size()];
102 String[] entryValues = new String[subscriptions.size()];
103 String current = prefs.getString(getString(R.string.pref_subscription), (Str ing) null);
104 int i = 0;
105 for (Subscription subscription : subscriptions)
106 {
107 entries[i] = subscription.title;
108 entryValues[i] = subscription.url;
109 i++;
110 }
111 subscriptionList.setEntries(entries);
112 subscriptionList.setEntryValues(entryValues);
113
114 boolean firstRun = false;
115
116 // If there is no current subscription autoselect one
117 if (current == null)
118 {
119 firstRun = true;
120 Subscription offer = application.offerSubscription();
121 current = offer.url;
122 if (offer != null)
123 {
124 subscriptionList.setValue(offer.url);
125 application.setSubscription(offer);
126 new AlertDialog.Builder(this).setTitle(R.string.app_name).setMessage(Str ing.format(getString(R.string.msg_subscription_offer, offer.title))).setIcon(and roid.R.drawable.ic_dialog_info)
127 .setPositiveButton(R.string.ok, null).create().show();
128 }
129 }
130
131 // Enable manual subscription refresh
132 subscriptionList.setOnRefreshClickListener(new View.OnClickListener() {
Felix Dahlke 2012/10/09 14:27:29 Brace on its own line please.
Andrey Novikov 2012/10/12 13:19:14 Done.
133 @Override
134 public void onClick(View v)
135 {
136 application.refreshSubscription();
137 }
138 });
139
140 // Set subscription status message
141 if (subscriptionSummary != null)
142 subscriptionList.setSummary(subscriptionSummary);
143 else
144 setPrefSummary(subscriptionList);
145
146 // Time to start listening for events
147 registerReceiver(receiver, new IntentFilter(AdblockPlus.BROADCAST_SUBSCRIPTI ON_STATUS));
148 registerReceiver(receiver, new IntentFilter(AdblockPlus.BROADCAST_FILTER_MAT CHES));
149 registerReceiver(receiver, new IntentFilter(ProxyService.BROADCAST_STATE_CHA NGED));
150 registerReceiver(receiver, new IntentFilter(ProxyService.BROADCAST_PROXY_FAI LED));
151
152 final String url = current;
153
154 // Initialize subscription verification
155 (new Thread() {
Felix Dahlke 2012/10/09 14:27:29 Brace on its own line please.
Andrey Novikov 2012/10/12 13:19:14 Done.
156 @Override
157 public void run()
158 {
159 if (!application.verifySubscriptions())
160 {
161 Subscription subscription = application.getSubscription(url);
162 application.setSubscription(subscription);
163 }
164 }
165 }).start();
166
167 // Check if service is running and update UI accordingly
168 boolean enabled = prefs.getBoolean(getString(R.string.pref_enabled), false);
169 if (enabled && !isServiceRunning())
170 {
171 setEnabled(false);
172 enabled = false;
Felix Dahlke 2012/10/09 14:27:29 enabled isn't read past this point, Setting it to
Andrey Novikov 2012/10/12 13:19:14 Done.
173 }
174 // Run service if this is first application run
175 else if (!enabled && firstRun)
176 {
177 startService(new Intent(this, ProxyService.class));
178 setEnabled(true);
179 }
180
181 // Process screen rotation
182 if (configurationMsg != null)
183 showConfigurationMsg(configurationMsg);
184
185 if (showAbout)
186 onAbout(findViewById(R.id.btn_about));
187 }
188
189 @Override
190 public void onPause()
191 {
192 super.onPause();
193 unregisterReceiver(receiver);
194 }
195
196 @Override
197 protected void onStop()
198 {
199 super.onStop();
200 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this );
201 boolean enabled = prefs.getBoolean(getString(R.string.pref_enabled), false);
202 AdblockPlus application = AdblockPlus.getApplication();
203 application.stopInteractive();
204 if (!enabled)
205 application.stopEngine(true);
206
207 if (aboutDialog != null)
208 aboutDialog.dismiss();
209 }
210
211 @Override
212 public boolean onCreateOptionsMenu(Menu menu)
213 {
214 MenuInflater inflater = getMenuInflater();
215 inflater.inflate(R.menu.menu_preferences, menu);
216 return true;
217 }
218
219 @Override
220 public boolean onOptionsItemSelected(MenuItem item)
221 {
222 switch (item.getItemId())
223 {
224 case R.id.menu_advanced:
225 startActivity(new Intent(this, AdvancedPreferences.class));
226 return true;
227 default:
228 return super.onOptionsItemSelected(item);
229 }
230 }
231
232 private void setEnabled(boolean enabled)
233 {
234 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferen ces(this).edit();
235 editor.putBoolean(getString(R.string.pref_enabled), enabled);
236 editor.commit();
237 ((CheckBoxPreference) findPreference(getString(R.string.pref_enabled))).setC hecked(enabled);
238 }
239
240 /**
241 * Checks if ProxyService is running.
242 *
243 * @return true if service is running
244 */
245 private boolean isServiceRunning()
246 {
247 ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVIC E);
248 // Actually it returns not only running services, so extra check is required
249 for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VAL UE))
250 {
251 if ("org.adblockplus.android.ProxyService".equals(service.service.getClass Name()) && service.pid > 0)
252 return true;
253 }
254 return false;
255 }
256
257 /**
258 * Copies file assets from installation package to filesystem.
259 */
260 private void copyAssets()
261 {
262 AssetManager assetManager = getAssets();
263 String[] files = null;
264 try
265 {
266 files = assetManager.list("install");
267 }
268 catch (IOException e)
269 {
270 Log.e(TAG, e.getMessage());
Felix Dahlke 2012/10/09 14:27:29 Why not pass e as the third parameter, like below?
Andrey Novikov 2012/10/12 13:19:14 Done.
271 }
272 for (int i = 0; i < files.length; i++)
273 {
274 InputStream in = null;
Felix Dahlke 2012/10/09 14:27:29 in and out can be declared in the try block, they
Andrey Novikov 2012/10/12 13:19:14 Done.
275 OutputStream out = null;
276 try
277 {
278 Log.d(TAG, "Copy: install/" + files[i]);
279 in = assetManager.open("install/" + files[i]);
280 out = openFileOutput(files[i], MODE_PRIVATE);
281 byte[] buffer = new byte[1024];
282 int read;
283 while ((read = in.read(buffer)) != -1)
284 {
285 out.write(buffer, 0, read);
286 }
287 in.close();
288 in = null;
Felix Dahlke 2012/10/09 14:27:29 You don't need to set in/out to null, they aren't
Andrey Novikov 2012/10/12 13:19:14 Done.
289 out.flush();
290 out.close();
291 out = null;
292
293 }
294 catch (Exception e)
295 {
296 Log.e(TAG, "Asset copy error", e);
297 }
298 }
299 }
300
301 /**
302 * Redirects user to configuration URL.
303 */
304 public void onHelp(View view)
305 {
306 Uri uri = Uri.parse(getString(R.string.configuring_url));
307 final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
Felix Dahlke 2012/10/09 14:27:29 Why make intent final?
Andrey Novikov 2012/10/12 13:19:14 No reason, just copied url opening code from sampl
308 startActivity(intent);
309 }
310
311 /**
312 * Shows about dialog.
313 */
314 public void onAbout(View view)
315 {
316 aboutDialog = new AboutDialog(this);
317 aboutDialog.setOnDismissListener(new OnDismissListener() {
318
319 @Override
320 public void onDismiss(DialogInterface dialog)
321 {
322 showAbout = false;
Felix Dahlke 2012/10/09 14:27:29 Naming nit pick: This sounds imperative, how about
Andrey Novikov 2012/10/12 13:19:14 For me name is correct - it flags if have to show
323 aboutDialog = null;
324 }
325 });
326 showAbout = true;
327 aboutDialog.show();
328 }
329
330 @Override
331 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Str ing key)
332 {
333 if (getString(R.string.pref_enabled).equals(key))
334 {
335 boolean enabled = sharedPreferences.getBoolean(key, false);
336 if (enabled && !isServiceRunning())
337 startService(new Intent(this, ProxyService.class));
338 else if (!enabled && isServiceRunning())
Felix Dahlke 2012/10/09 14:27:29 I'd feel safer is isServiceRunning() was called ju
Andrey Novikov 2012/10/12 13:19:14 Done.
339 stopService(new Intent(this, ProxyService.class));
340 }
341 if (getString(R.string.pref_subscription).equals(key))
342 {
343 String current = sharedPreferences.getString(key, null);
344 AdblockPlus application = AdblockPlus.getApplication();
345 Subscription subscription = application.getSubscription(current);
346 application.setSubscription(subscription);
347 }
348 super.onSharedPreferenceChanged(sharedPreferences, key);
349 }
350
351 private void showConfigurationMsg(String message)
352 {
353 TextView msg = (TextView) findViewById(R.id.txt_configuration);
354 msg.setText(message);
355 msg.setVisibility(View.VISIBLE);
356 configurationMsg = message;
357 }
358
359 private void hideConfigurationMsg()
360 {
361 if (configurationMsg == null)
362 return;
363 TextView msg = (TextView) findViewById(R.id.txt_configuration);
364 msg.setVisibility(View.GONE);
365 configurationMsg = null;
366 }
367
368 private BroadcastReceiver receiver = new BroadcastReceiver() {
Felix Dahlke 2012/10/09 14:27:29 Brace on a new line please.
Andrey Novikov 2012/10/12 13:19:14 Done.
369 @Override
370 public void onReceive(final Context context, Intent intent)
Felix Dahlke 2012/10/09 14:27:29 Why make context final?
Andrey Novikov 2012/10/12 13:19:14 It was previously used in a new thread, fixed.
371 {
372 String action = intent.getAction();
373 Bundle extra = intent.getExtras();
374 if (action.equals(ProxyService.BROADCAST_STATE_CHANGED))
375 {
376 if (extra.getBoolean("enabled"))
377 {
378 // If service is enabled in manual mode, show configuration message
379 if (extra.getBoolean("manual"))
380 {
381 showConfigurationMsg(getString(R.string.msg_configuration, extra.get Int("port")));
382 }
383 }
384 else
385 {
386 setEnabled(false);
387 hideConfigurationMsg();
388 }
389 }
390 if (action.equals(AdblockPlus.BROADCAST_FILTER_MATCHES))
391 {
392 // Hide configuration message if traffic is detected
393 hideConfigurationMsg();
394 }
395 if (action.equals(ProxyService.BROADCAST_PROXY_FAILED))
396 {
397 String msg = extra.getString("msg");
398 new AlertDialog.Builder(Preferences.this).setTitle(R.string.error).setMe ssage(msg).setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton(R.strin g.ok, null).create().show();
399 setEnabled(false);
400 }
401 if (action.equals(AdblockPlus.BROADCAST_SUBSCRIPTION_STATUS))
402 {
403 final String text = extra.getString("text");
404 final long time = extra.getLong("time");
405 runOnUiThread(new Runnable() {
406 public void run()
407 {
408 setSubscriptionStatus(text, time);
409 }
410 });
411 }
412 }
413 };
414
415 /**
416 * Constructs and updates subscription status text.
417 *
418 * @param text
419 * status message
420 * @param time
421 * time of last change
422 */
423 private void setSubscriptionStatus(String text, long time)
424 {
425 ListPreference subscriptionList = (ListPreference) findPreference(getString( R.string.pref_subscription));
426 CharSequence summary = subscriptionList.getEntry();
427 StringBuilder builder = new StringBuilder();
428 if (summary != null)
429 {
430 builder.append(summary);
431 if (text != "")
432 {
433 builder.append(" (");
434 int id = getResources().getIdentifier(text, "string", getPackageName());
435 if (id > 0)
436 builder.append(getString(id, text));
437 else
438 builder.append(text);
439 if (time > 0)
440 {
441 builder.append(": ");
442 Calendar calendar = Calendar.getInstance();
443 calendar.setTimeInMillis(time);
444 Date date = calendar.getTime();
445 builder.append(DateFormat.getDateFormat(this).format(date));
446 builder.append(" ");
447 builder.append(DateFormat.getTimeFormat(this).format(date));
448 }
449 builder.append(")");
450 }
451 subscriptionSummary = builder.toString();
452 subscriptionList.setSummary(subscriptionSummary);
453 }
454 }
455
456 @Override
457 protected void onRestoreInstanceState(Bundle state)
458 {
459 super.onRestoreInstanceState(state);
460 showAbout = state.getBoolean("showAbout");
461 configurationMsg = state.getString("configurationMsg");
462 subscriptionSummary = state.getString("subscriptionSummary");
463 }
464
465 @Override
466 protected void onSaveInstanceState(Bundle outState)
467 {
468 outState.putString("subscriptionSummary", subscriptionSummary);
469 outState.putString("configurationMsg", configurationMsg);
470 outState.putBoolean("showAbout", showAbout);
471 super.onSaveInstanceState(outState);
472 }
473 }
OLDNEW

Powered by Google App Engine
This is Rietveld