Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2013 Fairphone Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.fairphone.updater; |
| 18 | |
| 19 | import android.app.DownloadManager; |
| 20 | import android.app.DownloadManager.Request; |
| 21 | import android.app.Notification; |
| 22 | import android.app.NotificationManager; |
| 23 | import android.app.PendingIntent; |
| 24 | import android.app.Service; |
| 25 | import android.app.TaskStackBuilder; |
| 26 | import android.content.BroadcastReceiver; |
| 27 | import android.content.Context; |
| 28 | import android.content.Intent; |
| 29 | import android.content.IntentFilter; |
| 30 | import android.content.SharedPreferences; |
| 31 | import android.content.SharedPreferences.Editor; |
| 32 | import android.content.res.Resources; |
| 33 | import android.database.Cursor; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 34 | import android.net.ConnectivityManager; |
| 35 | import android.net.Uri; |
Jose Pascoal | cf13fde | 2014-05-21 20:17:17 +0100 | [diff] [blame] | 36 | import android.os.Build; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 37 | import android.os.Environment; |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 38 | import android.os.Handler; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 39 | import android.os.IBinder; |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 40 | import android.os.SystemClock; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 41 | import android.support.v4.app.NotificationCompat; |
Tiago Costa | c14ea24 | 2014-04-24 10:14:41 +0100 | [diff] [blame] | 42 | import android.util.Log; |
Jose Pascoal | 0e96628 | 2014-08-12 18:49:05 +0100 | [diff] [blame] | 43 | import android.widget.Toast; |
Filipe Gonçalves | cd0f33d | 2014-12-15 15:05:15 +0000 | [diff] [blame] | 44 | |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 45 | import com.fairphone.updater.data.UpdaterData; |
Jose Pascoal | 7bf83a0 | 2014-10-13 18:30:18 +0100 | [diff] [blame] | 46 | import com.fairphone.updater.data.Version; |
| 47 | import com.fairphone.updater.data.VersionParserHelper; |
Jose Pascoal | ac6a846 | 2014-09-10 20:12:08 +0100 | [diff] [blame] | 48 | import com.fairphone.updater.gappsinstaller.GappsInstallerHelper; |
Filipe Gonçalves | 49ce23c | 2015-02-13 16:33:52 +0000 | [diff] [blame] | 49 | import com.fairphone.updater.tools.PrivilegeChecker; |
Jose Pascoal | 02b849e | 2014-06-26 17:07:51 +0100 | [diff] [blame] | 50 | import com.fairphone.updater.tools.RSAUtils; |
| 51 | import com.fairphone.updater.tools.Utils; |
Jose Pascoal | cf13fde | 2014-05-21 20:17:17 +0100 | [diff] [blame] | 52 | import com.stericson.RootTools.execution.CommandCapture; |
| 53 | import com.stericson.RootTools.execution.Shell; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 54 | |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 55 | import java.io.File; |
| 56 | import java.io.FileInputStream; |
| 57 | import java.io.FileOutputStream; |
| 58 | import java.io.IOException; |
| 59 | import java.io.UnsupportedEncodingException; |
| 60 | import java.net.URLEncoder; |
| 61 | import java.nio.channels.FileChannel; |
| 62 | import java.nio.charset.Charset; |
| 63 | import java.util.concurrent.TimeoutException; |
| 64 | |
Filipe Gonçalves | cd0f33d | 2014-12-15 15:05:15 +0000 | [diff] [blame] | 65 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 66 | public class UpdaterService extends Service |
| 67 | { |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 68 | |
Filipe Gonçalves | 6ce7b14 | 2015-01-22 14:39:29 +0000 | [diff] [blame] | 69 | public static final String LAST_CONFIG_DOWNLOAD_IN_MS = "LAST_CONFIG_DOWNLOAD_IN_MS"; |
Filipe Gonçalves | 8b263ad | 2015-01-12 12:30:11 +0000 | [diff] [blame] | 70 | private static final int CONFIG_FILE_DOWNLOAD_TIMEOUT_MILLIS = 23500; |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 71 | public static final String EXTRA_FORCE_CONFIG_FILE_DOWNLOAD = "FORCE_DOWNLOAD"; |
| 72 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 73 | private static final String TAG = UpdaterService.class.getSimpleName(); |
| 74 | |
Jose Pascoal | c2545cc | 2014-12-18 16:51:52 +0000 | [diff] [blame] | 75 | public static final String PREFERENCE_LAST_CONFIG_DOWNLOAD_ID = "LastConfigDownloadId"; |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 76 | public static final String PREFERENCE_REINSTALL_GAPPS = "ReinstallGappsOmnStartUp"; |
Filipe Gonçalves | 80d4b15 | 2015-05-26 19:04:02 +0100 | [diff] [blame] | 77 | public static final String PREFERENCE_CONFIG_MD_5 = "CONFIG_MD5"; |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 78 | private DownloadManager mDownloadManager = null; |
| 79 | private DownloadBroadCastReceiver mDownloadBroadCastReceiver = null; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 80 | |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 81 | private static final int MAX_DOWNLOAD_RETRIES = 3; |
| 82 | private int mDownloadRetries; |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 83 | private long mLatestFileDownloadId; |
Filipe Gonçalves | d28bd62 | 2014-11-05 11:40:12 +0000 | [diff] [blame] | 84 | private boolean mInternetConnectionAvailable; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 85 | |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 86 | private SharedPreferences mSharedPreferences; |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 87 | |
Jose Pascoal | b03b55c | 2015-02-19 17:34:07 +0000 | [diff] [blame] | 88 | private final static long DOWNLOAD_GRACE_PERIOD_IN_MS = 24 /* hour */ * Utils.MINUTES_IN_HOUR /* minute */ * Utils.SECONDS_IN_MINUTE /* second */ * 1000 /* millisecond */; |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 89 | private BroadcastReceiver networkStateReceiver; |
Jose Pascoal | 29ee101 | 2014-09-12 17:25:36 +0100 | [diff] [blame] | 90 | |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 91 | @Override |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 92 | public int onStartCommand(Intent intent, int flags, int startId) |
| 93 | { |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 94 | // remove the logs |
| 95 | clearDataLogs(); |
Jose Pascoal | da00b38 | 2015-01-20 18:39:28 +0000 | [diff] [blame] | 96 | |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 97 | if(Utils.isDeviceUnsupported(getApplicationContext())){ |
Jose Pascoal | da00b38 | 2015-01-20 18:39:28 +0000 | [diff] [blame] | 98 | stopSelf(); |
| 99 | return START_NOT_STICKY; |
| 100 | } |
Jose Pascoal | 29ee101 | 2014-09-12 17:25:36 +0100 | [diff] [blame] | 101 | |
Jose Pascoal | 7bf83a0 | 2014-10-13 18:30:18 +0100 | [diff] [blame] | 102 | mSharedPreferences = getApplicationContext().getSharedPreferences(FairphoneUpdater.FAIRPHONE_UPDATER_PREFERENCES, MODE_PRIVATE); |
Jose Pascoal | 29ee101 | 2014-09-12 17:25:36 +0100 | [diff] [blame] | 103 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 104 | mLatestFileDownloadId = mSharedPreferences.getLong(PREFERENCE_LAST_CONFIG_DOWNLOAD_ID, 0); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 105 | |
Jose Pascoal | aa579a8 | 2014-11-05 22:17:16 +0000 | [diff] [blame] | 106 | setupDownloadManager(); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 107 | |
Filipe Gonçalves | d28bd62 | 2014-11-05 11:40:12 +0000 | [diff] [blame] | 108 | setupConnectivityMonitoring(); |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 109 | |
Maarten Derks | bf5f51c | 2016-05-31 14:38:26 +0200 | [diff] [blame] | 110 | if(Utils.isInternetEnabled(getApplicationContext())) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 111 | { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 112 | downloadConfigFile(intent != null && intent.getBooleanExtra(EXTRA_FORCE_CONFIG_FILE_DOWNLOAD, false)); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | // setup the gapps installer |
Jose Pascoal | 4091630 | 2015-02-06 18:43:47 +0000 | [diff] [blame] | 116 | GappsInstallerHelper.checkGappsAreInstalled(getApplicationContext()); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 117 | |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 118 | runInstallationDisclaimer(getApplicationContext()); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 119 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 120 | return Service.START_STICKY; |
| 121 | } |
| 122 | |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 123 | private static void runInstallationDisclaimer(Context context) |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 124 | { |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 125 | SharedPreferences sharedPreferences = context.getApplicationContext().getSharedPreferences(FairphoneUpdater.FAIRPHONE_UPDATER_PREFERENCES, MODE_PRIVATE); |
| 126 | if (sharedPreferences.getBoolean(PREFERENCE_REINSTALL_GAPPS, true) && !UpdaterData.getInstance().isAppStoreListEmpty()) |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 127 | { |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 128 | if(!GappsInstallerHelper.areGappsInstalled()){ |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 129 | showReinstallAlert(context); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 130 | } |
| 131 | |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 132 | Editor editor = sharedPreferences.edit(); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 133 | editor.putBoolean(PREFERENCE_REINSTALL_GAPPS, false); |
| 134 | |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 135 | editor.apply(); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 136 | } |
| 137 | } |
| 138 | |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 139 | private static void showReinstallAlert(Context context) |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 140 | { |
Filipe Gonçalves | 825414a | 2015-01-26 14:52:48 +0000 | [diff] [blame] | 141 | if ( FairphoneUpdater.BETA_MODE_ENABLED ) |
Jose Pascoal | 4091630 | 2015-02-06 18:43:47 +0000 | [diff] [blame] | 142 | { |
Filipe Gonçalves | 825414a | 2015-01-26 14:52:48 +0000 | [diff] [blame] | 143 | return; |
Jose Pascoal | 4091630 | 2015-02-06 18:43:47 +0000 | [diff] [blame] | 144 | } |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 145 | |
| 146 | NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 147 | |
Tiago Costa | 73575aa | 2015-01-19 15:48:26 +0000 | [diff] [blame] | 148 | //Intent notificationIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getResources().getString(R.string.supportAppStoreUrl))); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 149 | |
Tiago Costa | 73575aa | 2015-01-19 15:48:26 +0000 | [diff] [blame] | 150 | Intent notificationIntent = new Intent(context, FairphoneUpdater.class); |
| 151 | notificationIntent.setAction(GappsInstallerHelper.EXTRA_START_GAPPS_INSTALL); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 152 | |
Tiago Costa | 73575aa | 2015-01-19 15:48:26 +0000 | [diff] [blame] | 153 | PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 154 | |
Maarten Derks | 060032c | 2016-03-04 11:17:58 +0100 | [diff] [blame] | 155 | NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.updater_white) |
Filipe Gonçalves | 071b675 | 2015-06-24 12:37:32 +0100 | [diff] [blame] | 156 | .setContentTitle(context.getResources().getString(R.string.app_full_name)) |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 157 | .setContentText(context.getResources().getString(R.string.appStoreReinstall)) |
| 158 | .setAutoCancel(true) |
| 159 | .setDefaults(Notification.DEFAULT_SOUND) |
| 160 | .setContentIntent(contentIntent); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 161 | |
| 162 | mNotificationManager.notify(0, mBuilder.build()); |
| 163 | } |
| 164 | |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 165 | private void downloadConfigFile(boolean forceDownload) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 166 | { |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 167 | long now = System.currentTimeMillis(); |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 168 | long last_download = mSharedPreferences.getLong(LAST_CONFIG_DOWNLOAD_IN_MS, 0L); |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 169 | if( forceDownload || now > (last_download + DOWNLOAD_GRACE_PERIOD_IN_MS) ) { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 170 | Log.i(TAG, "Downloading updater configuration file."); |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 171 | // remove the old file if its still there for some reason |
| 172 | removeLatestFileDownload(getApplicationContext()); |
| 173 | |
| 174 | // start the download of the latest file |
| 175 | startDownloadLatest(); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 176 | |
Jose Pascoal | 0b48f8d | 2015-02-06 16:06:41 +0000 | [diff] [blame] | 177 | mSharedPreferences.edit().putLong(LAST_CONFIG_DOWNLOAD_IN_MS, now).apply(); |
Filipe Gonçalves | 8f226b0 | 2014-12-12 11:21:58 +0000 | [diff] [blame] | 178 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 179 | } |
| 180 | |
Jose Pascoal | cdd8204 | 2015-02-06 13:04:26 +0000 | [diff] [blame] | 181 | // --Commented out by Inspection START (06/02/2015 12:27): |
| 182 | // public void updateGoogleAppsIntallerWidgets() |
| 183 | // { |
| 184 | // AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this); |
| 185 | // int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(this, GoogleAppsInstallerWidget.class)); |
| 186 | // if (appWidgetIds.length > 0) |
| 187 | // { |
| 188 | // new GoogleAppsInstallerWidget().onUpdate(this, appWidgetManager, appWidgetIds); |
| 189 | // } |
| 190 | // } |
| 191 | // --Commented out by Inspection STOP (06/02/2015 12:27) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 192 | |
Jose Pascoal | cfc2dd4 | 2015-02-09 18:00:05 +0000 | [diff] [blame] | 193 | private static void clearDataLogs() |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 194 | { |
Filipe Gonçalves | 49ce23c | 2015-02-13 16:33:52 +0000 | [diff] [blame] | 195 | if (PrivilegeChecker.isPrivilegedApp()) { |
| 196 | clearDataLogsPrivileged(); |
| 197 | } else { |
| 198 | clearDataLogsUnprivileged(); |
Tiago Costa | c14ea24 | 2014-04-24 10:14:41 +0100 | [diff] [blame] | 199 | } |
| 200 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 201 | |
Filipe Gonçalves | 49ce23c | 2015-02-13 16:33:52 +0000 | [diff] [blame] | 202 | private static void clearDataLogsPrivileged() |
| 203 | { |
| 204 | try |
| 205 | { |
| 206 | Log.d(TAG, "Clearing dump log data..."); |
| 207 | Process p = Runtime.getRuntime().exec("rm /data/log_other_mode/*_log"); |
| 208 | try |
| 209 | { |
| 210 | p.waitFor(); |
| 211 | } catch (InterruptedException e) |
| 212 | { |
| 213 | e.printStackTrace(); |
| 214 | } |
| 215 | } catch (IOException e) |
| 216 | { |
| 217 | Log.d(TAG, "Clearing dump log data failed: " + e.getLocalizedMessage()); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | private static void clearDataLogsUnprivileged() |
| 222 | { |
| 223 | try |
| 224 | { |
| 225 | Log.d(TAG, "Clearing dump log data..."); |
| 226 | Shell.runCommand(new CommandCapture(0, "rm /data/log_other_mode/*_log")); |
| 227 | } catch (IOException | TimeoutException e) |
| 228 | { |
| 229 | Log.d(TAG, "Clearing dump log data failed: " + e.getLocalizedMessage()); |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 234 | @Override |
| 235 | public IBinder onBind(Intent intent) |
| 236 | { |
| 237 | return null; |
| 238 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 239 | |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 240 | void startDownloadLatest() |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 241 | { |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 242 | Resources resources = getApplicationContext().getResources(); |
| 243 | String downloadLink = getConfigDownloadLink(getApplicationContext()); |
| 244 | // set the download for the latest version on the download manager |
| 245 | Request request = createDownloadRequest(downloadLink, resources.getString(R.string.configFilename) + resources.getString(R.string.config_zip)); |
Maarten Derks | 750ca5c | 2016-06-16 09:12:24 +0200 | [diff] [blame^] | 246 | request.setNotificationVisibility(Request.VISIBILITY_HIDDEN); |
Jose Pascoal | fd3e43c | 2014-05-22 20:29:17 +0100 | [diff] [blame] | 247 | |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 248 | if (request != null && mDownloadManager != null) |
| 249 | { |
Maarten Derks | bf5f51c | 2016-05-31 14:38:26 +0200 | [diff] [blame] | 250 | // Allow download over mobile data and Wi-Fi |
| 251 | request.setAllowedNetworkTypes(Request.NETWORK_MOBILE|Request.NETWORK_WIFI); |
| 252 | |
Jose Pascoal | 8775874 | 2015-01-28 20:00:22 +0000 | [diff] [blame] | 253 | //Guarantee that only we have only one download |
| 254 | long oldDownloadId = mSharedPreferences.getLong(PREFERENCE_LAST_CONFIG_DOWNLOAD_ID, 0); |
| 255 | if(oldDownloadId != 0){ |
| 256 | mDownloadManager.remove(oldDownloadId); |
| 257 | saveLatestDownloadId(0); |
| 258 | } |
| 259 | |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 260 | mLatestFileDownloadId = mDownloadManager.enqueue(request); |
| 261 | saveLatestDownloadId(mLatestFileDownloadId); |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 262 | |
| 263 | final long currentId = mLatestFileDownloadId; |
| 264 | // Cancel download if it is stuck since DownloadManager doesn't seem able to do it. |
| 265 | new Handler().postAtTime(new Runnable() { |
| 266 | @Override |
| 267 | public void run() { |
Jose Pascoal | 46fdb06 | 2015-02-05 18:59:32 +0000 | [diff] [blame] | 268 | onDownloadStatus(currentId, new Runnable() { |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 269 | @Override |
| 270 | public void run() { |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 271 | Log.w(TAG, "Configuration file download timed out"); |
| 272 | mDownloadManager.remove(currentId); |
Jose Pascoal | 0b48f8d | 2015-02-06 16:06:41 +0000 | [diff] [blame] | 273 | mSharedPreferences.edit().remove(LAST_CONFIG_DOWNLOAD_IN_MS).apply(); |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 274 | } |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 275 | }); |
Filipe Gonçalves | b2536c0 | 2015-01-12 11:50:25 +0000 | [diff] [blame] | 276 | } |
Filipe Gonçalves | 8b263ad | 2015-01-12 12:30:11 +0000 | [diff] [blame] | 277 | }, SystemClock.uptimeMillis() + CONFIG_FILE_DOWNLOAD_TIMEOUT_MILLIS); |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 278 | } |
| 279 | else |
| 280 | { |
| 281 | Log.e(TAG, "Invalid request for link " + downloadLink); |
| 282 | Intent i = new Intent(FairphoneUpdater.FAIRPHONE_UPDATER_CONFIG_DOWNLOAD_FAILED); |
| 283 | i.putExtra(FairphoneUpdater.FAIRPHONE_UPDATER_CONFIG_DOWNLOAD_LINK, downloadLink); |
| 284 | sendBroadcast(i); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 285 | } |
| 286 | } |
| 287 | |
Jose Pascoal | c2545cc | 2014-12-18 16:51:52 +0000 | [diff] [blame] | 288 | private void saveLatestDownloadId(long id) |
| 289 | { |
| 290 | mLatestFileDownloadId = id; |
| 291 | Editor editor = mSharedPreferences.edit(); |
| 292 | editor.putLong(PREFERENCE_LAST_CONFIG_DOWNLOAD_ID, id); |
| 293 | editor.commit(); |
| 294 | } |
| 295 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 296 | private String getConfigDownloadLink(Context context) |
| 297 | { |
| 298 | |
| 299 | Resources resources = context.getResources(); |
| 300 | |
| 301 | StringBuilder sb = new StringBuilder(); |
Filipe Gonçalves | afeac2c | 2015-01-27 17:49:53 +0000 | [diff] [blame] | 302 | String download_url = mSharedPreferences.getString(FairphoneUpdater.PREFERENCE_OTA_DOWNLOAD_URL, getResources().getString(R.string.downloadUrl)); |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 303 | |
| 304 | sb.append(download_url); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 305 | sb.append(Build.MODEL.replaceAll("\\s", "")); |
Jose Pascoal | 0a5be01 | 2014-11-17 16:55:40 +0000 | [diff] [blame] | 306 | sb.append(Utils.getPartitionDownloadPath(resources)); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 307 | sb.append("/"); |
| 308 | |
| 309 | sb.append(resources.getString(R.string.configFilename)); |
| 310 | |
| 311 | sb.append(resources.getString(R.string.config_zip)); |
| 312 | |
Maarten Derks | ab3a986 | 2016-04-19 11:38:41 +0200 | [diff] [blame] | 313 | addUrlParameters(context, sb); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 314 | |
| 315 | String downloadLink = sb.toString(); |
| 316 | |
| 317 | Log.d(TAG, "Download link: " + downloadLink); |
| 318 | |
| 319 | return downloadLink; |
| 320 | } |
Jose Pascoal | cf13fde | 2014-05-21 20:17:17 +0100 | [diff] [blame] | 321 | |
Maarten Derks | ab3a986 | 2016-04-19 11:38:41 +0200 | [diff] [blame] | 322 | private static void addUrlParameters(Context context, StringBuilder sb) |
Tiago Costa | b24ef1c | 2014-07-25 12:02:34 +0100 | [diff] [blame] | 323 | { |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 324 | sb.append("?"); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 325 | Version currentVersion = VersionParserHelper.getDeviceVersion(context.getApplicationContext()); |
| 326 | |
Maarten Derks | ab3a986 | 2016-04-19 11:38:41 +0200 | [diff] [blame] | 327 | if (currentVersion != null) { |
Filipe Gonçalves | cd0f33d | 2014-12-15 15:05:15 +0000 | [diff] [blame] | 328 | try { |
| 329 | final String defaultCharset = Charset.defaultCharset().displayName(); |
Maarten Derks | ab3a986 | 2016-04-19 11:38:41 +0200 | [diff] [blame] | 330 | |
| 331 | String modelWithoutSpaces = Build.MODEL.replaceAll("\\s", ""); |
| 332 | if(modelWithoutSpaces.startsWith(context.getResources().getString(R.string.FP1Model))) { |
| 333 | sb.append("&b_n=").append(URLEncoder.encode(currentVersion.getBuildNumber(), defaultCharset)); |
| 334 | } |
Maarten Derks | f17e6db | 2016-02-09 15:10:53 +0100 | [diff] [blame] | 335 | sb.append("&ota_v_n=").append(URLEncoder.encode(String.valueOf(currentVersion.getId()), defaultCharset)); |
Maarten Derks | a02f4f1 | 2016-05-26 17:04:58 +0200 | [diff] [blame] | 336 | sb.append("&beta=").append(FairphoneUpdater.BETA_MODE_ENABLED ? BetaEnabler.BETA_ENABLED : BetaEnabler.BETA_DISABLED); |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 337 | sb.append("&dev=").append(FairphoneUpdater.DEV_MODE_ENABLED ? "1" : "0"); |
Filipe Gonçalves | cd0f33d | 2014-12-15 15:05:15 +0000 | [diff] [blame] | 338 | } catch (UnsupportedEncodingException e) { |
| 339 | Log.e(TAG, "Failed to add extra info on update request: "+e.getLocalizedMessage()); |
| 340 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 341 | } |
Tiago Costa | b24ef1c | 2014-07-25 12:02:34 +0100 | [diff] [blame] | 342 | } |
| 343 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 344 | private static void setNotification(Context currentContext) |
| 345 | { |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 346 | |
Filipe Gonçalves | 825414a | 2015-01-26 14:52:48 +0000 | [diff] [blame] | 347 | if ( FairphoneUpdater.BETA_MODE_ENABLED ) |
Jose Pascoal | 4091630 | 2015-02-06 18:43:47 +0000 | [diff] [blame] | 348 | { |
Filipe Gonçalves | 825414a | 2015-01-26 14:52:48 +0000 | [diff] [blame] | 349 | return; |
Jose Pascoal | 4091630 | 2015-02-06 18:43:47 +0000 | [diff] [blame] | 350 | } |
Filipe Gonçalves | 825414a | 2015-01-26 14:52:48 +0000 | [diff] [blame] | 351 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 352 | Context context = currentContext.getApplicationContext(); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 353 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 354 | NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 355 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 356 | NotificationCompat.Builder builder = |
telmo.agostinho | 1378e44 | 2016-01-22 15:50:04 +0000 | [diff] [blame] | 357 | new NotificationCompat.Builder(context).setSmallIcon(R.drawable.updater_white) |
Filipe Gonçalves | 071b675 | 2015-06-24 12:37:32 +0100 | [diff] [blame] | 358 | .setContentTitle(context.getResources().getString(R.string.app_full_name)) |
Pedro Arelo | 773bd82 | 2014-10-10 11:57:34 +0100 | [diff] [blame] | 359 | .setContentText(context.getResources().getString(R.string.fairphone_update_message)); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 360 | |
Jose Pascoal | 7bf83a0 | 2014-10-13 18:30:18 +0100 | [diff] [blame] | 361 | Intent resultIntent = new Intent(context, FairphoneUpdater.class); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 362 | TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 363 | |
Jose Pascoal | 7bf83a0 | 2014-10-13 18:30:18 +0100 | [diff] [blame] | 364 | stackBuilder.addParentStack(FairphoneUpdater.class); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 365 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 366 | stackBuilder.addNextIntent(resultIntent); |
| 367 | PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 368 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 369 | builder.setContentIntent(resultPendingIntent); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 370 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 371 | Notification notificationWhileRunnig = builder.build(); |
Jose Pascoal | fd3e43c | 2014-05-22 20:29:17 +0100 | [diff] [blame] | 372 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 373 | // Add notification |
| 374 | manager.notify(0, notificationWhileRunnig); |
| 375 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 376 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 377 | private Request createDownloadRequest(String url, String fileName) |
| 378 | { |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 379 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 380 | Resources resources = getApplicationContext().getResources(); |
| 381 | Request request; |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 382 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 383 | try |
| 384 | { |
| 385 | request = new Request(Uri.parse(url)); |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 386 | final File externalStoragePublicDirectory = Environment.getExternalStoragePublicDirectory(Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder)); |
Jose Pascoal | 46fdb06 | 2015-02-05 18:59:32 +0000 | [diff] [blame] | 387 | final boolean notMkDirs = !externalStoragePublicDirectory.mkdirs(); |
| 388 | if(notMkDirs && !externalStoragePublicDirectory.exists()) { |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 389 | throw new Exception("Couldn't create updater dir structures."); |
| 390 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 391 | |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 392 | request.setDestinationInExternalPublicDir(resources.getString(R.string.updaterFolder), fileName); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 393 | request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); |
| 394 | request.setAllowedOverRoaming(false); |
Pedro Arelo | 773bd82 | 2014-10-10 11:57:34 +0100 | [diff] [blame] | 395 | request.setTitle(resources.getString(R.string.fairphone_update_message_title)); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 396 | } catch (Exception e) |
| 397 | { |
| 398 | Log.e(TAG, "Error creating request: " + e.getMessage()); |
| 399 | request = null; |
| 400 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 401 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 402 | return request; |
| 403 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 404 | |
Filipe Gonçalves | d28bd62 | 2014-11-05 11:40:12 +0000 | [diff] [blame] | 405 | private void setupConnectivityMonitoring() |
| 406 | { |
| 407 | |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 408 | if (networkStateReceiver == null) { |
| 409 | // Check current connectivity status |
Maarten Derks | bf5f51c | 2016-05-31 14:38:26 +0200 | [diff] [blame] | 410 | mInternetConnectionAvailable = Utils.isInternetEnabled(getApplicationContext()); |
Filipe Gonçalves | d28bd62 | 2014-11-05 11:40:12 +0000 | [diff] [blame] | 411 | |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 412 | // Setup monitoring for future connectivity status changes |
| 413 | networkStateReceiver = new BroadcastReceiver() |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 414 | { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 415 | @Override |
| 416 | public void onReceive(Context context, Intent intent) |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 417 | { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 418 | if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) { |
| 419 | Log.i(TAG, "Lost network connectivity."); |
| 420 | mInternetConnectionAvailable = false; |
| 421 | if (mLatestFileDownloadId != 0 && mDownloadManager != null) |
| 422 | { |
| 423 | onDownloadStatus(mLatestFileDownloadId, new Runnable() { |
| 424 | @Override |
| 425 | public void run() { |
| 426 | Log.d(TAG, "Removing pending download."); |
| 427 | mDownloadManager.remove(mLatestFileDownloadId); |
| 428 | saveLatestDownloadId(0); |
| 429 | } |
| 430 | }); |
| 431 | } |
| 432 | } |
| 433 | else |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 434 | { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 435 | int conn_type = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_DUMMY); |
Maarten Derks | bf5f51c | 2016-05-31 14:38:26 +0200 | [diff] [blame] | 436 | if( conn_type == ConnectivityManager.TYPE_WIFI || conn_type == ConnectivityManager.TYPE_MOBILE) { |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 437 | Log.i(TAG, "Network connectivity potentially available."); |
| 438 | if (!mInternetConnectionAvailable) { |
| 439 | downloadConfigFile(false); |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 440 | } |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 441 | mInternetConnectionAvailable = true; |
| 442 | } |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 443 | } |
| 444 | } |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 445 | }; |
Filipe Gonçalves | d28bd62 | 2014-11-05 11:40:12 +0000 | [diff] [blame] | 446 | |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 447 | IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); |
| 448 | registerReceiver(networkStateReceiver, filter); |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 449 | |
Filipe Gonçalves | 4089313 | 2015-05-25 17:45:44 +0100 | [diff] [blame] | 450 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 451 | } |
| 452 | |
| 453 | private void setupDownloadManager() |
| 454 | { |
| 455 | if (mDownloadManager == null) |
| 456 | { |
| 457 | mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); |
| 458 | } |
| 459 | |
Filipe Gonçalves | d0dfe91 | 2014-11-04 16:24:25 +0000 | [diff] [blame] | 460 | if (mDownloadBroadCastReceiver == null) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 461 | { |
| 462 | mDownloadBroadCastReceiver = new DownloadBroadCastReceiver(); |
| 463 | |
| 464 | getApplicationContext().registerReceiver(mDownloadBroadCastReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); |
| 465 | } |
| 466 | } |
| 467 | |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 468 | private static void copyConfigToData(Context context) throws IOException { |
| 469 | Resources resources = context.getApplicationContext().getResources(); |
| 470 | String targetPath = Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder); |
| 471 | FileInputStream inStream = new FileInputStream(targetPath + resources.getString(R.string.configFilename) + resources.getString(R.string.config_xml)); |
| 472 | FileOutputStream outStream = context.openFileOutput(resources.getString(R.string.configFilename) + resources.getString(R.string.config_xml), MODE_PRIVATE); |
| 473 | FileChannel inChannel = inStream.getChannel(); |
| 474 | FileChannel outChannel = outStream.getChannel(); |
| 475 | inChannel.transferTo(0, inChannel.size(), outChannel); |
| 476 | inStream.close(); |
| 477 | outStream.close(); |
| 478 | } |
| 479 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 480 | private static void checkVersionValidation(Context context) |
| 481 | { |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 482 | Version latestVersion = VersionParserHelper.getLatestVersion(context.getApplicationContext()); |
| 483 | Version currentVersion = VersionParserHelper.getDeviceVersion(context.getApplicationContext()); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 484 | if (latestVersion != null) |
| 485 | { |
| 486 | if (latestVersion.isNewerVersionThan(currentVersion)) |
| 487 | { |
| 488 | setNotification(context); |
| 489 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 490 | } |
Filipe Gonçalves | a75e181 | 2015-03-19 12:12:07 +0000 | [diff] [blame] | 491 | runInstallationDisclaimer(context); |
Jose Pascoal | d5e4d4a | 2015-03-13 18:17:48 +0000 | [diff] [blame] | 492 | |
| 493 | // to update the activity |
| 494 | Intent updateIntent = new Intent(FairphoneUpdater.FAIRPHONE_UPDATER_NEW_VERSION_RECEIVED); |
| 495 | context.sendBroadcast(updateIntent); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 496 | } |
| 497 | |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 498 | public static boolean readUpdaterData(Context context){ |
| 499 | Version latestVersion = VersionParserHelper.getLatestVersion(context.getApplicationContext()); |
| 500 | return latestVersion != null; |
| 501 | } |
| 502 | |
| 503 | public static boolean updateUpdaterData(Context context) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 504 | { |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 505 | |
| 506 | boolean retVal = false; |
| 507 | Resources resources = context.getApplicationContext().getResources(); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 508 | String targetPath = Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder); |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 509 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 510 | String filePath = targetPath + resources.getString(R.string.configFilename) + resources.getString(R.string.config_zip); |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 511 | |
| 512 | File file = new File(filePath); |
| 513 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 514 | if (file.exists()) |
| 515 | { |
Filipe Gonçalves | 80d4b15 | 2015-05-26 19:04:02 +0100 | [diff] [blame] | 516 | String md5sum = Utils.calculateMD5(file); |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 517 | SharedPreferences sp = context.getApplicationContext().getSharedPreferences(FairphoneUpdater.FAIRPHONE_UPDATER_PREFERENCES, MODE_PRIVATE); |
Filipe Gonçalves | 80d4b15 | 2015-05-26 19:04:02 +0100 | [diff] [blame] | 518 | if(sp.getString(PREFERENCE_CONFIG_MD_5, "").equals(md5sum)){ |
| 519 | retVal = true; |
Filipe Gonçalves | 80d4b15 | 2015-05-26 19:04:02 +0100 | [diff] [blame] | 520 | } else { |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 521 | if (RSAUtils.checkFileSignature(context, filePath, targetPath)) { |
| 522 | try { |
| 523 | copyConfigToData(context); |
| 524 | checkVersionValidation(context); |
| 525 | retVal = true; |
| 526 | sp.edit().putString(PREFERENCE_CONFIG_MD_5, md5sum).apply(); |
| 527 | } catch (IOException e) { |
| 528 | Log.e(TAG, "Failed to store configuration " + e.getLocalizedMessage()); |
| 529 | retVal = false; |
| 530 | } |
| 531 | } else { |
| 532 | //Toast.makeText(context, resources.getString(R.string.invalid_signature_download_message), Toast.LENGTH_LONG).show(); |
| 533 | final boolean notDeleted = !file.delete(); |
| 534 | if(notDeleted) { |
| 535 | Log.d(TAG, "Unable to delete "+file.getAbsolutePath()); |
| 536 | } |
Filipe Gonçalves | b31d586 | 2015-02-04 17:28:58 +0000 | [diff] [blame] | 537 | |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 538 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 539 | } |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 540 | } else { |
| 541 | Log.wtf(TAG, "No file"); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 542 | } |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 543 | |
| 544 | return retVal; |
| 545 | } |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 546 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 547 | private void removeLatestFileDownload(Context context) |
| 548 | { |
| 549 | if (mLatestFileDownloadId != 0 && mDownloadManager != null) |
| 550 | { |
| 551 | mDownloadManager.remove(mLatestFileDownloadId); |
Jose Pascoal | c2545cc | 2014-12-18 16:51:52 +0000 | [diff] [blame] | 552 | saveLatestDownloadId(0); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 553 | } |
Jose Pascoal | c2545cc | 2014-12-18 16:51:52 +0000 | [diff] [blame] | 554 | VersionParserHelper.removeConfigFiles(context); |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 555 | } |
| 556 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 557 | private boolean retryDownload(Context context) |
| 558 | { |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 559 | Log.d(TAG, "Retry "+mDownloadRetries+" of "+MAX_DOWNLOAD_RETRIES); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 560 | // invalid file |
| 561 | boolean removeReceiver = true; |
| 562 | removeLatestFileDownload(context); |
| 563 | if (mDownloadRetries < MAX_DOWNLOAD_RETRIES) |
| 564 | { |
| 565 | startDownloadLatest(); |
| 566 | mDownloadRetries++; |
| 567 | removeReceiver = false; |
| 568 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 569 | return removeReceiver; |
| 570 | } |
Jose Pascoal | 0e96628 | 2014-08-12 18:49:05 +0100 | [diff] [blame] | 571 | |
Jose Pascoal | 46fdb06 | 2015-02-05 18:59:32 +0000 | [diff] [blame] | 572 | private void onDownloadStatus(long id, Runnable ifRunning) { |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 573 | Cursor cursor = mDownloadManager != null ? mDownloadManager.query(new DownloadManager.Query().setFilterById(id)) : null; |
| 574 | if (cursor != null && cursor.moveToFirst()) |
| 575 | { |
| 576 | int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); |
| 577 | switch(status){ |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 578 | case DownloadManager.STATUS_PAUSED: |
| 579 | if (ifRunning != null) { |
| 580 | ifRunning.run(); |
| 581 | } |
| 582 | break; |
| 583 | case DownloadManager.STATUS_PENDING: |
| 584 | if (ifRunning != null) { |
| 585 | ifRunning.run(); |
| 586 | } |
| 587 | break; |
| 588 | case DownloadManager.STATUS_RUNNING: |
| 589 | if (ifRunning != null) { |
| 590 | ifRunning.run(); |
| 591 | } |
| 592 | break; |
Jose Pascoal | 46fdb06 | 2015-02-05 18:59:32 +0000 | [diff] [blame] | 593 | case DownloadManager.STATUS_FAILED: |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 594 | case DownloadManager.STATUS_SUCCESSFUL: |
Filipe Gonçalves | 712d548 | 2015-01-13 17:00:44 +0000 | [diff] [blame] | 595 | default: |
| 596 | break; |
| 597 | } |
| 598 | } |
| 599 | if (cursor != null) |
| 600 | { |
| 601 | cursor.close(); |
| 602 | } |
| 603 | } |
| 604 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 605 | private class DownloadBroadCastReceiver extends BroadcastReceiver |
| 606 | { |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 607 | |
Jose Pascoal | 1ee56e2 | 2014-05-21 16:58:20 +0100 | [diff] [blame] | 608 | @Override |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 609 | public void onReceive(Context context, Intent intent) |
| 610 | { |
Kim Hansen | 086964d | 2013-12-10 11:33:28 +0000 | [diff] [blame] | 611 | |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 612 | boolean removeReceiver = false; |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 613 | DownloadManager.Query query = new DownloadManager.Query(); |
| 614 | |
| 615 | query.setFilterById(mLatestFileDownloadId); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 616 | |
Jose Pascoal | aa579a8 | 2014-11-05 22:17:16 +0000 | [diff] [blame] | 617 | Cursor cursor = mDownloadManager != null ? mDownloadManager.query(query) : null; |
| 618 | |
| 619 | if (cursor != null && cursor.moveToFirst()) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 620 | { |
| 621 | int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS); |
| 622 | int status = cursor.getInt(columnIndex); |
| 623 | Resources resources = context.getApplicationContext().getResources(); |
| 624 | |
| 625 | switch (status) |
| 626 | { |
| 627 | case DownloadManager.STATUS_SUCCESSFUL: |
| 628 | { |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 629 | Log.d(TAG, "Download successful."); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 630 | |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 631 | if (updateUpdaterData(context)) |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 632 | { |
Filipe Gonçalves | 4cc0b2e | 2015-05-27 18:12:40 +0100 | [diff] [blame] | 633 | removeLatestFileDownload(context); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 634 | } |
| 635 | else |
| 636 | { |
Pedro Arelo | 773bd82 | 2014-10-10 11:57:34 +0100 | [diff] [blame] | 637 | Toast.makeText(getApplicationContext(), resources.getString(R.string.invalid_signature_download_message), Toast.LENGTH_LONG).show(); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 638 | removeReceiver = retryDownload(context); |
| 639 | } |
| 640 | break; |
| 641 | } |
| 642 | case DownloadManager.STATUS_FAILED: |
| 643 | { |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 644 | Log.d(TAG, "Download failed."); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 645 | removeReceiver = retryDownload(context); |
| 646 | break; |
| 647 | } |
Filipe Gonçalves | 42ffc32 | 2015-01-28 12:51:14 +0000 | [diff] [blame] | 648 | default: |
| 649 | { |
| 650 | Log.d(TAG, "Status broadcast on mLatestFileDownloadId ("+mLatestFileDownloadId+"): "+ status); |
| 651 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 652 | } |
| 653 | } |
Tiago Costa | 87925fe | 2014-12-02 17:57:51 +0000 | [diff] [blame] | 654 | |
Jose Pascoal | aa579a8 | 2014-11-05 22:17:16 +0000 | [diff] [blame] | 655 | if (cursor != null) |
| 656 | { |
| 657 | cursor.close(); |
| 658 | } |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 659 | |
| 660 | if (removeReceiver) |
| 661 | { |
Filipe Gonçalves | 5b65c01 | 2015-01-08 13:49:42 +0000 | [diff] [blame] | 662 | Log.d(TAG, "Configuration download failed. Clearing grace period."); |
Jose Pascoal | 0b48f8d | 2015-02-06 16:06:41 +0000 | [diff] [blame] | 663 | mSharedPreferences.edit().remove(LAST_CONFIG_DOWNLOAD_IN_MS).apply(); |
Jose Pascoal | 810950b | 2014-10-09 17:16:08 +0100 | [diff] [blame] | 664 | } |
| 665 | } |
| 666 | } |
telmo.agostinho | 1378e44 | 2016-01-22 15:50:04 +0000 | [diff] [blame] | 667 | } |