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

Commit 4c751c86 authored by Hall Liu's avatar Hall Liu Committed by android-build-merger
Browse files

Merge "Implement cancelDownload and remove appName" am: 9b43ffcf

am: 4b1acf44

Change-Id: Ic6d19500c335bc40e6d14d009d4d459bf02b06e1
parents a1157b3a 4b1acf44
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