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