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

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

Merge "Implement cancelDownload and remove appName"

parents 874af710 9f116ef4
Loading
Loading
Loading
Loading
+70 −51
Original line number Diff line number Diff line
@@ -194,27 +194,23 @@ public class MbmsDownloadManager {

    private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null);
    private final IMbmsDownloadManagerCallback mCallback;
    private final String mDownloadAppName;

    private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback,
            String downloadAppName, int subId) {
    private MbmsDownloadManager(Context context, IMbmsDownloadManagerCallback callback, int subId) {
        mContext = context;
        mCallback = callback;
        mDownloadAppName = downloadAppName;
        mSubscriptionId = subId;
    }

    /**
     * Create a new MbmsDownloadManager using the system default data subscription ID.
     * See {@link #create(Context, IMbmsDownloadManagerCallback, String, int)}
     * See {@link #create(Context, IMbmsDownloadManagerCallback, int)}
     *
     * @hide
     */
    public static MbmsDownloadManager create(Context context,
            IMbmsDownloadManagerCallback listener, String downloadAppName)
            IMbmsDownloadManagerCallback listener)
            throws MbmsException {
        return create(context, listener, downloadAppName,
                SubscriptionManager.getDefaultSubscriptionId());
        return create(context, listener, SubscriptionManager.getDefaultSubscriptionId());
    }

    /**
@@ -229,15 +225,13 @@ public class MbmsDownloadManager {
     *
     * @param context The instance of {@link Context} to use
     * @param listener A callback to get asynchronous error messages and file service updates.
     * @param downloadAppName The app name, as negotiated with the eMBMS provider
     * @param subscriptionId The data subscription ID to use
     * @hide
     */
    public static MbmsDownloadManager create(Context context,
            IMbmsDownloadManagerCallback listener, String downloadAppName, int subscriptionId)
            IMbmsDownloadManagerCallback listener, int subscriptionId)
            throws MbmsException {
        MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName,
                subscriptionId);
        MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, subscriptionId);
        mdm.bindAndInitialize();
        return mdm;
    }
@@ -250,8 +244,7 @@ public class MbmsDownloadManager {
                        IMbmsDownloadService downloadService =
                                IMbmsDownloadService.Stub.asInterface(service);
                        try {
                            downloadService.initialize(
                                    mDownloadAppName, mSubscriptionId, mCallback);
                            downloadService.initialize(mSubscriptionId, mCallback);
                        } catch (RemoteException e) {
                            Log.e(LOG_TAG, "Service died before initialization");
                            return;
@@ -293,8 +286,7 @@ public class MbmsDownloadManager {
            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
        }
        try {
            int returnCode = downloadService.getFileServices(
                    mDownloadAppName, mSubscriptionId, classList);
            int returnCode = downloadService.getFileServices(mSubscriptionId, classList);
            if (returnCode != MbmsException.SUCCESS) {
                throw new MbmsException(returnCode);
            }
@@ -345,8 +337,7 @@ public class MbmsDownloadManager {
        }

        try {
            int result = downloadService.setTempFileRootDirectory(
                    mDownloadAppName, mSubscriptionId, filePath);
            int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath);
            if (result != MbmsException.SUCCESS) {
                throw new MbmsException(result);
            }
@@ -396,7 +387,6 @@ public class MbmsDownloadManager {
            tempRootDirectory.mkdirs();
            setTempFileRootDirectory(tempRootDirectory);
        }
        request.setAppName(mDownloadAppName);

        checkValidDownloadDestination(request);
        writeDownloadRequestToken(request);
@@ -404,6 +394,7 @@ public class MbmsDownloadManager {
            downloadService.download(request, callback);
        } catch (RemoteException e) {
            mService.set(null);
            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
        }
    }

@@ -422,18 +413,31 @@ public class MbmsDownloadManager {
    }

    /**
     * Attempts to cancel the specified DownloadRequest.
     * Attempts to cancel the specified {@link DownloadRequest}.
     *
     * May throw a RemoteException.
     * If the middleware is not aware of the specified download request, an MbmsException will be
     * thrown with error code {@link MbmsException#ERROR_UNKNOWN_DOWNLOAD_REQUEST}.
     *
     * Synchronous responses may include
     * <li>SUCCESS</li>
     * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
     * <li>ERROR_MSDC_UNKNOWN_REQUEST</li>
     * If this method returns without throwing an exception, you may assume that cancellation
     * was successful.
     * @param downloadRequest The download request that you wish to cancel.
     */
    public int cancelDownload(DownloadRequest downloadRequest) {
        // TODO: don't forget to delete the token
        return 0;
    public void cancelDownload(DownloadRequest downloadRequest) throws MbmsException {
        IMbmsDownloadService downloadService = mService.get();
        if (downloadService == null) {
            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
        }

        try {
            int result = downloadService.cancelDownload(downloadRequest);
            if (result != MbmsException.SUCCESS) {
                throw new MbmsException(result);
            }
        } catch (RemoteException e) {
            mService.set(null);
            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
        }
        deleteDownloadRequestToken(downloadRequest);
    }

    /**
@@ -472,6 +476,21 @@ public class MbmsDownloadManager {
        return 0;
    }

    public void dispose() {
        try {
            IMbmsDownloadService downloadService = mService.get();
            if (downloadService == null) {
                Log.i(LOG_TAG, "Service already dead");
                return;
            }
            downloadService.dispose(mSubscriptionId);
            mService.set(null);
        } catch (RemoteException e) {
            // Ignore
            Log.i(LOG_TAG, "Remote exception while disposing of service");
        }
    }

    /**
     * Retrieves the {@link ComponentName} for the {@link android.content.BroadcastReceiver} that
     * the various intents from the middleware should be targeted towards.
@@ -502,32 +521,13 @@ public class MbmsDownloadManager {
        return null;
    }

    public void dispose() {
        try {
            IMbmsDownloadService downloadService = mService.get();
            if (downloadService == null) {
                Log.i(LOG_TAG, "Service already dead");
                return;
            }
            downloadService.dispose(mDownloadAppName, mSubscriptionId);
            mService.set(null);
        } catch (RemoteException e) {
            // Ignore
            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();
        File token = getDownloadRequestTokenPath(request);
        if (!token.getParentFile().exists()) {
            token.getParentFile().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");
            Log.w(LOG_TAG, "Download token " + token.getName() + " already exists");
            return;
        }
        try {
@@ -541,6 +541,25 @@ public class MbmsDownloadManager {
        }
    }

    private void deleteDownloadRequestToken(DownloadRequest request) {
        File token = getDownloadRequestTokenPath(request);
        if (!token.isFile()) {
            Log.w(LOG_TAG, "Attempting to delete non-existent download token at " + token);
            return;
        }
        if (!token.delete()) {
            Log.w(LOG_TAG, "Couldn't delete download token at " + token);
        }
    }

    private File getDownloadRequestTokenPath(DownloadRequest request) {
        File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
                request.getFileServiceInfo());
        String downloadTokenFileName = request.getHash()
                + MbmsDownloadReceiver.DOWNLOAD_TOKEN_SUFFIX;
        return new File(tempFileLocation, downloadTokenFileName);
    }

    /**
     * Verifies the following:
     * If a request is multi-part,
+12 −19
Original line number Diff line number Diff line
@@ -43,16 +43,14 @@ public class MbmsStreamingManager {

    private AtomicReference<IMbmsStreamingService> mService = new AtomicReference<>(null);
    private MbmsStreamingManagerCallback mCallbackToApp;
    private final String mAppName;

    private final Context mContext;
    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;

    /** @hide */
    private MbmsStreamingManager(Context context, MbmsStreamingManagerCallback listener,
                    String streamingAppName, int subscriptionId) {
                    int subscriptionId) {
        mContext = context;
        mAppName = streamingAppName;
        mCallbackToApp = listener;
        mSubscriptionId = subscriptionId;
    }
@@ -67,27 +65,24 @@ public class MbmsStreamingManager {
     * @param context The {@link Context} to use.
     * @param listener A callback object on which you wish to receive results of asynchronous
     *                 operations.
     * @param streamingAppName The name of the streaming app, as specified by the carrier.
     * @param subscriptionId The subscription ID to use.
     */
    public static MbmsStreamingManager create(Context context,
            MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId)
            MbmsStreamingManagerCallback listener, int subscriptionId)
            throws MbmsException {
        MbmsStreamingManager manager = new MbmsStreamingManager(context, listener,
                streamingAppName, subscriptionId);
        MbmsStreamingManager manager = new MbmsStreamingManager(context, listener, subscriptionId);
        manager.bindAndInitialize();
        return manager;
    }

    /**
     * Create a new MbmsStreamingManager using the system default data subscription ID.
     * See {@link #create(Context, MbmsStreamingManagerCallback, String, int)}.
     * See {@link #create(Context, MbmsStreamingManagerCallback, int)}.
     */
    public static MbmsStreamingManager create(Context context,
            MbmsStreamingManagerCallback listener, String streamingAppName)
            MbmsStreamingManagerCallback listener)
            throws MbmsException {
        return create(context, listener, streamingAppName,
                SubscriptionManager.getDefaultSubscriptionId());
        return create(context, listener, SubscriptionManager.getDefaultSubscriptionId());
    }

    /**
@@ -101,7 +96,7 @@ public class MbmsStreamingManager {
            return;
        }
        try {
            streamingService.dispose(mAppName, mSubscriptionId);
            streamingService.dispose(mSubscriptionId);
        } catch (RemoteException e) {
            // Ignore for now
        }
@@ -132,8 +127,7 @@ public class MbmsStreamingManager {
            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
        }
        try {
            int returnCode = streamingService.getStreamingServices(
                    mAppName, mSubscriptionId, classList);
            int returnCode = streamingService.getStreamingServices(mSubscriptionId, classList);
            if (returnCode != MbmsException.SUCCESS) {
                throw new MbmsException(returnCode);
            }
@@ -168,7 +162,7 @@ public class MbmsStreamingManager {

        try {
            int returnCode = streamingService.startStreaming(
                    mAppName, mSubscriptionId, serviceInfo.getServiceId(), listener);
                    mSubscriptionId, serviceInfo.getServiceId(), listener);
            if (returnCode != MbmsException.SUCCESS) {
                throw new MbmsException(returnCode);
            }
@@ -178,8 +172,7 @@ public class MbmsStreamingManager {
            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
        }

        return new StreamingService(
                mAppName, mSubscriptionId, streamingService, serviceInfo, listener);
        return new StreamingService(mSubscriptionId, streamingService, serviceInfo, listener);
    }

    private void bindAndInitialize() throws MbmsException {
@@ -190,12 +183,12 @@ public class MbmsStreamingManager {
                        IMbmsStreamingService streamingService =
                                IMbmsStreamingService.Stub.asInterface(service);
                        try {
                            streamingService.initialize(mCallbackToApp, mAppName, mSubscriptionId);
                            streamingService.initialize(mCallbackToApp, mSubscriptionId);
                        } catch (RemoteException e) {
                            Log.e(LOG_TAG, "Service died before initialization");
                            return;
                        }
                        mService.set(null);
                        mService.set(streamingService);
                    }

                    @Override
+28 −20
Original line number Diff line number Diff line
@@ -22,11 +22,11 @@ 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;
import java.util.Objects;

/**
 * A Parcelable class describing a pending Cell-Broadcast download request
@@ -83,7 +83,7 @@ public class DownloadRequest implements Parcelable {

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

@@ -94,18 +94,16 @@ public class DownloadRequest implements Parcelable {
    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 version) {
            int sub, String appIntent, int version) {
        downloadId = id;
        fileServiceInfo = serviceInfo;
        sourceUri = source;
        destinationUri = dest;
        subscriptionId = sub;
        serializedResultIntentForApp = appIntent;
        appName = name;
        this.version = version;
    }

@@ -120,7 +118,6 @@ public class DownloadRequest implements Parcelable {
        destinationUri = dr.destinationUri;
        subscriptionId = dr.subscriptionId;
        serializedResultIntentForApp = dr.serializedResultIntentForApp;
        appName = dr.appName;
        version = dr.version;
    }

@@ -131,7 +128,6 @@ public class DownloadRequest implements Parcelable {
        destinationUri = in.readParcelable(getClass().getClassLoader());
        subscriptionId = in.readInt();
        serializedResultIntentForApp = in.readString();
        appName = in.readString();
        version = in.readInt();
    }

@@ -146,7 +142,6 @@ public class DownloadRequest implements Parcelable {
        out.writeParcelable(destinationUri, flags);
        out.writeInt(subscriptionId);
        out.writeString(serializedResultIntentForApp);
        out.writeString(appName);
        out.writeInt(version);
    }

@@ -178,18 +173,6 @@ public class DownloadRequest implements Parcelable {
        }
    }

    /** @hide */
    public synchronized void setAppName(String newAppName) {
        if (appName != null) {
            throw new IllegalStateException("Attempting to reset appName");
        }
        appName = newAppName;
    }

    public String getAppName() {
        return appName;
    }

    public int getVersion() {
        return version;
    }
@@ -234,4 +217,29 @@ public class DownloadRequest implements Parcelable {
        // Add updates for future versions here
        return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) {
            return false;
        }
        if (!(o instanceof DownloadRequest)) {
            return false;
        }
        DownloadRequest request = (DownloadRequest) o;
        return downloadId == request.downloadId &&
                subscriptionId == request.subscriptionId &&
                version == request.version &&
                Objects.equals(fileServiceInfo, request.fileServiceInfo) &&
                Objects.equals(sourceUri, request.sourceUri) &&
                Objects.equals(destinationUri, request.destinationUri) &&
                Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp);
    }

    @Override
    public int hashCode() {
        return Objects.hash(downloadId, fileServiceInfo, sourceUri, destinationUri,
                subscriptionId, serializedResultIntentForApp, version);
    }
}
+42 −7
Original line number Diff line number Diff line
@@ -29,16 +29,16 @@ import android.util.Log;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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
@@ -431,17 +431,16 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        }
        toFile.getParentFile().mkdirs();

        // TODO: This will not work if the two files are on different filesystems. Add manual
        // copy later.
        if (fromFile.renameTo(toFile)) {
            return Uri.fromFile(toFile);
        } else if (manualMove(fromFile, toFile)) {
            return Uri.fromFile(toFile);
        }
        return null;
    }

    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())) {
            Log.w(LOG_TAG, "Uri " + filePath + " does not have a file scheme");
            return false;
@@ -493,4 +492,40 @@ public class MbmsDownloadReceiver extends BroadcastReceiver {
        }
        return mMiddlewarePackageNameCache;
    }

    private static boolean manualMove(File src, File dst) {
        InputStream in = null;
        OutputStream out = null;
        try {
            if (!dst.exists()) {
                dst.createNewFile();
            }
            in = new FileInputStream(src);
            out = new FileOutputStream(dst);
            byte[] buffer = new byte[2048];
            int len;
            do {
                len = in.read(buffer);
                out.write(buffer, 0, len);
            } while (len > 0);
        } catch (IOException e) {
            Log.w(LOG_TAG, "Manual file move failed due to exception "  + e);
            if (dst.exists()) {
                dst.delete();
            }
            return false;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                Log.w(LOG_TAG, "Error closing streams: " + e);
            }
        }
        return true;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ public class MbmsException extends Exception {
    public static final int ERROR_UNABLE_TO_READ_SIM = 16;
    public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 17;
    public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 18;
    public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 19;
    public static final int ERROR_UNABLE_TO_INITIALIZE = 20;

    private final int mErrorCode;

Loading