]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetUrlSize.java
Replace Android's download manager. https://redmine.stoutner.com/issues/528
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / asynctasks / GetUrlSize.java
1 /*
2  * Copyright © 2020 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.asynctasks;
21
22 import android.app.AlertDialog;
23 import android.content.Context;
24 import android.os.AsyncTask;
25 import android.webkit.CookieManager;
26 import android.widget.TextView;
27
28 import com.stoutner.privacybrowser.R;
29 import com.stoutner.privacybrowser.helpers.ProxyHelper;
30
31 import java.io.IOException;
32 import java.lang.ref.WeakReference;
33 import java.net.HttpURLConnection;
34 import java.net.Proxy;
35 import java.net.URL;
36 import java.text.NumberFormat;
37
38 public class GetUrlSize extends AsyncTask<String, Void, String> {
39     // Define a weak reference for the calling context and fragment.
40     private WeakReference<Context> contextWeakReference;
41     private WeakReference<AlertDialog> alertDialogWeakReference;
42
43     // Define the class variables.
44     private String userAgent;
45     private boolean cookiesEnabled;
46
47     // The public constructor.
48     public GetUrlSize(Context context, AlertDialog alertDialog, String userAgent, boolean cookiesEnabled) {
49         // Populate the week references to the calling activity and fragment.
50         contextWeakReference = new WeakReference<>(context);
51         alertDialogWeakReference = new WeakReference<>(alertDialog);
52
53         // Store the class variables.
54         this.userAgent = userAgent;
55         this.cookiesEnabled = cookiesEnabled;
56     }
57
58     @Override
59     protected String doInBackground(String... urlToSave) {
60         // Get a handle for the context and the fragment.
61         Context context = contextWeakReference.get();
62         AlertDialog alertDialog = alertDialogWeakReference.get();
63
64         // Abort if the fragment is gone.
65         if (alertDialog == null) {
66             return null;
67         }
68
69         // Initialize the formatted file size string.
70         String formattedFileSize = context.getString(R.string.unknown_size);
71
72         // Because everything relating to requesting data from a webserver can throw errors, the entire section much catch `IOExceptions`.
73         try {
74             // Get the URL from the calling fragment.
75             URL url = new URL(urlToSave[0]);
76
77             // Instantiate the proxy helper.
78             ProxyHelper proxyHelper = new ProxyHelper();
79
80             // Get the current proxy.
81             Proxy proxy = proxyHelper.getCurrentProxy(context);
82
83             // Open a connection to the URL.  No data is actually sent at this point.
84             HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
85
86             // Add the user agent to the header property.
87             httpURLConnection.setRequestProperty("User-Agent", userAgent);
88
89             // Add the cookies if they are enabled.
90             if (cookiesEnabled) {
91                 // Ge the cookies for the current domain.
92                 String cookiesString = CookieManager.getInstance().getCookie(url.toString());
93
94                 // Only add the cookies if they are not null.
95                 if (cookiesString != null) {
96                     // Add the cookies to the header property.
97                     httpURLConnection.setRequestProperty("Cookie", cookiesString);
98                 }
99             }
100
101             // The actual network request is in a `try` bracket so that `disconnect()` is run in the `finally` section even if an error is encountered in the main block.
102             try {
103                 // Exit if the task has been cancelled.
104                 if (isCancelled()) {
105                     // Disconnect the HTTP URL connection.
106                     httpURLConnection.disconnect();
107
108                     // Return the formatted file size string.
109                     return formattedFileSize;
110                 }
111
112                 // Get the status code.
113                 int responseCode = httpURLConnection.getResponseCode();
114
115                 // Exit if the task has been cancelled.
116                 if (isCancelled()) {
117                     // Disconnect the HTTP URL connection.
118                     httpURLConnection.disconnect();
119
120                     // Return the formatted file size string.
121                     return formattedFileSize;
122                 }
123
124                 // Check the response code.
125                 if (responseCode >= 400) {  // The response code is an error message.
126                     // Set the formatted file size to indicate a bad URL.
127                     formattedFileSize = context.getString(R.string.bad_url);
128                 } else {  // The response code is not an error message.
129                     // Get the content length header.
130                     String contentLengthString = httpURLConnection.getHeaderField("Content-Length");
131
132                     // Define the file size long.
133                     long fileSize;
134
135                     // Make sure the content length isn't null.
136                     if (contentLengthString != null) {  // The content length isn't null.
137                         // Convert the content length to a long.
138                         fileSize = Long.parseLong(contentLengthString);
139
140                         // Format the file size.
141                         formattedFileSize = NumberFormat.getInstance().format(fileSize) + " " + context.getString(R.string.bytes);
142                     }
143                 }
144             } finally {
145                 // Disconnect the HTTP URL connection.
146                 httpURLConnection.disconnect();
147             }
148         } catch (IOException exception) {
149             // Set the formatted file size to indicate a bad URL.
150             formattedFileSize = context.getString(R.string.bad_url);
151         }
152
153         // Return the formatted file size string.
154         return formattedFileSize;
155     }
156
157     // `onPostExecute()` operates on the UI thread.
158     @Override
159     protected void onPostExecute(String fileSize) {
160         // Get a handle for the context and alert dialog.
161         AlertDialog alertDialog = alertDialogWeakReference.get();
162
163         // Abort if the alert dialog is gone.
164         if (alertDialog == null) {
165             return;
166         }
167
168         // Get a handle for the file size text view.
169         TextView fileSizeTextView = alertDialog.findViewById(R.id.file_size_textview);
170
171         // Update the file size.
172         fileSizeTextView.setText(fileSize);
173     }
174 }