| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |