Search in sources :

Example 26 with Apk

use of org.fdroid.fdroid.data.Apk in project fdroidclient by f-droid.

the class AppUpdateStatusService method processDownloadedApk.

/**
 * Verifies that {@param apkPath} is a valid apk which the user intends to install.
 * If it is corrupted to the point where {@link PackageManager} can't read it, doesn't match the hash of any apk
 * we know about in our database, is not pending install, or is already installed, then it will return null.
 */
@Nullable
private Apk processDownloadedApk(File apkPath) {
    Utils.debugLog(TAG, "Checking " + apkPath);
    // https://gitlab.com/fdroid/fdroidclient/issues/1172
    if (!apkPath.exists()) {
        Log.i(TAG, "Was going to check " + apkPath + ", but it has since been removed from the cache.");
        return null;
    }
    PackageInfo downloadedInfo = getPackageManager().getPackageArchiveInfo(apkPath.getAbsolutePath(), PackageManager.GET_GIDS);
    if (downloadedInfo == null) {
        Log.i(TAG, "Skipping " + apkPath + " because PackageManager was unable to read it.");
        return null;
    }
    Utils.debugLog(TAG, "Found package for " + downloadedInfo.packageName + ':' + downloadedInfo.versionCode + ", checking its hash to see if it downloaded correctly.");
    Apk downloadedApk = findApkMatchingHash(apkPath);
    if (downloadedApk == null) {
        Log.i(TAG, "Either the apk wasn't downloaded fully, or the repo it came from has been disabled. " + "Either way, not notifying the user about it.");
        return null;
    }
    if (!AppUpdateStatusManager.getInstance(this).isPendingInstall(downloadedApk.hash)) {
        Log.i(TAG, downloadedApk.packageName + ':' + downloadedApk.versionCode + " is NOT pending install, probably just left over from a previous install.");
        return null;
    }
    try {
        PackageInfo info = getPackageManager().getPackageInfo(downloadedApk.packageName, 0);
        File pathToInstalled = InstalledAppProviderService.getPathToInstalledApk(info);
        if (pathToInstalled != null && pathToInstalled.canRead() && // Check size before hash for performance.
        pathToInstalled.length() == downloadedApk.size && TextUtils.equals(Utils.getBinaryHash(pathToInstalled, "sha256"), downloadedApk.hash)) {
            Log.i(TAG, downloadedApk.packageName + " is pending install, but we already have the correct version installed.");
            AppUpdateStatusManager.getInstance(this).markAsNoLongerPendingInstall(downloadedApk.getUrl());
            return null;
        }
    } catch (PackageManager.NameNotFoundException ignored) {
    }
    Utils.debugLog(TAG, downloadedApk.packageName + ':' + downloadedApk.versionCode + " is pending install, so we need to notify the user about installing it.");
    return downloadedApk;
}
Also used : PackageManager(android.content.pm.PackageManager) PackageInfo(android.content.pm.PackageInfo) Apk(org.fdroid.fdroid.data.Apk) File(java.io.File) Nullable(android.support.annotation.Nullable)

Example 27 with Apk

use of org.fdroid.fdroid.data.Apk in project fdroidclient by f-droid.

the class RepoXMLHandler method startElement.

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    super.startElement(uri, localName, qName, attributes);
    if ("repo".equals(localName)) {
        repoSigningCert = attributes.getValue("", "pubkey");
        repoMaxAge = Utils.parseInt(attributes.getValue("", "maxage"), -1);
        repoVersion = Utils.parseInt(attributes.getValue("", "version"), -1);
        repoName = cleanWhiteSpace(attributes.getValue("", "name"));
        repoDescription = cleanWhiteSpace(attributes.getValue("", "description"));
        repoTimestamp = parseLong(attributes.getValue("", "timestamp"), 0);
        repoIcon = attributes.getValue("", "icon");
    } else if (RepoPushRequest.INSTALL.equals(localName) || RepoPushRequest.UNINSTALL.equals(localName)) {
        if (repo.pushRequests == Repo.PUSH_REQUEST_ACCEPT_ALWAYS) {
            RepoPushRequest r = new RepoPushRequest(localName, attributes.getValue("packageName"), attributes.getValue("versionCode"));
            onRepoPushRequestParsed(r);
        }
    } else if ("application".equals(localName) && curapp == null) {
        curapp = new App();
        curapp.repoId = repo.getId();
        curapp.packageName = attributes.getValue("", "id");
        // To appease the NON NULL constraint in the DB. Usually there is a description, and it
        // is quite difficult to get an app to _not_ have a description when using fdroidserver.
        // However, it shouldn't crash the client when this happens.
        curapp.description = "";
    } else if ("package".equals(localName) && curapp != null && curapk == null) {
        curapk = new Apk();
        curapk.packageName = curapp.packageName;
        curapk.repoId = repo.getId();
        currentApkHashType = null;
    } else if ("hash".equals(localName) && curapk != null) {
        currentApkHashType = attributes.getValue("", "type");
    } else if ("uses-permission".equals(localName) && curapk != null) {
        String maxSdkVersion = attributes.getValue("maxSdkVersion");
        if (maxSdkVersion == null || Build.VERSION.SDK_INT <= Integer.valueOf(maxSdkVersion)) {
            addRequestedPermission(attributes.getValue("name"));
        } else {
            removeRequestedPermission(attributes.getValue("name"));
        }
    } else if ("uses-permission-sdk-23".equals(localName) && curapk != null) {
        String maxSdkVersion = attributes.getValue("maxSdkVersion");
        if (Build.VERSION.SDK_INT >= 23 && (maxSdkVersion == null || Build.VERSION.SDK_INT <= Integer.valueOf(maxSdkVersion))) {
            addRequestedPermission(attributes.getValue("name"));
        } else {
            removeRequestedPermission(attributes.getValue("name"));
        }
    }
    curchars.setLength(0);
}
Also used : App(org.fdroid.fdroid.data.App) RepoPushRequest(org.fdroid.fdroid.data.RepoPushRequest) Apk(org.fdroid.fdroid.data.Apk)

Example 28 with Apk

use of org.fdroid.fdroid.data.Apk in project fdroidclient by f-droid.

the class AppDetails2 method upgradeApk.

@Override
public void upgradeApk() {
    Apk apkToInstall = ApkProvider.Helper.findSuggestedApk(this, app);
    installApk(apkToInstall);
}
Also used : Apk(org.fdroid.fdroid.data.Apk)

Example 29 with Apk

use of org.fdroid.fdroid.data.Apk in project fdroidclient by f-droid.

the class AppDetails2 method uninstallApk.

@Override
public void uninstallApk() {
    Apk apk = app.installedApk;
    if (apk == null) {
        // TODO ideally, app would be refreshed immediately after install, then this
        // workaround would be unnecessary - unless it is a media file
        apk = app.getMediaApkifInstalled(getApplicationContext());
        if (apk == null) {
            // When the app isn't a media file - the above workaround refers to this.
            apk = app.getInstalledApk(this);
            if (apk == null) {
                throw new IllegalStateException("Couldn't find installed apk for " + app.packageName);
            }
        }
        app.installedApk = apk;
    }
    Installer installer = InstallerFactory.create(this, apk);
    Intent intent = installer.getUninstallScreen();
    if (intent != null) {
        // uninstall screen required
        Utils.debugLog(TAG, "screen screen required");
        startActivityForResult(intent, REQUEST_UNINSTALL_DIALOG);
        return;
    }
    startUninstall();
}
Also used : Installer(org.fdroid.fdroid.installer.Installer) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) Apk(org.fdroid.fdroid.data.Apk)

Example 30 with Apk

use of org.fdroid.fdroid.data.Apk in project fdroidclient by f-droid.

the class AppDetails2 method installApk.

@Override
public void installApk() {
    Apk apkToInstall = ApkProvider.Helper.findSuggestedApk(this, app);
    installApk(apkToInstall);
}
Also used : Apk(org.fdroid.fdroid.data.Apk)

Aggregations

Apk (org.fdroid.fdroid.data.Apk)63 Test (org.junit.Test)17 Uri (android.net.Uri)16 File (java.io.File)12 Intent (android.content.Intent)11 App (org.fdroid.fdroid.data.App)10 Repo (org.fdroid.fdroid.data.Repo)10 ArrayList (java.util.ArrayList)8 PendingIntent (android.app.PendingIntent)7 Context (android.content.Context)7 PackageInfo (android.content.pm.PackageInfo)7 FileCompatTest (org.fdroid.fdroid.compat.FileCompatTest)7 BroadcastReceiver (android.content.BroadcastReceiver)6 PackageManager (android.content.pm.PackageManager)5 IOException (java.io.IOException)4 HashSet (java.util.HashSet)4 FDroidProviderTest (org.fdroid.fdroid.data.FDroidProviderTest)4 LocalBroadcastManager (androidx.localbroadcastmanager.content.LocalBroadcastManager)3 RepoDetails (org.fdroid.fdroid.mock.RepoDetails)3 SuppressLint (android.annotation.SuppressLint)2