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

Delta Between Two Patch Sets: src/org/adblockplus/android/ProxyService.java

Issue 5327480814567424: Issue 1108 - Support notifications (Closed)
Left Patch Set: Created Jan. 30, 2015, 12:44 p.m.
Right Patch Set: Only one Notification displayed now Created Feb. 18, 2015, 3:42 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/org/adblockplus/android/CrashHandler.java ('k') | src/org/adblockplus/android/Utils.java » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 package org.adblockplus.android; 18 package org.adblockplus.android;
19 19
20 import java.io.IOException; 20 import java.io.IOException;
21 import java.net.InetAddress; 21 import java.net.InetAddress;
22 import java.net.ServerSocket; 22 import java.net.ServerSocket;
23 import java.net.UnknownHostException; 23 import java.net.UnknownHostException;
24 import java.util.Properties; 24 import java.util.Properties;
25 25
26 import org.adblockplus.android.configurators.ProxyConfigurator; 26 import org.adblockplus.android.configurators.ProxyConfigurator;
27 import org.adblockplus.android.configurators.ProxyConfigurators; 27 import org.adblockplus.android.configurators.ProxyConfigurators;
28 import org.adblockplus.android.configurators.ProxyRegistrationType; 28 import org.adblockplus.android.configurators.ProxyRegistrationType;
29 import org.adblockplus.libadblockplus.Notification.Type;
29 import org.apache.commons.lang.StringUtils; 30 import org.apache.commons.lang.StringUtils;
30 31
31 import sunlabs.brazil.server.Server; 32 import sunlabs.brazil.server.Server;
32 import sunlabs.brazil.util.Base64; 33 import sunlabs.brazil.util.Base64;
33 import android.annotation.SuppressLint; 34 import android.annotation.SuppressLint;
34 import android.app.Notification; 35 import android.app.Notification;
35 import android.app.NotificationManager; 36 import android.app.NotificationManager;
36 import android.app.PendingIntent; 37 import android.app.PendingIntent;
37 import android.app.Service; 38 import android.app.Service;
38 import android.content.BroadcastReceiver; 39 import android.content.BroadcastReceiver;
(...skipping 13 matching lines...) Expand all
52 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener 53 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener
53 { 54 {
54 private static final String TAG = Utils.getTag(ProxyService.class); 55 private static final String TAG = Utils.getTag(ProxyService.class);
55 56
56 private static final String LOCALHOST = "127.0.0.1"; 57 private static final String LOCALHOST = "127.0.0.1";
57 58
58 private static final int[] PORT_VARIANTS = new int[] {-1, 2020, 3030, 4040, 50 50, 6060, 7070, 9090, 1234, 12345, 4321, 0}; 59 private static final int[] PORT_VARIANTS = new int[] {-1, 2020, 3030, 4040, 50 50, 6060, 7070, 9090, 1234, 12345, 4321, 0};
59 60
60 private static final boolean LOG_REQUESTS = false; 61 private static final boolean LOG_REQUESTS = false;
61 62
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; 63 private static final long POSITION_RIGHT = Build.VERSION.SDK_INT >= Build.VERS ION_CODES.GINGERBREAD ? Long.MIN_VALUE : Long.MAX_VALUE;
65 64
66 /** 65 /**
67 * This flag indicates that this mobile device runs an Android version that al lows the user to configure a http(s) proxy. 66 * This flag indicates that this mobile device runs an Android version that al lows the user to configure a http(s) proxy.
68 */ 67 */
69 public static final boolean GLOBAL_PROXY_USER_CONFIGURABLE = Build.VERSION.SDK _INT >= 12; // Honeycomb 3.1 68 public static final boolean GLOBAL_PROXY_USER_CONFIGURABLE = Build.VERSION.SDK _INT >= 12; // Honeycomb 3.1
70 69
71 /** 70 /**
72 * Broadcasted when service starts or stops. 71 * Broadcasted when service starts or stops.
73 */ 72 */
74 public static final String BROADCAST_STATE_CHANGED = "org.adblockplus.android. SERVICE_STATE_CHANGED"; 73 public static final String BROADCAST_STATE_CHANGED = "org.adblockplus.android. SERVICE_STATE_CHANGED";
75 74
76 /** 75 /**
77 * Broadcasted if proxy fails to start. 76 * Broadcasted if proxy fails to start.
78 */ 77 */
79 public static final String BROADCAST_PROXY_FAILED = "org.adblockplus.android.P ROXY_FAILURE"; 78 public static final String BROADCAST_PROXY_FAILED = "org.adblockplus.android.P ROXY_FAILURE";
80 79
81 /** 80 /**
82 * Common command bridge 81 * Proxy state changed
83 */ 82 */
84 public static final String PROXY_STATE_CHANGED_ACTION = "org.adblockplus.andro id.PROXY_STATE_CHANGED"; 83 public static final String PROXY_STATE_CHANGED_ACTION = "org.adblockplus.andro id.PROXY_STATE_CHANGED";
85 84
86 boolean hideIcon; 85 boolean hideIcon;
87 86
88 protected ProxyServer proxy = null; 87 protected ProxyServer proxy = null;
89 88
90 protected int port; 89 protected int port;
91 90
92 private final Properties proxyConfiguration = new Properties(); 91 private final Properties proxyConfiguration = new Properties();
93 92
94 private ProxyConfigurator proxyConfigurator = null; 93 private ProxyConfigurator proxyConfigurator = null;
94
95 private NotificationWatcher notificationWatcher = null;
95 96
96 @SuppressLint("NewApi") 97 @SuppressLint("NewApi")
97 @Override 98 @Override
98 public void onCreate() 99 public void onCreate()
99 { 100 {
100 super.onCreate(); 101 super.onCreate();
101 102
102 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 103 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
103 .permitAll() 104 .permitAll()
104 .penaltyLog() 105 .penaltyLog()
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 proxy = new ProxyServer(); 214 proxy = new ProxyServer();
214 proxy.logLevel = Server.LOG_LOG; 215 proxy.logLevel = Server.LOG_LOG;
215 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration); 216 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration);
216 proxy.start(); 217 proxy.start();
217 } 218 }
218 219
219 prefs.registerOnSharedPreferenceChangeListener(this); 220 prefs.registerOnSharedPreferenceChangeListener(this);
220 221
221 // Lock service 222 // Lock service
222 hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), getResources( ).getBoolean(R.bool.def_hideicon)); 223 hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), getResources( ).getBoolean(R.bool.def_hideicon));
223 startForeground(ONGOING_NOTIFICATION_ID, getNotification()); 224 startForeground(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotification());
224 225
225 sendStateChangedBroadcast(); 226 sendStateChangedBroadcast();
227
228 this.startNotificationWatcher();
229
226 Log.i(TAG, "Service started"); 230 Log.i(TAG, "Service started");
227 } 231 }
228 232
229 @Override 233 @Override
230 public int onStartCommand(final Intent intent, final int flags, final int star tId) 234 public int onStartCommand(final Intent intent, final int flags, final int star tId)
231 { 235 {
232 return START_STICKY; 236 return START_STICKY;
233 } 237 }
234 238
235 @Override 239 @Override
236 public void onDestroy() 240 public void onDestroy()
237 { 241 {
238 super.onDestroy(); 242 super.onDestroy();
243
244 this.stopNotificationWatcher();
239 245
240 unregisterReceiver(this.proxyReceiver); 246 unregisterReceiver(this.proxyReceiver);
241 unregisterReceiver(this.proxyStateChangedReceiver); 247 unregisterReceiver(this.proxyStateChangedReceiver);
242 248
243 if (this.proxyConfigurator != null) 249 if (this.proxyConfigurator != null)
244 { 250 {
245 this.proxyConfigurator.unregisterProxy(); 251 this.proxyConfigurator.unregisterProxy();
246 this.proxyConfigurator.shutdown(); 252 this.proxyConfigurator.shutdown();
247 } 253 }
248 254
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 builder.setContentText(getString(msgId, port)); 499 builder.setContentText(getString(msgId, port));
494 builder.setOngoing(true); 500 builder.setOngoing(true);
495 501
496 return builder.getNotification(); 502 return builder.getNotification();
497 } 503 }
498 504
499 public void setEmptyIcon(final boolean hide) 505 public void setEmptyIcon(final boolean hide)
500 { 506 {
501 hideIcon = hide; 507 hideIcon = hide;
502 final NotificationManager notificationManager = (NotificationManager) getSys temService(NOTIFICATION_SERVICE); 508 final NotificationManager notificationManager = (NotificationManager) getSys temService(NOTIFICATION_SERVICE);
503 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification()); 509 notificationManager.notify(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotificat ion());
504 } 510 }
505 511
506 public void sendStateChangedBroadcast() 512 public void sendStateChangedBroadcast()
507 { 513 {
508 final boolean manual = isManual(); 514 final boolean manual = isManual();
509 final Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED) 515 final Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED)
510 .putExtra("enabled", true) 516 .putExtra("enabled", true)
511 .putExtra("port", port) 517 .putExtra("port", port)
512 .putExtra("manual", manual); 518 .putExtra("manual", manual);
513 519
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 * </p> 562 * </p>
557 */ 563 */
558 private final BroadcastReceiver proxyStateChangedReceiver = new BroadcastRecei ver() 564 private final BroadcastReceiver proxyStateChangedReceiver = new BroadcastRecei ver()
559 { 565 {
560 @Override 566 @Override
561 public void onReceive(final Context context, final Intent intent) 567 public void onReceive(final Context context, final Intent intent)
562 { 568 {
563 if (intent != null && PROXY_STATE_CHANGED_ACTION.equals(intent.getAction() )) 569 if (intent != null && PROXY_STATE_CHANGED_ACTION.equals(intent.getAction() ))
564 { 570 {
565 final NotificationManager notificationManager = (NotificationManager) ge tSystemService(NOTIFICATION_SERVICE); 571 final NotificationManager notificationManager = (NotificationManager) ge tSystemService(NOTIFICATION_SERVICE);
566 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification()); 572 notificationManager.notify(AdblockPlus.ONGOING_NOTIFICATION_ID, getNotif ication());
567 ProxyService.this.sendStateChangedBroadcast(); 573 ProxyService.this.sendStateChangedBroadcast();
568 } 574 }
569 } 575 }
570 }; 576 };
571 577
572 final class ProxyServer extends Server 578 final class ProxyServer extends Server
573 { 579 {
574 @Override 580 @Override
575 public void close() 581 public void close()
576 { 582 {
(...skipping 12 matching lines...) Expand all
589 595
590 @Override 596 @Override
591 public void log(final int level, final Object obj, final String message) 597 public void log(final int level, final Object obj, final String message)
592 { 598 {
593 if (level <= logLevel) 599 if (level <= logLevel)
594 { 600 {
595 Log.println(7 - level, obj != null ? obj.toString() : TAG, message); 601 Log.println(7 - level, obj != null ? obj.toString() : TAG, message);
596 } 602 }
597 } 603 }
598 } 604 }
605
606 private void startNotificationWatcher()
607 {
608 this.stopNotificationWatcher();
609
610 this.notificationWatcher = new NotificationWatcher(this);
611
612 final Thread thread = new Thread(this.notificationWatcher);
613 thread.setDaemon(true);
614 thread.start();
615 }
616
617 private void stopNotificationWatcher()
618 {
619 if (this.notificationWatcher != null)
620 {
621 this.notificationWatcher.stop();
622 this.notificationWatcher = null;
623 }
624 }
625
626 private static class NotificationWatcher implements Runnable
627 {
628 public static final int DEFAULT_POLL_DELAY = 3 * 60; /* seconds */
629 public static final int DEFAULT_POLL_INTERVAL = 0; /* seconds */
630
631 private final ProxyService proxyService;
632 private final int pollDelay;
633 private final int pollInterval;
634
635 volatile boolean running = true;
636
637 public NotificationWatcher(final ProxyService proxyService, final int pollDe lay,
638 final int pollInterval)
639 {
640 this.proxyService = proxyService;
641 this.pollDelay = Math.max(0, pollDelay);
642 this.pollInterval = Math.max(0, pollInterval);
643 }
644
645 public NotificationWatcher(final ProxyService proxyService)
646 {
647 this(proxyService, DEFAULT_POLL_DELAY, DEFAULT_POLL_INTERVAL);
648 }
649
650 protected void stop()
651 {
652 this.running = false;
653 }
654
655 @Override
656 public void run()
657 {
658 if (this.pollDelay == 0)
659 {
660 this.running = false;
661 return;
662 }
663
664 long nextPoll = System.currentTimeMillis() + 1000L * this.pollDelay;
665
666 while (this.running)
667 {
668 try
669 {
670 Thread.sleep(250);
671 }
672 catch (InterruptedException ex)
673 {
674 break;
675 }
676
677 if (System.currentTimeMillis() >= nextPoll && this.running)
678 {
679 try
680 {
681 Log.d(TAG, "Polling for notifications");
682 org.adblockplus.libadblockplus.Notification notification =
683 AdblockPlus.getApplication().getNextNotificationToShow();
684
685 while (notification != null
686 && (notification.getType() == Type.INVALID || notification.getTy pe() == Type.QUESTION))
687 {
688 notification = AdblockPlus.getApplication().getNextNotificationToS how();
689 }
690
691 if (notification != null)
692 {
693 final NotificationManager notificationManager = (NotificationManag er) this.proxyService
694 .getSystemService(NOTIFICATION_SERVICE);
695
696 notificationManager.notify(AdblockPlus.SERVER_NOTIFICATION_ID,
697 new NotificationCompat.Builder(this.proxyService.getApplicatio nContext())
698 .setSmallIcon(R.drawable.ic_stat_blocking)
699 .setContentTitle(notification.getTitle())
700 .setContentText(notification.getMessageString())
701 .getNotification());
702 }
703 }
704 catch (Exception ex)
705 {
706 Log.e(TAG, "Polling for notifications failed: " + ex.getMessage(), e x);
707 }
708
709 if (this.pollInterval == 0)
710 {
711 this.running = false;
712 }
713 else
714 {
715 nextPoll = System.currentTimeMillis() + 1000L * this.pollInterval;
716 }
717 }
718 }
719 }
720 }
599 } 721 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld