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

Side by Side Diff: src/org/adblockplus/android/updater/AlarmReceiver.java

Issue 5153282527854592: Issue 98 - Use the libadblockplus update mechanism (Closed)
Patch Set: Only append the revision to the version for devbuilds Created Sept. 26, 2014, 2: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
(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.updater;
19
20 import java.io.IOException;
21 import java.io.StringReader;
22 import java.net.URI;
23 import java.net.URISyntaxException;
24 import java.net.URL;
25 import java.util.Locale;
26
27 import javax.xml.parsers.DocumentBuilder;
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import javax.xml.parsers.ParserConfigurationException;
30
31 import org.adblockplus.android.AdblockPlus;
32 import org.adblockplus.android.R;
33 import org.adblockplus.android.Utils;
34 import org.apache.http.HttpEntity;
35 import org.apache.http.HttpResponse;
36 import org.apache.http.client.methods.HttpGet;
37 import org.apache.http.impl.client.DefaultHttpClient;
38 import org.apache.http.util.EntityUtils;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NodeList;
42 import org.xml.sax.InputSource;
43 import org.xml.sax.SAXException;
44
45 import android.app.Notification;
46 import android.app.NotificationManager;
47 import android.app.PendingIntent;
48 import android.content.BroadcastReceiver;
49 import android.content.Context;
50 import android.content.Intent;
51 import android.content.pm.PackageManager.NameNotFoundException;
52 import android.net.ConnectivityManager;
53 import android.net.NetworkInfo;
54 import android.os.Build;
55 import android.util.Log;
56
57 /**
58 * Processes Alarm event to check for update availability.
59 */
60 public class AlarmReceiver extends BroadcastReceiver
61 {
62 private static final String TAG = Utils.getTag(AlarmReceiver.class);
63 private static final int NOTIFICATION_ID = R.string.app_name + 1;
64
65 @Override
66 public void onReceive(final Context context, final Intent intent)
67 {
68 Log.i(TAG, "Alarm; requesting updater service");
69
70 final AdblockPlus application = AdblockPlus.getApplication();
71
72 // Indicates manual (immediate) update check which requires response to user .
73 final boolean notify = intent.getBooleanExtra("notifynoupdate", false);
74
75 // Check network availability
76 boolean connected = false;
77 final ConnectivityManager connectivityManager = (ConnectivityManager) contex t.getSystemService(Context.CONNECTIVITY_SERVICE);
78 NetworkInfo networkInfo = null;
79 if (connectivityManager != null)
80 {
81 networkInfo = connectivityManager.getActiveNetworkInfo();
82 connected = networkInfo == null ? false : networkInfo.isConnected();
83 }
84
85 // Prepare notification
86 final NotificationManager notificationManager = (NotificationManager) contex t.getSystemService(Context.NOTIFICATION_SERVICE);
87 final Notification notification = new Notification();
88 notification.icon = R.drawable.ic_stat_warning;
89 notification.when = System.currentTimeMillis();
90 notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY _ALERT_ONCE;
91 if (notify)
92 notification.flags |= Notification.DEFAULT_SOUND;
93 final PendingIntent emptyIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
94
95 // Get update info
96 if (application.checkWriteExternalPermission() && connected)
97 {
98 final Thread thread = new Thread(new Runnable()
99 {
100 @Override
101 public void run()
102 {
103 boolean success = false;
104 try
105 {
106 // Read updates manifest
107 final DefaultHttpClient httpClient = new DefaultHttpClient();
108
109 final String locale = Locale.getDefault().toString().toLowerCase();
110 final String device = AdblockPlus.getDeviceName();
111 final boolean releaseBuild = context.getResources().getBoolean(R.boo l.def_release);
112 final String updateUrlTemplate = context.getString(releaseBuild ? R. string.update_url : R.string.devbuild_update_url);
113 final URL updateUrl = new URL(String.format(updateUrlTemplate, Build .VERSION.SDK_INT, AdblockPlus.getApplication().getBuildNumber(), locale, device) );
114 // The following line correctly url-encodes query string parameters
115 final URI uri = new URI(updateUrl.getProtocol(), updateUrl.getUserIn fo(), updateUrl.getHost(), updateUrl.getPort(), updateUrl.getPath(), updateUrl.g etQuery(), updateUrl.getRef());
116 final HttpGet httpGet = new HttpGet(uri);
117
118 final HttpResponse httpResponse = httpClient.execute(httpGet);
119 final HttpEntity httpEntity = httpResponse.getEntity();
120 final String xml = EntityUtils.toString(httpEntity);
121
122 // Parse XML
123 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstanc e();
124 final DocumentBuilder db = dbf.newDocumentBuilder();
125
126 final InputSource is = new InputSource();
127 is.setCharacterStream(new StringReader(xml));
128 final Document doc = db.parse(is);
129
130 // Find best match
131 final NodeList nl = doc.getElementsByTagName("updatecheck");
132 int newBuild = -1;
133 int newApi = -1;
134 String newUrl = null;
135 for (int i = 0; i < nl.getLength(); i++)
136 {
137 final Element e = (Element) nl.item(i);
138 final String url = e.getAttribute("package");
139 final int build = Integer.parseInt(e.getAttribute("build"));
140 final int api = Integer.parseInt(e.getAttribute("api"));
141 if (api > android.os.Build.VERSION.SDK_INT)
142 continue;
143 if ((build > newBuild) || (build == newBuild && api > newApi))
144 {
145 newBuild = build;
146 newApi = api;
147 newUrl = url;
148 }
149 }
150
151 final int thisBuild = context.getPackageManager().getPackageInfo(con text.getPackageName(), 0).versionCode;
152
153 // Notify user if newer update was found
154 if (thisBuild < newBuild)
155 {
156 notification.icon = R.drawable.ic_stat_download;
157 final Intent intent = new Intent(context, UpdaterActivity.class).a ddFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
158 intent.setAction("download");
159 intent.putExtra("url", newUrl);
160 intent.putExtra("build", newBuild);
161 final PendingIntent updateIntent = PendingIntent.getActivity(conte xt, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
162 notification.setLatestEventInfo(context, context.getText(R.string. app_name), context.getString(R.string.msg_update_available), updateIntent);
163 notificationManager.notify(NOTIFICATION_ID, notification);
164 }
165 // Notify user that no update was found
166 else if (notify)
167 {
168 notification.setLatestEventInfo(context, context.getText(R.string. app_name), context.getString(R.string.msg_update_missing), emptyIntent);
169 notificationManager.notify(NOTIFICATION_ID, notification);
170 }
171 success = true;
172 }
173 catch (final IOException e)
174 {
175 }
176 catch (final NumberFormatException e)
177 {
178 }
179 catch (final NameNotFoundException e)
180 {
181 }
182 catch (final ParserConfigurationException e)
183 {
184 }
185 catch (final SAXException e)
186 {
187 Log.e(TAG, "Error", e);
188 }
189 catch (final URISyntaxException e)
190 {
191 Log.e(TAG, "Error", e);
192 }
193 finally
194 {
195 if (!success)
196 {
197 // Notify user about failure
198 if (notify)
199 {
200 notification.setLatestEventInfo(context, context.getText(R.strin g.app_name), context.getString(R.string.msg_update_fail), emptyIntent);
201 notificationManager.notify(NOTIFICATION_ID, notification);
202 }
203 }
204 // Schedule next check
205 application.scheduleUpdater(0);
206 }
207 }
208 });
209 thread.start();
210 }
211 else
212 {
213 // Notify user about failure
214 if (notify)
215 {
216 notification.setLatestEventInfo(context, context.getText(R.string.app_na me), context.getString(R.string.msg_update_fail), emptyIntent);
217 notificationManager.notify(NOTIFICATION_ID, notification);
218 }
219 // Schedule retry in 30 minutes - there is no connection available at this time
220 application.scheduleUpdater(30);
221 }
222 }
223 }
OLDNEW
« no previous file with comments | « src/org/adblockplus/android/Utils.java ('k') | src/org/adblockplus/libadblockplus/FilterEngine.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld