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

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

Issue 5327480814567424: Issue 1108 - Support notifications (Closed)
Patch Set: Removed unused import, cleaned up formatting." Created Feb. 17, 2015, 1:54 p.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
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener 52 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener
53 { 53 {
54 private static final String TAG = Utils.getTag(ProxyService.class); 54 private static final String TAG = Utils.getTag(ProxyService.class);
55 55
56 private static final String LOCALHOST = "127.0.0.1"; 56 private static final String LOCALHOST = "127.0.0.1";
57 57
58 private static final int[] PORT_VARIANTS = new int[] {-1, 2020, 3030, 4040, 50 50, 6060, 7070, 9090, 1234, 12345, 4321, 0}; 58 private static final int[] PORT_VARIANTS = new int[] {-1, 2020, 3030, 4040, 50 50, 6060, 7070, 9090, 1234, 12345, 4321, 0};
59 59
60 private static final boolean LOG_REQUESTS = false; 60 private static final boolean LOG_REQUESTS = false;
61 61
62 static final int ONGOING_NOTIFICATION_ID = R.string.app_name;
63
64 private static final long POSITION_RIGHT = Build.VERSION.SDK_INT >= Build.VERS ION_CODES.GINGERBREAD ? Long.MIN_VALUE : Long.MAX_VALUE; 62 private static final long POSITION_RIGHT = Build.VERSION.SDK_INT >= Build.VERS ION_CODES.GINGERBREAD ? Long.MIN_VALUE : Long.MAX_VALUE;
65 63
66 /** 64 /**
67 * This flag indicates that this mobile device runs an Android version that al lows the user to configure a http(s) proxy. 65 * This flag indicates that this mobile device runs an Android version that al lows the user to configure a http(s) proxy.
68 */ 66 */
69 public static final boolean GLOBAL_PROXY_USER_CONFIGURABLE = Build.VERSION.SDK _INT >= 12; // Honeycomb 3.1 67 public static final boolean GLOBAL_PROXY_USER_CONFIGURABLE = Build.VERSION.SDK _INT >= 12; // Honeycomb 3.1
70 68
71 /** 69 /**
72 * Broadcasted when service starts or stops. 70 * Broadcasted when service starts or stops.
73 */ 71 */
74 public static final String BROADCAST_STATE_CHANGED = "org.adblockplus.android. SERVICE_STATE_CHANGED"; 72 public static final String BROADCAST_STATE_CHANGED = "org.adblockplus.android. SERVICE_STATE_CHANGED";
75 73
76 /** 74 /**
77 * Broadcasted if proxy fails to start. 75 * Broadcasted if proxy fails to start.
78 */ 76 */
79 public static final String BROADCAST_PROXY_FAILED = "org.adblockplus.android.P ROXY_FAILURE"; 77 public static final String BROADCAST_PROXY_FAILED = "org.adblockplus.android.P ROXY_FAILURE";
80 78
81 /** 79 /**
82 * Common command bridge 80 * Proxy state changed
83 */ 81 */
84 public static final String PROXY_STATE_CHANGED_ACTION = "org.adblockplus.andro id.PROXY_STATE_CHANGED"; 82 public static final String PROXY_STATE_CHANGED_ACTION = "org.adblockplus.andro id.PROXY_STATE_CHANGED";
85 83
86 boolean hideIcon; 84 boolean hideIcon;
87 85
88 protected ProxyServer proxy = null; 86 protected ProxyServer proxy = null;
89 87
90 protected int port; 88 protected int port;
91 89
92 private final Properties proxyConfiguration = new Properties(); 90 private final Properties proxyConfiguration = new Properties();
93 91
94 private ProxyConfigurator proxyConfigurator = null; 92 private ProxyConfigurator proxyConfigurator = null;
95 93
94 private NotificationWatcher notificationWatcher = null;
95
96 @SuppressLint("NewApi") 96 @SuppressLint("NewApi")
97 @Override 97 @Override
98 public void onCreate() 98 public void onCreate()
99 { 99 {
100 super.onCreate(); 100 super.onCreate();
101 101
102 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 102 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
103 .permitAll() 103 .permitAll()
104 .penaltyLog() 104 .penaltyLog()
105 .build()); 105 .build());
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 proxy = new ProxyServer(); 213 proxy = new ProxyServer();
214 proxy.logLevel = Server.LOG_LOG; 214 proxy.logLevel = Server.LOG_LOG;
215 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration); 215 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration);
216 proxy.start(); 216 proxy.start();
217 } 217 }
218 218
219 prefs.registerOnSharedPreferenceChangeListener(this); 219 prefs.registerOnSharedPreferenceChangeListener(this);
220 220
221 // Lock service 221 // Lock service
222 hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), getResources( ).getBoolean(R.bool.def_hideicon)); 222 hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), getResources( ).getBoolean(R.bool.def_hideicon));
223 startForeground(ONGOING_NOTIFICATION_ID, getNotification()); 223 startForeground(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotification());
224 224
225 sendStateChangedBroadcast(); 225 sendStateChangedBroadcast();
226
227 this.startNotificationWatcher();
228
226 Log.i(TAG, "Service started"); 229 Log.i(TAG, "Service started");
227 } 230 }
228 231
229 @Override 232 @Override
230 public int onStartCommand(final Intent intent, final int flags, final int star tId) 233 public int onStartCommand(final Intent intent, final int flags, final int star tId)
231 { 234 {
232 return START_STICKY; 235 return START_STICKY;
233 } 236 }
234 237
235 @Override 238 @Override
236 public void onDestroy() 239 public void onDestroy()
237 { 240 {
238 super.onDestroy(); 241 super.onDestroy();
239 242
243 this.stopNotificationWatcher();
244
240 unregisterReceiver(this.proxyReceiver); 245 unregisterReceiver(this.proxyReceiver);
241 unregisterReceiver(this.proxyStateChangedReceiver); 246 unregisterReceiver(this.proxyStateChangedReceiver);
242 247
243 if (this.proxyConfigurator != null) 248 if (this.proxyConfigurator != null)
244 { 249 {
245 this.proxyConfigurator.unregisterProxy(); 250 this.proxyConfigurator.unregisterProxy();
246 this.proxyConfigurator.shutdown(); 251 this.proxyConfigurator.shutdown();
247 } 252 }
248 253
249 sendBroadcast(new Intent(BROADCAST_STATE_CHANGED).putExtra("enabled", false) ); 254 sendBroadcast(new Intent(BROADCAST_STATE_CHANGED).putExtra("enabled", false) );
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 builder.setContentText(getString(msgId, port)); 498 builder.setContentText(getString(msgId, port));
494 builder.setOngoing(true); 499 builder.setOngoing(true);
495 500
496 return builder.getNotification(); 501 return builder.getNotification();
497 } 502 }
498 503
499 public void setEmptyIcon(final boolean hide) 504 public void setEmptyIcon(final boolean hide)
500 { 505 {
501 hideIcon = hide; 506 hideIcon = hide;
502 final NotificationManager notificationManager = (NotificationManager) getSys temService(NOTIFICATION_SERVICE); 507 final NotificationManager notificationManager = (NotificationManager) getSys temService(NOTIFICATION_SERVICE);
503 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification()); 508 notificationManager.notify(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotificat ion());
504 } 509 }
505 510
506 public void sendStateChangedBroadcast() 511 public void sendStateChangedBroadcast()
507 { 512 {
508 final boolean manual = isManual(); 513 final boolean manual = isManual();
509 final Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED) 514 final Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED)
510 .putExtra("enabled", true) 515 .putExtra("enabled", true)
511 .putExtra("port", port) 516 .putExtra("port", port)
512 .putExtra("manual", manual); 517 .putExtra("manual", manual);
513 518
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 * </p> 561 * </p>
557 */ 562 */
558 private final BroadcastReceiver proxyStateChangedReceiver = new BroadcastRecei ver() 563 private final BroadcastReceiver proxyStateChangedReceiver = new BroadcastRecei ver()
559 { 564 {
560 @Override 565 @Override
561 public void onReceive(final Context context, final Intent intent) 566 public void onReceive(final Context context, final Intent intent)
562 { 567 {
563 if (intent != null && PROXY_STATE_CHANGED_ACTION.equals(intent.getAction() )) 568 if (intent != null && PROXY_STATE_CHANGED_ACTION.equals(intent.getAction() ))
564 { 569 {
565 final NotificationManager notificationManager = (NotificationManager) ge tSystemService(NOTIFICATION_SERVICE); 570 final NotificationManager notificationManager = (NotificationManager) ge tSystemService(NOTIFICATION_SERVICE);
566 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification()); 571 notificationManager.notify(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotif ication());
567 ProxyService.this.sendStateChangedBroadcast(); 572 ProxyService.this.sendStateChangedBroadcast();
568 } 573 }
569 } 574 }
570 }; 575 };
571 576
572 final class ProxyServer extends Server 577 final class ProxyServer extends Server
573 { 578 {
574 @Override 579 @Override
575 public void close() 580 public void close()
576 { 581 {
(...skipping 12 matching lines...) Expand all
589 594
590 @Override 595 @Override
591 public void log(final int level, final Object obj, final String message) 596 public void log(final int level, final Object obj, final String message)
592 { 597 {
593 if (level <= logLevel) 598 if (level <= logLevel)
594 { 599 {
595 Log.println(7 - level, obj != null ? obj.toString() : TAG, message); 600 Log.println(7 - level, obj != null ? obj.toString() : TAG, message);
596 } 601 }
597 } 602 }
598 } 603 }
604
605 private void startNotificationWatcher()
606 {
607 this.stopNotificationWatcher();
608
609 this.notificationWatcher = new NotificationWatcher(this);
610
611 final Thread thread = new Thread(this.notificationWatcher);
612 thread.setDaemon(true);
613 thread.start();
614 }
615
616 private void stopNotificationWatcher()
617 {
618 if (this.notificationWatcher != null)
619 {
620 this.notificationWatcher.stop();
621 this.notificationWatcher = null;
622 }
623 }
624
625 private static class NotificationWatcher implements Runnable
Felix Dahlke 2015/02/18 12:49:56 This seems to be way too much code for what we wan
René Jeschke 2015/02/18 13:13:02 AlarmManager: Why use a system-wide, scheduling se
Felix Dahlke 2015/02/18 14:10:07 Well, if this doesn't work reliably on the EDT, fa
626 {
627 public static final int DEFAULT_FIRST_POLL_INTERVAL = 3 * 60; /* seconds */
628 public static final int DEFAULT_NEXT_POLL_INTERVALS = 0; /* seconds */
629
630 private final ProxyService proxyService;
631 private final int firstPollInterval;
Felix Dahlke 2015/02/18 14:10:07 How about initialDelay? It's not really an interva
René Jeschke 2015/02/18 14:45:20 Done.
632 private final int nextPollIntervals;
Felix Dahlke 2015/02/18 14:10:07 Assuming firstPollInterval is renamed, this could
René Jeschke 2015/02/18 14:45:20 Done.
633
634 volatile boolean running = true;
635
636 public NotificationWatcher(final ProxyService proxyService, final int firstP ollInterval,
637 final int nextPollIntervals)
638 {
639 this.proxyService = proxyService;
640 this.firstPollInterval = Math.max(0, firstPollInterval);
641 this.nextPollIntervals = Math.max(0, nextPollIntervals);
642 }
643
644 public NotificationWatcher(final ProxyService proxyService)
645 {
646 this(proxyService, DEFAULT_FIRST_POLL_INTERVAL, DEFAULT_NEXT_POLL_INTERVAL S);
647 }
648
649 protected void stop()
650 {
651 this.running = false;
652 }
653
654 @Override
655 public void run()
656 {
657 if (this.firstPollInterval == 0)
658 {
659 this.running = false;
660 return;
661 }
662
663 long nextPoll = System.currentTimeMillis() + 1000L * this.firstPollInterva l;
664
665 while (this.running)
666 {
667 try
668 {
669 Thread.sleep(250);
670 }
671 catch (InterruptedException ex)
672 {
673 break;
674 }
675
676 if (System.currentTimeMillis() >= nextPoll && this.running)
677 {
678 try
679 {
680 Log.d(TAG, "Polling for notifications");
681 org.adblockplus.libadblockplus.Notification notification = AdblockPl us.getApplication()
682 .getNotificationToShow();
683
684 int idx = 0;
685 while (notification != null)
Felix Dahlke 2015/02/18 14:10:07 We should actually just show a single notification
René Jeschke 2015/02/18 14:45:20 It is guaranteed that there aren't any two notific
Felix Dahlke 2015/02/18 14:55:04 There can be an arbitrary number of notifications
686 {
687 Notification notif = new NotificationCompat.Builder(
688 this.proxyService.getApplicationContext())
Felix Dahlke 2015/02/18 14:10:07 Shouldn't we pass the app's context here rather th
René Jeschke 2015/02/18 14:45:20 I still am working on the service separation. The
689 .setSmallIcon(R.drawable.ic_stat_blocking)
690 .setContentTitle(notification.getTitle())
691 .setContentText(notification.getMessageString())
692 .getNotification();
693
694 final NotificationManager notificationManager = (NotificationManag er) this.proxyService
695 .getSystemService(NOTIFICATION_SERVICE);
696 notificationManager.notify(AdblockPlus.GROUPED_NOTIFICATION_ID + i dx, notif);
697
698 notification.markAsShown();
Felix Dahlke 2015/02/18 14:10:07 We actually only need to call this for question no
René Jeschke 2015/02/18 14:45:20 Ah, Ok. I thought this has something to do with 'f
699
700 idx++;
701 notification = AdblockPlus.getApplication().getNotificationToShow( );
702 }
703
704 Log.d(TAG, "Received " + idx + " new notifications");
705 }
706 catch (Exception ex)
707 {
708 Log.e(TAG, "Polling for notifications failed: " + ex.getMessage(), e x);
709 }
710
711 if (this.nextPollIntervals == 0)
712 {
713 this.running = false;
714 }
715 else
716 {
717 nextPoll = System.currentTimeMillis() + 1000L * this.nextPollInterva ls;
718 }
719 }
720 }
721 }
722 }
599 } 723 }
OLDNEW

Powered by Google App Engine
This is Rietveld