Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b671aa06 authored by Sumedh Sen's avatar Sumedh Sen
Browse files

Install from download manager overrides originating pkgName

If user initiates an installation from the Downloads Manager, use the
app label of the downloads provider directly instead of relying on
originating uid to fetch an app label

Bug: 280886418
Test: Install an app from Files > Downloads. Follow repro steps in the
bug

Change-Id: Ic4e407fe141a2a7e9e0fd4054a28d48dd449395c
parent af0f3422
Loading
Loading
Loading
Loading
+4 −15
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ import java.util.Arrays;
public class InstallStart extends Activity {
    private static final String TAG = InstallStart.class.getSimpleName();

    private static final String DOWNLOADS_AUTHORITY = "downloads";

    private static final int DLG_INSTALL_APPS_RESTRICTED_FOR_USER = 1;
    private static final int DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER = 2;
@@ -103,6 +102,8 @@ public class InstallStart extends Activity {

        boolean isDocumentsManager = checkPermission(Manifest.permission.MANAGE_DOCUMENTS,
                -1, callingUid) == PackageManager.PERMISSION_GRANTED;
        boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo(
                                                mPackageManager, callingUid) != null;
        boolean isTrustedSource = false;
        if (sourceInfo != null && sourceInfo.isPrivilegedApp()) {
            isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false) || (
@@ -111,7 +112,7 @@ public class InstallStart extends Activity {
                            == PackageManager.PERMISSION_GRANTED);
        }

        if (!isTrustedSource && !isSystemDownloadsProvider(callingUid) && !isDocumentsManager
        if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager
                && originatingUid != Process.INVALID_UID) {
            final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid);
            if (targetSdkVersion < 0) {
@@ -241,17 +242,6 @@ public class InstallStart extends Activity {
        return null;
    }

    private boolean isSystemDownloadsProvider(int uid) {
        final ProviderInfo downloadProviderPackage = getPackageManager().resolveContentProvider(
                DOWNLOADS_AUTHORITY, 0);
        if (downloadProviderPackage == null) {
            // There seems to be no currently enabled downloads provider on the system.
            return false;
        }
        final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
        return ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                && uid == appInfo.uid);
    }

    @NonNull
    private boolean canPackageQuery(int callingUid, Uri packageUri) {
@@ -346,7 +336,6 @@ public class InstallStart extends Activity {
     * Create a new dialog.
     *
     * @param id The id of the dialog (determines dialog type)
     *
     * @return The dialog
     */
    private DialogFragment createDialog(int id) {
+9 −0
Original line number Diff line number Diff line
@@ -265,6 +265,15 @@ public class PackageInstallerActivity extends AlertActivity {
    }

    private String getPackageNameForUid(int sourceUid) {
        // If the sourceUid belongs to the system downloads provider, we explicitly return the
        // name of the Download Manager package. This is because its UID is shared with multiple
        // packages, resulting in uncertainty about which package will end up first in the list
        // of packages associated with this UID
        ApplicationInfo systemDownloadProviderInfo = PackageUtil.getSystemDownloadsProviderInfo(
                                                        mPm, sourceUid);
        if (systemDownloadProviderInfo != null) {
            return systemDownloadProviderInfo.packageName;
        }
        String[] packagesForUid = mPm.getPackagesForUid(sourceUid);
        if (packagesForUid == null) {
            return null;
+25 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -48,7 +49,7 @@ import java.io.IOException;
 * used in the package installer application.
 */
public class PackageUtil {
    private static final String LOG_TAG = PackageUtil.class.getSimpleName();
    private static final String LOG_TAG = "PackageInstaller";

    public static final String PREFIX="com.android.packageinstaller.";
    public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
@@ -56,6 +57,7 @@ public class PackageUtil {
    public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
    //intent attribute strings related to uninstall
    public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
    private static final String DOWNLOADS_AUTHORITY = "downloads";

    /**
     * Utility method to get package information for a given {@link File}
@@ -245,4 +247,26 @@ public class PackageUtil {
            getActivity().finish();
        }
    }

    /**
     * Determines if the UID belongs to the system downloads provider and returns the
     * {@link ApplicationInfo} of the provider
     *
     * @param uid UID of the caller
     * @return {@link ApplicationInfo} of the provider if a downloads provider exists,
     *          it is a system app, and its UID matches with the passed UID, null otherwise.
     */
    public static ApplicationInfo getSystemDownloadsProviderInfo(PackageManager pm, int uid) {
        final ProviderInfo providerInfo = pm.resolveContentProvider(
                DOWNLOADS_AUTHORITY, 0);
        if (providerInfo == null) {
            // There seems to be no currently enabled downloads provider on the system.
            return null;
        }
        ApplicationInfo appInfo = providerInfo.applicationInfo;
        if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 && uid == appInfo.uid) {
            return appInfo;
        }
        return null;
    }
}