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

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

Issue 9423010: ABP/Android Better icon hide (Closed)
Patch Set: Created Feb. 20, 2013, 12:08 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 the Adblock Plus, 2 * This file is part of the Adblock Plus,
3 * Copyright (C) 2006-2012 Eyeo GmbH 3 * Copyright (C) 2006-2012 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 11 matching lines...) Expand all
22 import java.io.IOException; 22 import java.io.IOException;
23 import java.lang.reflect.Method; 23 import java.lang.reflect.Method;
24 import java.net.InetAddress; 24 import java.net.InetAddress;
25 import java.net.ServerSocket; 25 import java.net.ServerSocket;
26 import java.util.List; 26 import java.util.List;
27 import java.util.Properties; 27 import java.util.Properties;
28 import java.util.concurrent.TimeoutException; 28 import java.util.concurrent.TimeoutException;
29 29
30 import sunlabs.brazil.server.Server; 30 import sunlabs.brazil.server.Server;
31 import sunlabs.brazil.util.Base64; 31 import sunlabs.brazil.util.Base64;
32 import android.annotation.SuppressLint;
32 import android.app.Notification; 33 import android.app.Notification;
33 import android.app.NotificationManager; 34 import android.app.NotificationManager;
34 import android.app.PendingIntent; 35 import android.app.PendingIntent;
35 import android.app.Service; 36 import android.app.Service;
36 import android.content.BroadcastReceiver; 37 import android.content.BroadcastReceiver;
37 import android.content.Context; 38 import android.content.Context;
38 import android.content.Intent; 39 import android.content.Intent;
39 import android.content.IntentFilter; 40 import android.content.IntentFilter;
40 import android.content.SharedPreferences; 41 import android.content.SharedPreferences;
41 import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 42 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
42 import android.content.pm.PackageManager.NameNotFoundException; 43 import android.content.pm.PackageManager.NameNotFoundException;
43 import android.content.res.Resources; 44 import android.content.res.Resources;
44 import android.net.ConnectivityManager; 45 import android.net.ConnectivityManager;
45 import android.net.NetworkInfo; 46 import android.net.NetworkInfo;
46 import android.net.Proxy; 47 import android.net.Proxy;
47 import android.os.Binder; 48 import android.os.Binder;
48 import android.os.Build; 49 import android.os.Build;
49 import android.os.Handler; 50 import android.os.Handler;
50 import android.os.IBinder; 51 import android.os.IBinder;
51 import android.preference.PreferenceManager; 52 import android.preference.PreferenceManager;
53 import android.support.v4.app.NotificationCompat;
52 import android.util.Log; 54 import android.util.Log;
53 import android.widget.Toast; 55 import android.widget.Toast;
54 56
55 import com.stericson.RootTools.RootTools; 57 import com.stericson.RootTools.RootTools;
56 import com.stericson.RootTools.RootToolsException; 58 import com.stericson.RootTools.RootToolsException;
57 59
58 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener 60 public class ProxyService extends Service implements OnSharedPreferenceChangeLis tener
59 { 61 {
60 private static final String LOCALHOST = "127.0.0.1"; 62 private static final String LOCALHOST = "127.0.0.1";
61 /** 63 /**
62 * Indicates that system supports native proxy configuration. 64 * Indicates that system supports native proxy configuration.
63 */ 65 */
64 public static boolean hasNativeProxy = Build.VERSION.SDK_INT >= 12; // Honeyco mb 3.1 66 public static boolean hasNativeProxy = Build.VERSION.SDK_INT >= 12; // Honeyco mb 3.1
65 67
66 static 68 static
67 { 69 {
68 RootTools.debugMode = false; 70 RootTools.debugMode = false;
69 } 71 }
70 72
71 private static final String TAG = "ProxyService"; 73 private static final String TAG = "ProxyService";
72 private static final boolean logRequests = false; 74 private static final boolean logRequests = false;
73 75
74 private final static int DEFAULT_TIMEOUT = 3000; 76 private final static int DEFAULT_TIMEOUT = 3000;
75 private final static int NO_TRAFFIC_TIMEOUT = 5 * 60 * 1000; // 5 minutes 77 private final static int NO_TRAFFIC_TIMEOUT = 5 * 60 * 1000; // 5 minutes
76 78
77 final static int ONGOING_NOTIFICATION_ID = R.string.app_name; 79 final static int ONGOING_NOTIFICATION_ID = R.string.app_name;
80 private static final long POSITION_RIGHT = Build.VERSION.SDK_INT >= Build.VERS ION_CODES.GINGERBREAD ? Long.MIN_VALUE : Long.MAX_VALUE;
78 private final static int NOTRAFFIC_NOTIFICATION_ID = R.string.app_name + 3; 81 private final static int NOTRAFFIC_NOTIFICATION_ID = R.string.app_name + 3;
79 82
80 /** 83 /**
81 * Broadcasted when service starts or stops. 84 * Broadcasted when service starts or stops.
82 */ 85 */
83 public final static String BROADCAST_STATE_CHANGED = "org.adblockplus.android. service.state"; 86 public final static String BROADCAST_STATE_CHANGED = "org.adblockplus.android. service.state";
84 /** 87 /**
85 * Broadcasted if proxy fails to start. 88 * Broadcasted if proxy fails to start.
86 */ 89 */
87 public final static String BROADCAST_PROXY_FAILED = "org.adblockplus.android.p roxy.failure"; 90 public final static String BROADCAST_PROXY_FAILED = "org.adblockplus.android.p roxy.failure";
88 91
89 private final static String IPTABLES_RETURN = " -t nat -m owner --uid-owner {{ UID}} -A OUTPUT -p tcp -j RETURN\n"; 92 private final static String IPTABLES_RETURN = " -t nat -m owner --uid-owner {{ UID}} -A OUTPUT -p tcp -j RETURN\n";
90 private final static String IPTABLES_ADD_HTTP = " -t nat -A OUTPUT -p tcp --dp ort 80 -j REDIRECT --to {{PORT}}\n"; 93 private final static String IPTABLES_ADD_HTTP = " -t nat -A OUTPUT -p tcp --dp ort 80 -j REDIRECT --to {{PORT}}\n";
91 94
92 private Notification ongoingNotification; 95 boolean hideIcon;
93 private PendingIntent contentIntent;
94
95 private Handler notrafficHandler; 96 private Handler notrafficHandler;
96 97
97 protected ProxyServer proxy = null; 98 protected ProxyServer proxy = null;
98 protected int port; 99 protected int port;
99 private Properties proxyConfiguration = new Properties(); 100 private Properties proxyConfiguration = new Properties();
100 101
101 /** 102 /**
102 * Indicates that service is working with root privileges. 103 * Indicates that service is working with root privileges.
103 */ 104 */
104 private boolean transparent = false; 105 private boolean transparent = false;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 257
257 proxy = new ProxyServer(); 258 proxy = new ProxyServer();
258 proxy.logLevel = Server.LOG_DIAGNOSTIC; 259 proxy.logLevel = Server.LOG_DIAGNOSTIC;
259 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration); 260 proxy.setup(listen, proxyConfiguration.getProperty("handler"), proxyConfig uration);
260 proxy.start(); 261 proxy.start();
261 } 262 }
262 263
263 prefs.registerOnSharedPreferenceChangeListener(this); 264 prefs.registerOnSharedPreferenceChangeListener(this);
264 265
265 // Lock service 266 // Lock service
266 boolean hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), resou rces.getBoolean(R.bool.def_hideicon)); 267 hideIcon = prefs.getBoolean(getString(R.string.pref_hideicon), resources.get Boolean(R.bool.def_hideicon));
267 String msg = getString(transparent ? R.string.notif_all : nativeProxy ? R.st ring.notif_wifi : R.string.notif_waiting); 268 startForeground(ONGOING_NOTIFICATION_ID, getNotification());
268 ongoingNotification = new Notification();
269 ongoingNotification.when = 0;
270 contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Preferen ces.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TA SK), 0);
271 ongoingNotification.icon = hideIcon ? R.drawable.transparent : R.drawable.ic _stat_blocking;
272 ongoingNotification.setLatestEventInfo(getApplicationContext(), getText(R.st ring.app_name), msg, contentIntent);
273 startForeground(ONGOING_NOTIFICATION_ID, ongoingNotification);
274 269
275 // If automatic setting of proxy was blocked, check if user has set it manua lly 270 // If automatic setting of proxy was blocked, check if user has set it manua lly
276 boolean manual = isManual(); 271 boolean manual = isManual();
277 if (manual && hasNativeProxy) 272 if (manual && hasNativeProxy)
278 { 273 {
279 ConnectivityManager connectivityManager = (ConnectivityManager) getSystemS ervice(Context.CONNECTIVITY_SERVICE); 274 ConnectivityManager connectivityManager = (ConnectivityManager) getSystemS ervice(Context.CONNECTIVITY_SERVICE);
280 updateNoTrafficCheck(connectivityManager); 275 updateNoTrafficCheck(connectivityManager);
281 } 276 }
282 277
283 sendStateChangedBroadcast(); 278 sendStateChangedBroadcast();
284 Log.i(TAG, "Service started"); 279 Log.i(TAG, "Service started");
285 } 280 }
286 281
287 @Override 282 @Override
288 public int onStartCommand(Intent intent, int flags, int startId) 283 public int onStartCommand(Intent intent, int flags, int startId)
289 { 284 {
290 return START_STICKY; 285 return START_STICKY;
291 } 286 }
292 287
293 @Override 288 @Override
294 public void onDestroy() 289 public void onDestroy()
295 { 290 {
296 super.onDestroy(); 291 super.onDestroy();
297 292
298 stopNoTrafficCheck(false, false); 293 stopNoTrafficCheck();
299 294
300 unregisterReceiver(matchesReceiver); 295 unregisterReceiver(matchesReceiver);
301 unregisterReceiver(proxyReceiver); 296 unregisterReceiver(proxyReceiver);
302 297
303 // Stop IP redirecting 298 // Stop IP redirecting
304 if (transparent) 299 if (transparent)
305 { 300 {
306 new Thread() 301 new Thread()
307 { 302 {
308 @Override 303 @Override
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 Log.e(TAG, null, e); 606 Log.e(TAG, null, e);
612 } 607 }
613 } 608 }
614 609
615 /** 610 /**
616 * Raises or removes no traffic notification based on the user proxy settings 611 * Raises or removes no traffic notification based on the user proxy settings
617 */ 612 */
618 private void updateNoTrafficCheck(String[] userProxy) 613 private void updateNoTrafficCheck(String[] userProxy)
619 { 614 {
620 boolean ourProxy = userProxy != null && isLocalHost(userProxy[0]) && Integer .valueOf(userProxy[1]) == port; 615 boolean ourProxy = userProxy != null && isLocalHost(userProxy[0]) && Integer .valueOf(userProxy[1]) == port;
616 if (ourProxy != proxyManualyConfigured)
Thomas Greiner 2013/02/27 16:34:29 rename to proxyManuallyConfigured
617 {
618 proxyManualyConfigured = ourProxy;
619 sendStateChangedBroadcast();
620 }
621 if (ourProxy) 621 if (ourProxy)
622 { 622 {
623 stopNoTrafficCheck(true, true); 623 stopNoTrafficCheck();
624 } 624 }
625 else 625 else
626 { 626 {
627 // Initiate no traffic check 627 // Initiate no traffic check
628 notrafficHandler = new Handler(); 628 notrafficHandler = new Handler();
Thomas Greiner 2013/02/27 16:34:29 variable name should be camel-cased (otherwise it
629 notrafficHandler.postDelayed(noTraffic, NO_TRAFFIC_TIMEOUT); 629 notrafficHandler.postDelayed(noTraffic, NO_TRAFFIC_TIMEOUT);
630 NotificationManager notificationManager = (NotificationManager) getSystemS ervice(NOTIFICATION_SERVICE);
631 ongoingNotification.setLatestEventInfo(ProxyService.this, getText(R.string .app_name), getText(R.string.notif_waiting), contentIntent);
632 notificationManager.notify(ONGOING_NOTIFICATION_ID, ongoingNotification);
633 } 630 }
634 if (ourProxy != proxyManualyConfigured) 631 NotificationManager notificationManager = (NotificationManager) getSystemSer vice(NOTIFICATION_SERVICE);
635 { 632 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification());
636 proxyManualyConfigured = ourProxy;
637 sendStateChangedBroadcast();
638 }
639 } 633 }
640 634
641 /** 635 /**
642 * Stops no traffic check, optionally resetting notification message. 636 * Stops no traffic check and resets notification message.
643 *
644 * @param changeStatus
645 * true if notification message should be set to normal operating
646 * mode
647 * @param forceMessageReset
648 * if true unconditionally reset main notification message
649 */ 637 */
650 private void stopNoTrafficCheck(boolean changeStatus, boolean forceMessageRese t) 638 private void stopNoTrafficCheck()
651 { 639 {
652 if (notrafficHandler != null) 640 if (notrafficHandler != null)
653 { 641 {
654 notrafficHandler.removeCallbacks(noTraffic); 642 notrafficHandler.removeCallbacks(noTraffic);
655 proxyManualyConfigured = true;
656 sendStateChangedBroadcast(); 643 sendStateChangedBroadcast();
657 }
658 if (changeStatus && (notrafficHandler != null || forceMessageReset))
659 {
660 NotificationManager notificationManager = (NotificationManager) getSystemS ervice(NOTIFICATION_SERVICE); 644 NotificationManager notificationManager = (NotificationManager) getSystemS ervice(NOTIFICATION_SERVICE);
661 ongoingNotification.setLatestEventInfo(ProxyService.this, getText(R.string .app_name), getText(R.string.notif_wifi), contentIntent); 645 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification());
662 notificationManager.notify(ONGOING_NOTIFICATION_ID, ongoingNotification);
663 } 646 }
664 notrafficHandler = null; 647 notrafficHandler = null;
665 } 648 }
666 649
667 public void setEmptyIcon(boolean empty) 650 @SuppressLint("NewApi")
651 private Notification getNotification()
668 { 652 {
669 ongoingNotification.icon = empty ? R.drawable.transparent : R.drawable.ic_st at_blocking; 653 int msgId = R.string.notif_waiting;
654 if (nativeProxy || proxyManualyConfigured)
655 msgId = R.string.notif_wifi;
656 if (transparent)
657 msgId = R.string.notif_all;
658
659 Log.e(TAG, "V: " + nativeProxy + " " + proxyManualyConfigured + " " + transp arent);
Thomas Greiner 2013/02/27 16:34:29 Why is this being logged with priority ERROR?
660 NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
661 if (hideIcon && msgId != R.string.notif_waiting)
662 {
663 builder.setWhen(POSITION_RIGHT);
664 builder.setSmallIcon(R.drawable.transparent);
665 //builder.setContent(new RemoteViews(getPackageName(), R.layout.notif_hidd en));
Thomas Greiner 2013/02/27 16:34:29 you can add a TODO here but keep unused code in lo
666 }
667 else
668 {
669 builder.setWhen(0);
670 builder.setSmallIcon(R.drawable.ic_stat_blocking);
671 }
672 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent( this, Preferences.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_A CTIVITY_NEW_TASK), 0);
673 builder.setContentIntent(contentIntent);
674 builder.setContentTitle(getText(R.string.app_name));
675 builder.setContentText(getText(msgId));
676
677 Notification notification = builder.getNotification();
678 return notification;
679 }
680
681 public void setEmptyIcon(boolean hide)
682 {
683 hideIcon = hide;
670 NotificationManager notificationManager = (NotificationManager) getSystemSer vice(NOTIFICATION_SERVICE); 684 NotificationManager notificationManager = (NotificationManager) getSystemSer vice(NOTIFICATION_SERVICE);
671 notificationManager.notify(ONGOING_NOTIFICATION_ID, ongoingNotification); 685 notificationManager.notify(ONGOING_NOTIFICATION_ID, getNotification());
672 } 686 }
673 687
674 public void sendStateChangedBroadcast() 688 public void sendStateChangedBroadcast()
675 { 689 {
676 Log.i(TAG, "Broadcasting " + BROADCAST_STATE_CHANGED); 690 Log.i(TAG, "Broadcasting " + BROADCAST_STATE_CHANGED);
677 boolean manual = isManual(); 691 boolean manual = isManual();
678 Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED).putExtra("enabled", true).putExtra("port", port).putExtra("manual", manual); 692 Intent stateIntent = new Intent(BROADCAST_STATE_CHANGED).putExtra("enabled", true).putExtra("port", port).putExtra("manual", manual);
679 if (manual) 693 if (manual)
680 stateIntent.putExtra("configured", proxyManualyConfigured); 694 stateIntent.putExtra("configured", proxyManualyConfigured);
681 sendBroadcast(stateIntent); 695 sendBroadcast(stateIntent);
(...skipping 17 matching lines...) Expand all
699 713
700 /** 714 /**
701 * Executed if no traffic is detected after a period of time. Notifies user 715 * Executed if no traffic is detected after a period of time. Notifies user
702 * about possible configuration problems. 716 * about possible configuration problems.
703 */ 717 */
704 private Runnable noTraffic = new Runnable() 718 private Runnable noTraffic = new Runnable()
705 { 719 {
706 public void run() 720 public void run()
707 { 721 {
708 // Show warning notification 722 // Show warning notification
709 Notification notification = new Notification(); 723 NotificationCompat.Builder builder = new NotificationCompat.Builder(ProxyS ervice.this);
710 notification.icon = R.drawable.ic_stat_warning; 724 builder.setSmallIcon(R.drawable.ic_stat_warning);
711 notification.when = System.currentTimeMillis(); 725 builder.setWhen(System.currentTimeMillis());
712 notification.flags |= Notification.FLAG_AUTO_CANCEL; 726 builder.setAutoCancel(true);
713 notification.defaults |= Notification.DEFAULT_SOUND; 727 builder.setDefaults(Notification.DEFAULT_SOUND);
714 Intent intent = new Intent(ProxyService.this, ConfigurationActivity.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 728 Intent intent = new Intent(ProxyService.this, ConfigurationActivity.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
715 intent.putExtra("port", port); 729 intent.putExtra("port", port);
716 PendingIntent contentIntent = PendingIntent.getActivity(ProxyService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 730 PendingIntent contentIntent = PendingIntent.getActivity(ProxyService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
717 notification.setLatestEventInfo(ProxyService.this, getText(R.string.app_na me), getString(R.string.notif_notraffic), contentIntent); 731 builder.setContentIntent(contentIntent);
732 builder.setContentTitle(getText(R.string.app_name));
733 builder.setContentText(getText(R.string.notif_notraffic));
718 NotificationManager notificationManager = (NotificationManager) getSystemS ervice(NOTIFICATION_SERVICE); 734 NotificationManager notificationManager = (NotificationManager) getSystemS ervice(NOTIFICATION_SERVICE);
719 notificationManager.notify(NOTRAFFIC_NOTIFICATION_ID, notification); 735 notificationManager.notify(NOTRAFFIC_NOTIFICATION_ID, builder.getNotificat ion());
720 } 736 }
721 }; 737 };
722 738
723 /** 739 /**
724 * Stops no traffic check if traffic is detected by proxy service. 740 * Stops no traffic check if traffic is detected by proxy service.
725 */ 741 */
726 private BroadcastReceiver matchesReceiver = new BroadcastReceiver() 742 private BroadcastReceiver matchesReceiver = new BroadcastReceiver()
727 { 743 {
728 @Override 744 @Override
729 public void onReceive(final Context context, Intent intent) 745 public void onReceive(final Context context, Intent intent)
730 { 746 {
731 if (intent.getAction().equals(AdblockPlus.BROADCAST_FILTER_MATCHES)) 747 if (intent.getAction().equals(AdblockPlus.BROADCAST_FILTER_MATCHES))
732 stopNoTrafficCheck(true, false); 748 {
749 proxyManualyConfigured = true;
750 stopNoTrafficCheck();
751 }
733 } 752 }
734 }; 753 };
735 754
736 /** 755 /**
737 * Stops service if proxy fails. 756 * Stops service if proxy fails.
738 */ 757 */
739 private BroadcastReceiver proxyReceiver = new BroadcastReceiver() 758 private BroadcastReceiver proxyReceiver = new BroadcastReceiver()
740 { 759 {
741 @Override 760 @Override
742 public void onReceive(final Context context, Intent intent) 761 public void onReceive(final Context context, Intent intent)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 @Override 857 @Override
839 public void log(int level, Object obj, String message) 858 public void log(int level, Object obj, String message)
840 { 859 {
841 if (level <= logLevel) 860 if (level <= logLevel)
842 { 861 {
843 Log.println(7 - level, obj != null ? obj.toString() : TAG, message); 862 Log.println(7 - level, obj != null ? obj.toString() : TAG, message);
844 } 863 }
845 } 864 }
846 } 865 }
847 } 866 }
OLDNEW
« src/org/adblockplus/android/Preferences.java ('K') | « src/org/adblockplus/android/Preferences.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld