Skip to content

Commit

Permalink
Use FileProvider for installing WebAPKs on Android N
Browse files Browse the repository at this point in the history
Android N now bans installing APKs from world readable files and requires
FileProvider. See http://stackoverflow.com/questions/36755301/how-to-run-install-app-in-internal-files-dir

BUG=663800

Review-Url: https://codereview.chromium.org/2487353002
Cr-Commit-Position: refs/heads/master@{#431777}
  • Loading branch information
pkotwicz authored and Commit bot committed Nov 12, 2016
1 parent 5a6886d commit 14e9548
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
1 change: 1 addition & 0 deletions chrome/android/java/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="images" path="images/"/>
<cache-path name="cache" path="net-export/"/>
<cache-path name="webapk" path="webapks/" />

<!-- Note(twellington): This path is included to facilitate creating
content:// URIs for downloads. This may no longer work if/when users
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@

package org.chromium.chrome.browser.webapps;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;

import org.chromium.base.ApplicationState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.ContentUriUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.banners.InstallerDelegate;
import org.chromium.chrome.browser.util.IntentUtils;

import java.io.File;

Expand Down Expand Up @@ -87,16 +90,24 @@ private boolean installAsyncAndMonitorInstallationFromNative(
* @param filePath File to install.
*/
private boolean installDownloadedWebApk(String filePath) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri = Uri.fromFile(new File(filePath));
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
ContextUtils.getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
return false;
// TODO(pkotwicz|hanxi): For Chrome Stable figure out a different way of installing
// WebAPKs which does not involve enabling "installation from Unsigned Sources".
Context context = ContextUtils.getApplicationContext();
Intent intent;
File pathToInstall = new File(filePath);

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri = Uri.fromFile(pathToInstall);
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} else {
Uri source = ContentUriUtils.getContentUriFromFile(context, pathToInstall);
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(source);
}
return true;
return IntentUtils.safeStartActivity(context, intent);
}

private InstallerDelegate.Observer createInstallerDelegateObserver() {
Expand Down
3 changes: 2 additions & 1 deletion chrome/browser/android/webapk/webapk_installer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ void WebApkInstaller::OnCreatedSubDirAndSetPermissions(
return;
}

DownloadWebApk(output_dir.AppendASCII(webapk_package_), download_url, true);
DownloadWebApk(output_dir.AppendASCII(webapk_package_ + ".apk"),
download_url, true);
}

void WebApkInstaller::DownloadWebApk(const base::FilePath& output_path,
Expand Down

0 comments on commit 14e9548

Please sign in to comment.