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

Commit c2f33f18 authored by Hall Liu's avatar Hall Liu Committed by Gerrit Code Review
Browse files

Merge changes from topics 'embms-cleanup-action', 'embms-download-token'

* changes:
  Implement the cleanup action in MbmsDownloadReceiver
  Add download request tokens and enforce destination clear
parents 4e77ae6d 990a573d
Loading
Loading
Loading
Loading
+62 −14
Original line number Diff line number Diff line
@@ -166,6 +166,14 @@ public class MbmsDownloadManager {
    public static final String EXTRA_TEMP_FILES_IN_USE =
            "android.telephony.mbms.extra.TEMP_FILES_IN_USE";

    /**
     * Extra containing an instance of {@link android.telephony.mbms.ServiceInfo}, used by
     * file-descriptor requests and cleanup requests to specify which service they want to
     * request temp files or clean up temp files for, respectively.
     */
    public static final String EXTRA_SERVICE_INFO =
            "android.telephony.mbms.extra.SERVICE_INFO";

    /**
     * Extra containing a single {@link Uri} indicating the location of the successfully
     * downloaded file. Set on the intent provided via
@@ -388,21 +396,10 @@ public class MbmsDownloadManager {
            tempRootDirectory.mkdirs();
            setTempFileRootDirectory(tempRootDirectory);
        }

        request.setAppName(mDownloadAppName);
        // Check if the request is a multipart download. If so, validate that the destination is
        // a directory that exists.
        // TODO: figure out what qualifies a request as a multipart download request.
        if (request.getSourceUri().getLastPathSegment() != null &&
                request.getSourceUri().getLastPathSegment().contains("*")) {
            File toFile = new File(request.getDestinationUri().getSchemeSpecificPart());
            if (!toFile.isDirectory()) {
                throw new IllegalArgumentException("Multipart download must specify valid " +
                        "destination directory.");
            }
        }
        // TODO: check to make sure destination is clear
        // TODO: write download request token

        checkValidDownloadDestination(request);
        writeDownloadRequestToken(request);
        try {
            downloadService.download(request, callback);
        } catch (RemoteException e) {
@@ -435,6 +432,7 @@ public class MbmsDownloadManager {
     * <li>ERROR_MSDC_UNKNOWN_REQUEST</li>
     */
    public int cancelDownload(DownloadRequest downloadRequest) {
        // TODO: don't forget to delete the token
        return 0;
    }

@@ -518,4 +516,54 @@ public class MbmsDownloadManager {
            Log.i(LOG_TAG, "Remote exception while disposing of service");
        }
    }

    private void writeDownloadRequestToken(DownloadRequest request) {
        File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
                request.getFileServiceInfo());
        if (!tempFileLocation.exists()) {
            tempFileLocation.mkdirs();
        }
        String downloadTokenFileName = request.getHash()
                + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX;
        File token = new File(tempFileLocation, downloadTokenFileName);
        if (token.exists()) {
            Log.w(LOG_TAG, "Download token " + downloadTokenFileName + " already exists");
            return;
        }
        try {
            if (!token.createNewFile()) {
                throw new RuntimeException("Failed to create download token for request "
                        + request);
            }
        } catch (IOException e) {
            throw new RuntimeException("Failed to create download token for request " + request
                    + " due to IOException " + e);
        }
    }

    /**
     * Verifies the following:
     * If a request is multi-part,
     *     1. Destination Uri must exist and be a directory
     *     2. Directory specified must contain no files.
     * Otherwise
     *     1. The file specified by the destination Uri must not exist.
     */
    private void checkValidDownloadDestination(DownloadRequest request) {
        File toFile = new File(request.getDestinationUri().getSchemeSpecificPart());
        if (request.isMultipartDownload()) {
            if (!toFile.isDirectory()) {
                throw new IllegalArgumentException("Multipart download must specify valid " +
                        "destination directory.");
            }
            if (toFile.listFiles().length > 0) {
                throw new IllegalArgumentException("Destination directory must be clear of all " +
                        "files.");
            }
        } else {
            if (toFile.exists()) {
                throw new IllegalArgumentException("Destination file must not exist.");
            }
        }
    }
}
+55 −2
Original line number Diff line number Diff line
@@ -20,15 +20,22 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;

import java.lang.IllegalStateException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * A Parcelable class describing a pending Cell-Broadcast download request
 * @hide
 */
public class DownloadRequest implements Parcelable {
    // Version code used to keep token calculation consistent.
    private static final int CURRENT_VERSION = 1;

    /** @hide */
    public static class Builder {
        private int id;
@@ -37,6 +44,7 @@ public class DownloadRequest implements Parcelable {
        private Uri dest;
        private int subscriptionId;
        private String appIntent;
        private int version = CURRENT_VERSION;

        public Builder setId(int id) {
            this.id = id;
@@ -68,9 +76,14 @@ public class DownloadRequest implements Parcelable {
            return this;
        }

        public Builder setVersion(int version) {
            this.version = version;
            return this;
        }

        public DownloadRequest build() {
            return new DownloadRequest(id, serviceInfo, source, dest,
                    subscriptionId, appIntent, null);
                    subscriptionId, appIntent, null, version);
        }
    }

@@ -80,11 +93,12 @@ public class DownloadRequest implements Parcelable {
    private final Uri destinationUri;
    private final int subscriptionId;
    private final String serializedResultIntentForApp;
    private final int version;
    private String appName; // not the Android app Name, the embms app name

    private DownloadRequest(int id, FileServiceInfo serviceInfo,
            Uri source, Uri dest,
            int sub, String appIntent, String name) {
            int sub, String appIntent, String name, int version) {
        downloadId = id;
        fileServiceInfo = serviceInfo;
        sourceUri = source;
@@ -92,6 +106,7 @@ public class DownloadRequest implements Parcelable {
        subscriptionId = sub;
        serializedResultIntentForApp = appIntent;
        appName = name;
        this.version = version;
    }

    public static DownloadRequest copy(DownloadRequest other) {
@@ -106,6 +121,7 @@ public class DownloadRequest implements Parcelable {
        subscriptionId = dr.subscriptionId;
        serializedResultIntentForApp = dr.serializedResultIntentForApp;
        appName = dr.appName;
        version = dr.version;
    }

    private DownloadRequest(Parcel in) {
@@ -116,6 +132,7 @@ public class DownloadRequest implements Parcelable {
        subscriptionId = in.readInt();
        serializedResultIntentForApp = in.readString();
        appName = in.readString();
        version = in.readInt();
    }

    public int describeContents() {
@@ -130,6 +147,7 @@ public class DownloadRequest implements Parcelable {
        out.writeInt(subscriptionId);
        out.writeString(serializedResultIntentForApp);
        out.writeString(appName);
        out.writeInt(version);
    }

    public int getDownloadId() {
@@ -172,6 +190,10 @@ public class DownloadRequest implements Parcelable {
        return appName;
    }

    public int getVersion() {
        return version;
    }

    public static final Parcelable.Creator<DownloadRequest> CREATOR =
            new Parcelable.Creator<DownloadRequest>() {
        public DownloadRequest createFromParcel(Parcel in) {
@@ -181,4 +203,35 @@ public class DownloadRequest implements Parcelable {
            return new DownloadRequest[size];
        }
    };

    /**
     * @hide
     */
    public boolean isMultipartDownload() {
        // TODO: figure out what qualifies a request as a multipart download request.
        return getSourceUri().getLastPathSegment() != null &&
                getSourceUri().getLastPathSegment().contains("*");
    }

    /**
     * Retrieves the hash string that should be used as the filename when storing a token for
     * this DownloadRequest.
     * @hide
     */
    public String getHash() {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Could not get sha256 hash object");
        }
        if (version >= 1) {
            // Hash the source URI, destination URI, and the app intent
            digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8));
            digest.update(destinationUri.toString().getBytes(StandardCharsets.UTF_8));
            digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
        }
        // Add updates for future versions here
        return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP);
    }
}
+148 −49
Original line number Diff line number Diff line
@@ -28,35 +28,85 @@ import android.telephony.MbmsDownloadManager;
import android.util.Log;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;

/**
 * @hide
 */
public class MbmsDownloadReceiver extends BroadcastReceiver {
    public static final String DOWNLOAD_TOKEN_SUFFIX = ".download_token";
    public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority";

    /**
     * TODO: @SystemApi all these result codes
     * Indicates that the requested operation completed without error.
     */
    public static final int RESULT_OK = 0;

    /**
     * Indicates that the intent sent had an invalid action. This will be the result if
     * {@link Intent#getAction()} returns anything other than
     * {@link MbmsDownloadManager#ACTION_DOWNLOAD_RESULT_INTERNAL},
     * {@link MbmsDownloadManager#ACTION_FILE_DESCRIPTOR_REQUEST}, or
     * {@link MbmsDownloadManager#ACTION_CLEANUP}.
     * This is a fatal result code and no result extras should be expected.
     */
    public static final int RESULT_INVALID_ACTION = 1;

    /**
     * Indicates that the intent was missing some required extras.
     * This is a fatal result code and no result extras should be expected.
     */
    public static final int RESULT_MALFORMED_INTENT = 2;

    /**
     * Indicates that the supplied value for {@link MbmsDownloadManager#EXTRA_TEMP_FILE_ROOT}
     * does not match what the app has stored.
     * This is a fatal result code and no result extras should be expected.
     */
    public static final int RESULT_BAD_TEMP_FILE_ROOT = 3;

    /**
     * Indicates that the manager was unable to move the completed download to its final location.
     * This is a fatal result code and no result extras should be expected.
     */
    public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4;

    /**
     * Indicates that the manager weas unable to generate one or more of the requested file
     * descriptors.
     * This is a non-fatal result code -- some file descriptors may still be generated, but there
     * is no guarantee that they will be the same number as requested.
     */
    public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5;

    private static final String LOG_TAG = "MbmsDownloadReceiver";
    private static final String TEMP_FILE_SUFFIX = ".embms.temp";
    private static final int MAX_TEMP_FILE_RETRIES = 5;

    public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority";

    private String mFileProviderAuthorityCache = null;
    private String mMiddlewarePackageNameCache = null;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (!verifyIntentContents(intent)) {
            setResultCode(1 /* TODO: define error constants */);
        if (!verifyIntentContents(context, intent)) {
            setResultCode(RESULT_MALFORMED_INTENT);
            return;
        }
        if (!Objects.equals(intent.getStringExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT),
                MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath())) {
            setResultCode(1 /* TODO: define error constants */);
            setResultCode(RESULT_BAD_TEMP_FILE_ROOT);
            return;
        }

@@ -65,11 +115,14 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
            cleanupPostMove(context, intent);
        } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
            generateTempFiles(context, intent);
        } else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) {
            cleanupTempFiles(context, intent);
        } else {
            setResultCode(RESULT_INVALID_ACTION);
        }
        // TODO: Add handling for ACTION_CLEANUP
    }

    private boolean verifyIntentContents(Intent intent) {
    private boolean verifyIntentContents(Context context, Intent intent) {
        if (MbmsDownloadManager.ACTION_DOWNLOAD_RESULT_INTERNAL.equals(intent.getAction())) {
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_RESULT)) {
                Log.w(LOG_TAG, "Download result did not include a result code. Ignoring.");
@@ -93,26 +146,47 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
                        "temp file. Ignoring.");
                return false;
            }
            return true;
            DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST);
            String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
            File expectedTokenFile = new File(
                    MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceInfo()),
                    expectedTokenFileName);
            if (!expectedTokenFile.exists()) {
                Log.w(LOG_TAG, "Supplied download request does not match a token that we have. " +
                        "Expected " + expectedTokenFile);
                return false;
            }
        } else if (MbmsDownloadManager.ACTION_FILE_DESCRIPTOR_REQUEST.equals(intent.getAction())) {
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_REQUEST)) {
                Log.w(LOG_TAG, "Temp file request not include the associated request. Ignoring.");
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) {
                Log.w(LOG_TAG, "Temp file request did not include the associated service info." +
                        " Ignoring.");
                return false;
            }
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT)) {
                Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
                return false;
            }
            return true;
        } else if (MbmsDownloadManager.ACTION_CLEANUP.equals(intent.getAction())) {
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO)) {
                Log.w(LOG_TAG, "Cleanup request did not include the associated service info." +
                        " Ignoring.");
                return false;
            }

        Log.w(LOG_TAG, "Received intent with unknown action: " + intent.getAction());
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILE_ROOT)) {
                Log.w(LOG_TAG, "Cleanup request did not include the temp file root. Ignoring.");
                return false;
            }
            if (!intent.hasExtra(MbmsDownloadManager.EXTRA_TEMP_FILES_IN_USE)) {
                Log.w(LOG_TAG, "Cleanup request did not include the list of temp files in use. " +
                        "Ignoring.");
                return false;
            }
        }
        return true;
    }

    private void moveDownloadedFile(Context context, Intent intent) {
        DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST);
        // TODO: check request against token
        Intent intentForApp = request.getIntentForApp();

        int result = intent.getIntExtra(MbmsDownloadManager.EXTRA_RESULT,
@@ -127,9 +201,9 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {

        Uri destinationUri = request.getDestinationUri();
        Uri finalTempFile = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_FINAL_URI);
        if (!verifyTempFilePath(context, request, finalTempFile)) {
        if (!verifyTempFilePath(context, request.getFileServiceInfo(), finalTempFile)) {
            Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
            setResultCode(1);
            setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
            return;
        }

@@ -140,16 +214,15 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        if (finalFileLocation == null) {
            Log.w(LOG_TAG, "Failed to move temp file to final destination");
            // TODO: how do we notify the app of this?
            setResultCode(1);
            setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
        }
        intentForApp.putExtra(MbmsDownloadManager.EXTRA_COMPLETED_FILE_URI, finalFileLocation);

        context.sendBroadcast(intentForApp);
        setResultCode(0);
        setResultCode(RESULT_OK);
    }

    private void cleanupPostMove(Context context, Intent intent) {
        // TODO: account for in-use temp files
        DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST);
        if (request == null) {
            Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
@@ -162,7 +235,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        }

        for (Uri tempFileUri : tempFiles) {
            if (verifyTempFilePath(context, request, tempFileUri)) {
            if (verifyTempFilePath(context, request.getFileServiceInfo(), tempFileUri)) {
                File tempFile = new File(tempFileUri.getSchemeSpecificPart());
                tempFile.delete();
            }
@@ -170,11 +243,12 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
    }

    private void generateTempFiles(Context context, Intent intent) {
        // TODO: update pursuant to final decision on temp file locations
        DownloadRequest request = intent.getParcelableExtra(MbmsDownloadManager.EXTRA_REQUEST);
        if (request == null) {
            Log.w(LOG_TAG, "Temp file request did not include the associated request. Ignoring.");
            setResultCode(1 /* TODO: define error constants */);
        FileServiceInfo serviceInfo =
                intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO);
        if (serviceInfo == null) {
            Log.w(LOG_TAG, "Temp file request did not include the associated service info. " +
                    "Ignoring.");
            setResultCode(RESULT_MALFORMED_INTENT);
            return;
        }
        int fdCount = intent.getIntExtra(MbmsDownloadManager.EXTRA_FD_COUNT, 0);
@@ -182,24 +256,27 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {

        if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
            Log.i(LOG_TAG, "No temp files actually requested. Ending.");
            setResultCode(0);
            setResultCode(RESULT_OK);
            setResultExtras(Bundle.EMPTY);
            return;
        }

        ArrayList<UriPathPair> freshTempFiles = generateFreshTempFiles(context, request, fdCount);
        ArrayList<UriPathPair> freshTempFiles =
                generateFreshTempFiles(context, serviceInfo, fdCount);
        ArrayList<UriPathPair> pausedFiles =
                generateUrisForPausedFiles(context, request, pausedList);
                generateUrisForPausedFiles(context, serviceInfo, pausedList);

        Bundle result = new Bundle();
        result.putParcelableArrayList(MbmsDownloadManager.EXTRA_FREE_URI_LIST, freshTempFiles);
        result.putParcelableArrayList(MbmsDownloadManager.EXTRA_PAUSED_URI_LIST, pausedFiles);
        setResultCode(RESULT_OK);
        setResultExtras(result);
    }

    private ArrayList<UriPathPair> generateFreshTempFiles(Context context, DownloadRequest request,
    private ArrayList<UriPathPair> generateFreshTempFiles(Context context,
            FileServiceInfo serviceInfo,
            int freshFdCount) {
        File tempFileDir = getEmbmsTempFileDirForRequest(context, request);
        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo);
        if (!tempFileDir.exists()) {
            tempFileDir.mkdirs();
        }
@@ -210,11 +287,11 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        for (int i = 0; i < freshFdCount; i++) {
            File tempFile = generateSingleTempFile(tempFileDir);
            if (tempFile == null) {
                setResultCode(2 /* TODO: define error constants */);
                setResultCode(RESULT_TEMP_FILE_GENERATION_ERROR);
                Log.w(LOG_TAG, "Failed to generate a temp file. Moving on.");
                continue;
            }
            Uri fileUri = Uri.fromParts(ContentResolver.SCHEME_FILE, tempFile.getPath(), null);
            Uri fileUri = Uri.fromFile(tempFile);
            Uri contentUri = MbmsTempFileProvider.getUriForFile(
                    context, getFileProviderAuthorityCached(context), tempFile);
            context.grantUriPermission(getMiddlewarePackageCached(context), contentUri,
@@ -243,22 +320,22 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
    }

    private ArrayList<UriPathPair> generateUrisForPausedFiles(Context context,
            DownloadRequest request, List<Uri> pausedFiles) {
            FileServiceInfo serviceInfo, List<Uri> pausedFiles) {
        if (pausedFiles == null) {
            return new ArrayList<>(0);
        }
        ArrayList<UriPathPair> result = new ArrayList<>(pausedFiles.size());

        for (Uri fileUri : pausedFiles) {
            if (!verifyTempFilePath(context, request, fileUri)) {
            if (!verifyTempFilePath(context, serviceInfo, fileUri)) {
                Log.w(LOG_TAG, "Supplied file " + fileUri + " is not a valid temp file to resume");
                setResultCode(2 /* TODO: define error codes */);
                setResultCode(RESULT_TEMP_FILE_GENERATION_ERROR);
                continue;
            }
            File tempFile = new File(fileUri.getSchemeSpecificPart());
            if (!tempFile.exists()) {
                Log.w(LOG_TAG, "Supplied file " + fileUri + " does not exist.");
                setResultCode(2 /* TODO: define error codes */);
                setResultCode(RESULT_TEMP_FILE_GENERATION_ERROR);
                continue;
            }
            Uri contentUri = MbmsTempFileProvider.getUriForFile(
@@ -271,6 +348,38 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        return result;
    }

    private void cleanupTempFiles(Context context, Intent intent) {
        FileServiceInfo serviceInfo =
                intent.getParcelableExtra(MbmsDownloadManager.EXTRA_SERVICE_INFO);
        File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo);
        List<Uri> filesInUse =
                intent.getParcelableArrayListExtra(MbmsDownloadManager.EXTRA_TEMP_FILES_IN_USE);
        File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                File canonicalFile;
                try {
                    canonicalFile = file.getCanonicalFile();
                } catch (IOException e) {
                    Log.w(LOG_TAG, "Got IOException canonicalizing " + file + ", not deleting.");
                    return false;
                }
                // Reject all files that don't match what we think a temp file should look like
                // e.g. download tokens
                if (!canonicalFile.getName().endsWith(TEMP_FILE_SUFFIX)) {
                    return false;
                }
                // If any of the files in use match the uri, return false to reject it from the
                // list to delete.
                Uri fileInUseUri = Uri.fromFile(canonicalFile);
                return !filesInUse.contains(fileInUseUri);
            }
        });
        for (File fileToDelete : filesToDelete) {
            fileToDelete.delete();
        }
    }

    private static String calculateDestinationFileRelativePath(DownloadRequest request,
            FileInfo info) {
        List<String> filePathComponents = info.getUri().getPathSegments();
@@ -330,7 +439,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        return null;
    }

    private static boolean verifyTempFilePath(Context context, DownloadRequest request,
    private static boolean verifyTempFilePath(Context context, FileServiceInfo serviceInfo,
            Uri filePath) {
        // TODO: modify pursuant to final decision on temp file path scheme
        if (!ContentResolver.SCHEME_FILE.equals(filePath.getScheme())) {
@@ -345,24 +454,14 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
            return false;
        }

        if (!MbmsUtils.isContainedIn(getEmbmsTempFileDirForRequest(context, request), tempFile)) {
        if (!MbmsUtils.isContainedIn(
                MbmsUtils.getEmbmsTempFileDirForService(context, serviceInfo), tempFile)) {
            return false;
        }

        return true;
    }

    /**
     * Returns a File linked to the directory used to store temp files for this request
     */
    private static File getEmbmsTempFileDirForRequest(Context context, DownloadRequest request) {
        File embmsTempFileDir = MbmsTempFileProvider.getEmbmsTempFileDir(context);

        // TODO: better naming scheme for temp file dirs
        String tempFileDirName = String.valueOf(request.getFileServiceInfo().getServiceId());
        return new File(embmsTempFileDir, tempFileDirName);
    }

    private String getFileProviderAuthorityCached(Context context) {
        if (mFileProviderAuthorityCache != null) {
            return mFileProviderAuthorityCache;
+10 −0

File changed.

Preview size limit exceeded, changes collapsed.