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: Show Android notifications Created Feb. 17, 2015, 1:51 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
« no previous file with comments | « src/org/adblockplus/android/CrashHandler.java ('k') | src/org/adblockplus/android/Utils.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 23 matching lines...) Expand all
34 import android.app.Notification; 34 import android.app.Notification;
35 import android.app.NotificationManager; 35 import android.app.NotificationManager;
36 import android.app.PendingIntent; 36 import android.app.PendingIntent;
37 import android.app.Service; 37 import android.app.Service;
38 import android.content.BroadcastReceiver; 38 import android.content.BroadcastReceiver;
39 import android.content.Context; 39 import android.content.Context;
40 import android.content.Intent; 40 import android.content.Intent;
41 import android.content.IntentFilter; 41 import android.content.IntentFilter;
42 import android.content.SharedPreferences; 42 import android.content.SharedPreferences;
43 import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 43 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
44 import android.graphics.BitmapFactory;
44 import android.os.Binder; 45 import android.os.Binder;
45 import android.os.Build; 46 import android.os.Build;
46 import android.os.IBinder; 47 import android.os.IBinder;
47 import android.os.StrictMode; 48 import android.os.StrictMode;
48 import android.preference.PreferenceManager; 49 import android.preference.PreferenceManager;
49 import android.support.v4.app.NotificationCompat; 50 import android.support.v4.app.NotificationCompat;
50 import android.util.Log; 51 import android.util.Log;
51 52
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;
95 94
95 private NotificationWatcher notificationWatcher = null;
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()
105 .build()); 106 .build());
(...skipping 107 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();
239 243
244 this.stopNotificationWatcher();
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
249 sendBroadcast(new Intent(BROADCAST_STATE_CHANGED).putExtra("enabled", false) ); 255 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)); 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_FIRST_POLL_INTERVAL = 3 * 60; /* seconds */
629 public static final int DEFAULT_NEXT_POLL_INTERVALS = 0; /* seconds */
630
631 private final ProxyService proxyService;
632 private final int firstPollInterval;
633 private final int nextPollIntervals;
634
635 volatile boolean running = true;
636
637 public NotificationWatcher(final ProxyService proxyService, final int firstP ollInterval, 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)
686 {
687 Notification notif = new NotificationCompat.Builder(
688 this.proxyService.getApplicationContext())
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();
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
« no previous file with comments | « src/org/adblockplus/android/CrashHandler.java ('k') | src/org/adblockplus/android/Utils.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld