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

Side by Side Diff: src/org/adblockplus/android/configurators/ManualProxyConfigurator.java

Issue 4705284891082752: Proxy configurators (Closed)
Patch Set: Created Aug. 11, 2014, 12:36 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
(Empty)
1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17
18 package org.adblockplus.android.configurators;
19
20 import java.net.InetAddress;
21 import java.util.concurrent.Semaphore;
22 import java.util.concurrent.locks.ReentrantLock;
23
24 import org.adblockplus.android.BridgeCommand;
25 import org.adblockplus.android.ConfigurationActivity;
26 import org.adblockplus.android.ProxyService;
27 import org.adblockplus.android.R;
28 import org.adblockplus.android.compat.ProxyProperties;
29 import org.adblockplus.brazil.RequestHandler;
30
31 import android.app.NotificationManager;
32 import android.app.PendingIntent;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.os.Handler;
36 import android.support.v4.app.NotificationCompat;
37
38 /**
39 * A dummy registrator only holding callbacks and checks.
40 *
41 * @author rjeschke
42 */
43 public class ManualProxyConfigurator implements ProxyConfigurator
44 {
45 final Context context;
46 private ProxyProperties proxyProperties = null;
47 private static final int NOTRAFFIC_NOTIFICATION_ID = R.string.proxysettings_na me;
48 private static final int NO_TRAFFIC_TIMEOUT = 5 * 60 * 1000; // 5 minutes
49 private volatile boolean isRegistered = false;
50 private NoTrafficWorker noTrafficWorker = null;
51 private ReentrantLock noTrafficAccessLock = new ReentrantLock();
52 private final Handler uiHandler;
53
54 public ManualProxyConfigurator(final Context context)
55 {
56 this.uiHandler = new Handler();
57 this.context = context;
58 }
59
60 @Override
61 public boolean initialize()
62 {
63 return true;
64 }
65
66 @Override
67 public boolean registerProxy(final InetAddress address, final int port)
68 {
69 this.proxyProperties = new ProxyProperties(address.getHostName(), port, "");
70 this.startNoTrafficCheck();
71 return true;
72 }
73
74 @Override
75 public void unregisterProxy()
76 {
77 this.isRegistered = false;
78 this.abortNoTrafficCheck();
79 }
80
81 @Override
82 public void shutdown()
83 {
84 this.removeErrorNotification();
85 }
86
87 @Override
88 public ProxyRegistrationType getType()
89 {
90 return ProxyRegistrationType.MANUAL;
91 }
92
93 @Override
94 public boolean isRegistered()
95 {
96 return this.isRegistered;
97 }
98
99 @Override
100 public boolean isSticky()
101 {
102 return true;
103 }
104
105 @Override
106 public String toString()
107 {
108 return "[ProxyConfigurator: " + this.getType() + "]";
109 }
110
111 private void removeErrorNotification()
112 {
113 final NotificationManager notificationManager =
114 (NotificationManager) this.context.getSystemService(Context.NOTIFICATION _SERVICE);
115 notificationManager.cancel(NOTRAFFIC_NOTIFICATION_ID);
116 }
117
118 private void startNoTrafficCheck()
119 {
120 this.noTrafficAccessLock.lock();
121 try
122 {
123 if (this.noTrafficWorker == null)
124 {
125 this.noTrafficWorker = new NoTrafficWorker(this);
126 final Thread t = new Thread(this.noTrafficWorker);
127 t.setDaemon(true);
128 t.start();
129 }
130 }
131 finally
132 {
133 this.noTrafficAccessLock.unlock();
134 }
135 }
136
137 private void abortNoTrafficCheck()
138 {
139 this.noTrafficAccessLock.lock();
140 try
141 {
142 if (this.noTrafficWorker != null)
143 {
144 this.noTrafficWorker.stop();
145 }
146 }
147 finally
148 {
149 this.noTrafficWorker = null;
150 this.noTrafficAccessLock.unlock();
151 }
152 }
153
154 private synchronized void trafficReceived()
155 {
156 this.isRegistered = true;
157 this.abortNoTrafficCheck();
158
159 this.uiHandler.post(new Runnable()
160 {
161 @Override
162 public void run()
163 {
164 ManualProxyConfigurator.this.removeErrorNotification();
165 ProxyService.sendBridgeCommand(ManualProxyConfigurator.this.context, Bri dgeCommand.STATE_CHANGED);
166 }
167 });
168 }
169
170 private synchronized void noTrafficReceived()
171 {
172 this.isRegistered = false;
173 this.abortNoTrafficCheck();
174
175 this.uiHandler.post(new Runnable()
176 {
177 @Override
178 public void run()
179 {
180 final Context context = ManualProxyConfigurator.this.context;
181 // Show warning notification
182 final Intent intent =
183 new Intent(context, ConfigurationActivity.class)
184 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
185 .putExtra("port", ManualProxyConfigurator.this.proxyProperties.g etPort());
186
187 final PendingIntent contentIntent =
188 PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPD ATE_CURRENT);
189
190 final NotificationCompat.Builder builder =
191 new NotificationCompat.Builder(context)
192 .setSmallIcon(R.drawable.ic_stat_warning)
193 .setWhen(System.currentTimeMillis())
194 .setAutoCancel(true)
195 .setContentIntent(contentIntent)
196 .setContentTitle(context.getText(R.string.app_name))
197 .setContentText(context.getText(R.string.notif_notraffic));
198
199 final NotificationManager notificationManager = (NotificationManager) co ntext.getSystemService(Context.NOTIFICATION_SERVICE);
200 notificationManager.notify(NOTRAFFIC_NOTIFICATION_ID, builder.getNotific ation());
201
202 ProxyService.sendBridgeCommand(context, BridgeCommand.STATE_CHANGED);
203 }
204 });
205 }
206
207 private static class NoTrafficWorker implements Runnable
208 {
209 private volatile boolean running = true;
210 private final Semaphore finished = new Semaphore(1);
211 private final ManualProxyConfigurator manualProxyConfigurator;
212
213 public NoTrafficWorker(final ManualProxyConfigurator manualProxyConfigurator )
214 {
215 this.manualProxyConfigurator = manualProxyConfigurator;
216 this.finished.acquireUninterruptibly();
217 }
218
219 @Override
220 public void run()
221 {
222 try
223 {
224 final long endTime = System.currentTimeMillis() + NO_TRAFFIC_TIMEOUT;
225
226 final long blockedStart = RequestHandler.getBlockedRequestCount();
227 final long unblockedStart = RequestHandler.getUnblockedRequestCount();
228
229 while (this.running)
230 {
231 try
232 {
233 if (System.currentTimeMillis() >= endTime)
234 {
235 this.running = false;
236 this.manualProxyConfigurator.noTrafficReceived();
237 break;
238 }
239
240 if (RequestHandler.getBlockedRequestCount() != blockedStart
241 || RequestHandler.getUnblockedRequestCount() != unblockedStart)
242 {
243 this.running = false;
244 this.manualProxyConfigurator.trafficReceived();
245 break;
246 }
247
248 Thread.sleep(100);
249 }
250 catch (Throwable t)
251 {
252 // Swallow everything to keep this thread alive at all cost
253 }
254 }
255 }
256 finally
257 {
258 this.finished.release();
259 }
260 }
261
262 public synchronized void stop()
263 {
264 if (this.running)
265 {
266 this.running = false;
267 this.finished.acquireUninterruptibly();
268 }
269 }
270 }
271 }
OLDNEW

Powered by Google App Engine
This is Rietveld