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

Commit 2a08ccdd authored by Hall Liu's avatar Hall Liu Committed by android-build-merger
Browse files

Merge "EMBMS API tweaks" am: 47e1d11b

am: 3b40c709

Change-Id: I8b281f717d3862a9f7a5de3d834dcded4ac436dc
parents 9b31dd86 3b40c709
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -40415,12 +40415,12 @@ package android.telephony {
  public class MbmsDownloadSession implements java.lang.AutoCloseable {
    method public int cancelDownload(android.telephony.mbms.DownloadRequest);
    method public void close();
    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
    method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsDownloadSessionCallback);
    method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsDownloadSessionCallback);
    method public int download(android.telephony.mbms.DownloadRequest);
    method public java.io.File getTempFileRootDirectory();
    method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadStateCallback);
    method public void requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
    method public void requestUpdateFileServices(java.util.List<java.lang.String>);
    method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
@@ -40448,10 +40448,10 @@ package android.telephony {
  public class MbmsStreamingSession implements java.lang.AutoCloseable {
    method public void close();
    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, int, android.os.Handler);
    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, android.os.Handler);
    method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback);
    method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsStreamingSessionCallback);
    method public void requestUpdateStreamingServices(java.util.List<java.lang.String>);
    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler);
    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, java.util.concurrent.Executor, android.telephony.mbms.StreamingServiceCallback);
  }
  public class NeighboringCellInfo implements android.os.Parcelable {
@@ -41279,20 +41279,23 @@ package android.telephony.gsm {
package android.telephony.mbms {
  public final class DownloadRequest implements android.os.Parcelable {
    method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
    method public int describeContents();
    method public android.net.Uri getDestinationUri();
    method public java.lang.String getFileServiceId();
    method public static int getMaxAppIntentSize();
    method public static int getMaxDestinationUriSize();
    method public android.net.Uri getSourceUri();
    method public int getSubscriptionId();
    method public byte[] toByteArray();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.telephony.mbms.DownloadRequest> CREATOR;
  }
  public static class DownloadRequest.Builder {
    ctor public DownloadRequest.Builder(android.net.Uri);
    ctor public DownloadRequest.Builder(android.net.Uri, android.net.Uri);
    method public android.telephony.mbms.DownloadRequest build();
    method public static android.telephony.mbms.DownloadRequest.Builder fromDownloadRequest(android.telephony.mbms.DownloadRequest);
    method public static android.telephony.mbms.DownloadRequest.Builder fromSerializedRequest(byte[]);
    method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
    method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
    method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
@@ -41388,10 +41391,10 @@ package android.telephony.mbms {
    method public java.util.Date getSessionStartTime();
  }
  public class StreamingService {
  public class StreamingService implements java.lang.AutoCloseable {
    method public void close();
    method public android.telephony.mbms.StreamingServiceInfo getInfo();
    method public android.net.Uri getPlaybackUri();
    method public void stopStreaming();
    field public static final int BROADCAST_METHOD = 1; // 0x1
    field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
    field public static final int REASON_END_OF_SESSION = 2; // 0x2
+0 −5
Original line number Diff line number Diff line
@@ -5287,12 +5287,7 @@ package android.telephony.ims.stub {

package android.telephony.mbms {

  public final class DownloadRequest implements android.os.Parcelable {
    method public byte[] getOpaqueData();
  }

  public static class DownloadRequest.Builder {
    method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]);
    method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String);
  }

+59 −27
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.telephony.mbms.DownloadStateCallback;
import android.telephony.mbms.FileInfo;
@@ -53,6 +52,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

@@ -107,11 +107,8 @@ public class MbmsDownloadSession implements AutoCloseable {
    /**
     * {@link Uri} extra that Android will attach to the intent supplied via
     * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
     * Indicates the location of the successfully downloaded file within the temp file root set
     * via {@link #setTempFileRootDirectory(File)}.
     * While you may use this file in-place, it is highly encouraged that you move
     * this file to a different location after receiving the download completion intent, as this
     * file resides within the temp file directory.
     * Indicates the location of the successfully downloaded file within the directory that the
     * app provided via the builder.
     *
     * Will always be set to a non-null value if
     * {@link #EXTRA_MBMS_DOWNLOAD_RESULT} is set to {@link #RESULT_SUCCESSFUL}.
@@ -220,6 +217,8 @@ public class MbmsDownloadSession implements AutoCloseable {
     */
    public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4;

    private static final String DESTINATION_SANITY_CHECK_FILE_NAME = "destinationSanityCheckFile";

    private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);

    private final Context mContext;
@@ -236,23 +235,20 @@ public class MbmsDownloadSession implements AutoCloseable {
    private final Map<DownloadStateCallback, InternalDownloadStateCallback>
            mInternalDownloadCallbacks = new HashMap<>();

    private MbmsDownloadSession(Context context, MbmsDownloadSessionCallback callback,
            int subscriptionId, Handler handler) {
    private MbmsDownloadSession(Context context, Executor executor, int subscriptionId,
            MbmsDownloadSessionCallback callback) {
        mContext = context;
        mSubscriptionId = subscriptionId;
        if (handler == null) {
            handler = new Handler(Looper.getMainLooper());
        }
        mInternalCallback = new InternalDownloadSessionCallback(callback, handler);
        mInternalCallback = new InternalDownloadSessionCallback(callback, executor);
    }

    /**
     * Create a new {@link MbmsDownloadSession} using the system default data subscription ID.
     * See {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)}
     * See {@link #create(Context, Executor, int, MbmsDownloadSessionCallback)}
     */
    public static MbmsDownloadSession create(@NonNull Context context,
            @NonNull MbmsDownloadSessionCallback callback, @NonNull Handler handler) {
        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
            @NonNull Executor executor, @NonNull MbmsDownloadSessionCallback callback) {
        return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
    }

    /**
@@ -279,24 +275,24 @@ public class MbmsDownloadSession implements AutoCloseable {
     * {@link MbmsDownloadSession} that you received before calling this method again.
     *
     * @param context The instance of {@link Context} to use
     * @param callback A callback to get asynchronous error messages and file service updates.
     * @param executor The executor on which you wish to execute callbacks.
     * @param subscriptionId The data subscription ID to use
     * @param handler The {@link Handler} on which callbacks should be enqueued.
     * @param callback A callback to get asynchronous error messages and file service updates.
     * @return A new instance of {@link MbmsDownloadSession}, or null if an error occurred during
     * setup.
     */
    public static @Nullable MbmsDownloadSession create(@NonNull Context context,
            final @NonNull MbmsDownloadSessionCallback callback,
            int subscriptionId, @NonNull Handler handler) {
            @NonNull Executor executor, int subscriptionId,
            final @NonNull MbmsDownloadSessionCallback callback) {
        if (!sIsInitialized.compareAndSet(false, true)) {
            throw new IllegalStateException("Cannot have two active instances");
        }
        MbmsDownloadSession session =
                new MbmsDownloadSession(context, callback, subscriptionId, handler);
                new MbmsDownloadSession(context, executor, subscriptionId, callback);
        final int result = session.bindAndInitialize();
        if (result != MbmsErrors.SUCCESS) {
            sIsInitialized.set(false);
            handler.post(new Runnable() {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    callback.onError(result, null);
@@ -500,6 +496,10 @@ public class MbmsDownloadSession implements AutoCloseable {
     * {@link MbmsDownloadSession#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY} and store that as the temp
     * file root directory.
     *
     * If the {@link DownloadRequest} has a destination that is not on the same filesystem as the
     * temp file directory provided via {@link #getTempFileRootDirectory()}, an
     * {@link IllegalArgumentException} will be thrown.
     *
     * Asynchronous errors through the callback may include any error not specific to the
     * streaming use-case.
     * @param request The request that specifies what should be downloaded.
@@ -522,6 +522,8 @@ public class MbmsDownloadSession implements AutoCloseable {
            setTempFileRootDirectory(tempRootDirectory);
        }

        checkDownloadRequestDestination(request);

        try {
            int result = downloadService.download(request);
            if (result == MbmsErrors.SUCCESS) {
@@ -568,21 +570,21 @@ public class MbmsDownloadSession implements AutoCloseable {
     * this method will throw an {@link IllegalArgumentException}.
     *
     * @param request The {@link DownloadRequest} that you want updates on.
     * @param executor The {@link Executor} on which calls to {@code callback} should be executed.
     * @param callback The callback that should be called when the middleware has information to
     *                 share on the download.
     * @param handler The {@link Handler} on which calls to {@code callback} should be enqueued on.
     * @return {@link MbmsErrors#SUCCESS} if the operation did not encounter a synchronous error,
     * and some other error code otherwise.
     */
    public int registerStateCallback(@NonNull DownloadRequest request,
            @NonNull DownloadStateCallback callback, @NonNull Handler handler) {
            @NonNull Executor executor, @NonNull DownloadStateCallback callback) {
        IMbmsDownloadService downloadService = mService.get();
        if (downloadService == null) {
            throw new IllegalStateException("Middleware not yet bound");
        }

        InternalDownloadStateCallback internalCallback =
                new InternalDownloadStateCallback(callback, handler);
                new InternalDownloadStateCallback(callback, executor);

        try {
            int result = downloadService.registerStateCallback(request, internalCallback,
@@ -604,7 +606,7 @@ public class MbmsDownloadSession implements AutoCloseable {

    /**
     * Un-register a callback previously registered via
     * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}. After
     * {@link #registerStateCallback(DownloadRequest, Executor, DownloadStateCallback)}. After
     * this method is called, no further callbacks will be enqueued on the {@link Handler}
     * provided upon registration, even if this method throws an exception.
     *
@@ -692,7 +694,7 @@ public class MbmsDownloadSession implements AutoCloseable {
     * The state will be delivered as a callback via
     * {@link DownloadStateCallback#onStateUpdated(DownloadRequest, FileInfo, int)}. If no such
     * callback has been registered via
     * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}, this
     * {@link #registerStateCallback(DownloadRequest, Executor, DownloadStateCallback)}, this
     * method will be a no-op.
     *
     * If the middleware has no record of the
@@ -775,7 +777,7 @@ public class MbmsDownloadSession implements AutoCloseable {
     * instance of {@link MbmsDownloadSessionCallback}, but callbacks that have already been
     * enqueued will still be delivered.
     *
     * It is safe to call {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)} to
     * It is safe to call {@link #create(Context, Executor, int, MbmsDownloadSessionCallback)} to
     * obtain another instance of {@link MbmsDownloadSession} immediately after this method
     * returns.
     *
@@ -831,6 +833,36 @@ public class MbmsDownloadSession implements AutoCloseable {
        }
    }

    private void checkDownloadRequestDestination(DownloadRequest request) {
        File downloadRequestDestination = new File(request.getDestinationUri().getPath());
        if (!downloadRequestDestination.isDirectory()) {
            throw new IllegalArgumentException("The destination path must be a directory");
        }
        // Check if the request destination is okay to use by attempting to rename an empty
        // file to there.
        File testFile = new File(MbmsTempFileProvider.getEmbmsTempFileDir(mContext),
                DESTINATION_SANITY_CHECK_FILE_NAME);
        File testFileDestination = new File(downloadRequestDestination,
                DESTINATION_SANITY_CHECK_FILE_NAME);

        try {
            if (!testFile.exists()) {
                testFile.createNewFile();
            }
            if (!testFile.renameTo(testFileDestination)) {
                throw new IllegalArgumentException("Destination provided in the download request " +
                        "is invalid -- files in the temp file directory cannot be directly moved " +
                        "there.");
            }
        } catch (IOException e) {
            throw new IllegalStateException("Got IOException while testing out the destination: "
                    + e);
        } finally {
            testFile.delete();
            testFileDestination.delete();
        }
    }

    private File getDownloadRequestTokenPath(DownloadRequest request) {
        File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
                request.getFileServiceId());
+19 −23
Original line number Diff line number Diff line
@@ -24,9 +24,7 @@ import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.telephony.mbms.InternalStreamingSessionCallback;
import android.telephony.mbms.InternalStreamingServiceCallback;
@@ -42,6 +40,7 @@ import android.util.Log;

import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

@@ -89,14 +88,11 @@ public class MbmsStreamingSession implements AutoCloseable {
    private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;

    /** @hide */
    private MbmsStreamingSession(Context context, MbmsStreamingSessionCallback callback,
                    int subscriptionId, Handler handler) {
    private MbmsStreamingSession(Context context, Executor executor, int subscriptionId,
            MbmsStreamingSessionCallback callback) {
        mContext = context;
        mSubscriptionId = subscriptionId;
        if (handler == null) {
            handler = new Handler(Looper.getMainLooper());
        }
        mInternalCallback = new InternalStreamingSessionCallback(callback, handler);
        mInternalCallback = new InternalStreamingSessionCallback(callback, executor);
    }

    /**
@@ -117,25 +113,25 @@ public class MbmsStreamingSession implements AutoCloseable {
     * {@link MbmsStreamingSession} that you received before calling this method again.
     *
     * @param context The {@link Context} to use.
     * @param executor The executor on which you wish to execute callbacks.
     * @param subscriptionId The subscription ID to use.
     * @param callback A callback object on which you wish to receive results of asynchronous
     *                 operations.
     * @param subscriptionId The subscription ID to use.
     * @param handler The handler you wish to receive callbacks on.
     * @return An instance of {@link MbmsStreamingSession}, or null if an error occurred.
     */
    public static @Nullable MbmsStreamingSession create(@NonNull Context context,
            final @NonNull MbmsStreamingSessionCallback callback, int subscriptionId,
            @NonNull Handler handler) {
            @NonNull Executor executor, int subscriptionId,
            final @NonNull MbmsStreamingSessionCallback callback) {
        if (!sIsInitialized.compareAndSet(false, true)) {
            throw new IllegalStateException("Cannot create two instances of MbmsStreamingSession");
        }
        MbmsStreamingSession session = new MbmsStreamingSession(context, callback,
                subscriptionId, handler);
        MbmsStreamingSession session = new MbmsStreamingSession(context, executor,
                subscriptionId, callback);

        final int result = session.bindAndInitialize();
        if (result != MbmsErrors.SUCCESS) {
            sIsInitialized.set(false);
            handler.post(new Runnable() {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    callback.onError(result, null);
@@ -148,22 +144,22 @@ public class MbmsStreamingSession implements AutoCloseable {

    /**
     * Create a new {@link MbmsStreamingSession} using the system default data subscription ID.
     * See {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)}.
     * See {@link #create(Context, Executor, int, MbmsStreamingSessionCallback)}.
     */
    public static MbmsStreamingSession create(@NonNull Context context,
            @NonNull MbmsStreamingSessionCallback callback, @NonNull Handler handler) {
        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
            @NonNull Executor executor, @NonNull MbmsStreamingSessionCallback callback) {
        return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
    }

    /**
     * Terminates this instance. Also terminates
     * any streaming services spawned from this instance as if
     * {@link StreamingService#stopStreaming()} had been called on them. After this method returns,
     * {@link StreamingService#close()} had been called on them. After this method returns,
     * no further callbacks originating from the middleware will be enqueued on the provided
     * instance of {@link MbmsStreamingSessionCallback}, but callbacks that have already been
     * enqueued will still be delivered.
     *
     * It is safe to call {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)} to
     * It is safe to call {@link #create(Context, Executor, int, MbmsStreamingSessionCallback)} to
     * obtain another instance of {@link MbmsStreamingSession} immediately after this method
     * returns.
     *
@@ -237,20 +233,20 @@ public class MbmsStreamingSession implements AutoCloseable {
     * {@link MbmsErrors.StreamingErrors}.
     *
     * @param serviceInfo The information about the service to stream.
     * @param executor The executor on which you wish to execute callbacks for this stream.
     * @param callback A callback that'll be called when something about the stream changes.
     * @param handler A handler that calls to {@code callback} should be called on.
     * @return An instance of {@link StreamingService} through which the stream can be controlled.
     *         May be {@code null} if an error occurred.
     */
    public @Nullable StreamingService startStreaming(StreamingServiceInfo serviceInfo,
            StreamingServiceCallback callback, @NonNull Handler handler) {
            @NonNull Executor executor, StreamingServiceCallback callback) {
        IMbmsStreamingService streamingService = mService.get();
        if (streamingService == null) {
            throw new IllegalStateException("Middleware not yet bound");
        }

        InternalStreamingServiceCallback serviceCallback = new InternalStreamingServiceCallback(
                callback, handler);
                callback, executor);

        StreamingService serviceForApp = new StreamingService(
                mSubscriptionId, streamingService, this, serviceInfo, serviceCallback);
+119 −70

File changed.

Preview size limit exceeded, changes collapsed.

Loading