-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10610 from wordpress-mobile/feature/enable_downlo…
…ads_from_private_sites Enable downloads from private sites
- Loading branch information
Showing
6 changed files
with
292 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderFileDownloadManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package org.wordpress.android.ui.reader | ||
|
||
import android.app.DownloadManager | ||
import android.content.BroadcastReceiver | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Environment | ||
import org.wordpress.android.ui.utils.AuthenticationUtils | ||
import org.wordpress.android.ui.utils.DownloadManagerWrapper | ||
import javax.inject.Inject | ||
|
||
class ReaderFileDownloadManager | ||
@Inject constructor( | ||
private val authenticationUtils: AuthenticationUtils, | ||
private val downloadManager: DownloadManagerWrapper | ||
) : BroadcastReceiver() { | ||
override fun onReceive(context: Context, intent: Intent) { | ||
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE == intent.action) { | ||
val downloadId = intent.getLongExtra( | ||
DownloadManager.EXTRA_DOWNLOAD_ID, 0 | ||
) | ||
openDownloadedAttachment(context, downloadId) | ||
} | ||
} | ||
|
||
fun downloadFile(fileUrl: String) { | ||
val request = downloadManager.buildRequest(fileUrl) | ||
|
||
for (entry in authenticationUtils.getAuthHeaders(fileUrl).entries) { | ||
request.addRequestHeader(entry.key, entry.value) | ||
} | ||
|
||
val fileName = downloadManager.guessUrl(fileUrl) | ||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) | ||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) | ||
request.setMimeType(downloadManager.getMimeType(fileUrl)) | ||
request.setTitle(fileName) | ||
request.allowScanningByMediaScanner() | ||
|
||
downloadManager.enqueue(request) | ||
} | ||
|
||
private fun openDownloadedAttachment(context: Context, downloadId: Long) { | ||
val query = downloadManager.buildQuery() | ||
query.setFilterById(downloadId) | ||
val cursor = downloadManager.query(query) | ||
if (cursor.moveToFirst()) { | ||
val downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) | ||
val downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)) | ||
val downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE)) | ||
if (downloadStatus == DownloadManager.STATUS_SUCCESSFUL && downloadLocalUri != null) { | ||
downloadManager.openDownloadedAttachment(context, downloadLocalUri, downloadMimeType) | ||
} | ||
} | ||
cursor.close() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
WordPress/src/main/java/org/wordpress/android/ui/utils/AuthenticationUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.wordpress.android.ui.utils | ||
|
||
import android.util.Base64 | ||
import org.wordpress.android.fluxc.network.HTTPAuthManager | ||
import org.wordpress.android.fluxc.network.UserAgent | ||
import org.wordpress.android.fluxc.network.rest.wpcom.auth.AccessToken | ||
import org.wordpress.android.util.WPUrlUtils | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Singleton | ||
class AuthenticationUtils | ||
@Inject constructor( | ||
private val accessToken: AccessToken, | ||
private val httpAuthManager: HTTPAuthManager, | ||
private val userAgent: UserAgent | ||
) { | ||
fun getAuthHeaders(url: String): Map<String, String> { | ||
val headers = mutableMapOf<String, String>() | ||
headers["User-Agent"] = userAgent.userAgent | ||
if (WPUrlUtils.safeToAddWordPressComAuthToken(url)) { | ||
if (accessToken.exists()) { | ||
headers["Authorization"] = "Bearer " + accessToken.get() | ||
} | ||
} else { | ||
// Check if we had HTTP Auth credentials for the root url | ||
val httpAuthModel = httpAuthManager.getHTTPAuthModel(url) | ||
if (httpAuthModel != null) { | ||
val creds = String.format("%s:%s", httpAuthModel.username, httpAuthModel.password) | ||
val auth = "Basic " + Base64.encodeToString(creds.toByteArray(), Base64.NO_WRAP) | ||
headers["Authorization"] = auth | ||
} | ||
} | ||
return headers | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
WordPress/src/main/java/org/wordpress/android/ui/utils/DownloadManagerWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.wordpress.android.ui.utils | ||
|
||
import android.app.DownloadManager | ||
import android.app.DownloadManager.Query | ||
import android.app.DownloadManager.Request | ||
import android.content.ActivityNotFoundException | ||
import android.content.ContentResolver | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.database.Cursor | ||
import android.net.Uri | ||
import android.webkit.MimeTypeMap | ||
import android.webkit.URLUtil | ||
import androidx.core.content.FileProvider | ||
import org.wordpress.android.BuildConfig | ||
import org.wordpress.android.util.AppLog | ||
import org.wordpress.android.util.AppLog.T | ||
import java.io.File | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Singleton | ||
class DownloadManagerWrapper | ||
@Inject constructor(private val context: Context) { | ||
fun enqueue(request: Request): Long = downloadManager().enqueue(request) | ||
|
||
fun buildRequest(fileUrl: String) = Request(Uri.parse(fileUrl)) | ||
|
||
fun query(query: Query): Cursor = downloadManager().query(query) | ||
|
||
fun buildQuery() = Query() | ||
|
||
fun guessUrl(fileUrl: String): String = URLUtil.guessUrl(fileUrl) | ||
|
||
fun getMimeType(url: String): String? { | ||
var type: String? = null | ||
val extension = MimeTypeMap.getFileExtensionFromUrl(url) | ||
if (extension != null) { | ||
val mime = MimeTypeMap.getSingleton() | ||
type = mime.getMimeTypeFromExtension(extension) | ||
} | ||
return type | ||
} | ||
|
||
private fun toPublicUri(fileUrl: String): Uri { | ||
val fileUri = Uri.parse(fileUrl) | ||
return if (ContentResolver.SCHEME_FILE == fileUri.scheme) { | ||
val file = File(fileUri.path) | ||
FileProvider.getUriForFile( | ||
context, | ||
"${BuildConfig.APPLICATION_ID}.provider", | ||
file | ||
) | ||
} else { | ||
fileUri | ||
} | ||
} | ||
|
||
fun openDownloadedAttachment( | ||
context: Context, | ||
fileUrl: String, | ||
attachmentMimeType: String | ||
) { | ||
val attachmentUri = toPublicUri(fileUrl) | ||
|
||
val openAttachmentIntent = Intent(Intent.ACTION_VIEW) | ||
openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType) | ||
openAttachmentIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK | ||
try { | ||
context.startActivity(openAttachmentIntent) | ||
} catch (e: ActivityNotFoundException) { | ||
AppLog.e(T.READER, "No browser found on the device: ${e.message}") | ||
} | ||
} | ||
|
||
private fun downloadManager() = | ||
(context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager) | ||
} |
Oops, something went wrong.