1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.providers.media.photopicker; 18 19 import static android.provider.CloudMediaProviderContract.EXTRA_AUTHORITY; 20 import static android.provider.CloudMediaProviderContract.EXTRA_LOOPING_PLAYBACK_ENABLED; 21 import static android.provider.CloudMediaProviderContract.EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED; 22 23 import android.content.res.AssetFileDescriptor; 24 import android.database.Cursor; 25 import android.graphics.Point; 26 import android.os.Bundle; 27 import android.os.CancellationSignal; 28 import android.os.ParcelFileDescriptor; 29 import android.os.RemoteException; 30 import android.provider.CloudMediaProvider; 31 import android.provider.ICloudMediaSurfaceController; 32 import android.util.Log; 33 import android.view.Surface; 34 35 import androidx.annotation.NonNull; 36 import androidx.annotation.Nullable; 37 38 import com.android.providers.media.photopicker.ui.remotepreview.RemoteSurfaceController; 39 40 import java.io.FileNotFoundException; 41 42 /** 43 * Implements the {@link CloudMediaProvider} interface over the local items in the MediaProvider 44 * database. 45 */ 46 public class RemoteVideoPreviewProvider extends CloudMediaProvider { 47 private static final String TAG = "RemoteVideoPreviewProvider"; 48 public static final String AUTHORITY = 49 "com.android.providers.media.remote_video_preview"; 50 51 @Override onCreate()52 public boolean onCreate() { 53 return true; 54 } 55 56 @Override onQueryMedia(Bundle extras)57 public Cursor onQueryMedia(Bundle extras) { 58 throw new UnsupportedOperationException("onQueryMedia not supported"); 59 } 60 61 @Override onQueryDeletedMedia(Bundle extras)62 public Cursor onQueryDeletedMedia(Bundle extras) { 63 throw new UnsupportedOperationException("onQueryDeletedMedia not supported"); 64 } 65 66 @Override onOpenPreview(String mediaId, Point size, Bundle extras, CancellationSignal signal)67 public AssetFileDescriptor onOpenPreview(String mediaId, Point size, Bundle extras, 68 CancellationSignal signal) throws FileNotFoundException { 69 throw new UnsupportedOperationException("onOpenPreview not supported"); 70 } 71 72 @Override onOpenMedia(String mediaId, Bundle extras, CancellationSignal signal)73 public ParcelFileDescriptor onOpenMedia(String mediaId, Bundle extras, 74 CancellationSignal signal) throws FileNotFoundException { 75 throw new UnsupportedOperationException("onOpenMedia not supported"); 76 } 77 78 @Override onGetMediaCollectionInfo(Bundle extras)79 public Bundle onGetMediaCollectionInfo(Bundle extras) { 80 throw new UnsupportedOperationException("onGetMediaCollectionInfo not supported"); 81 } 82 83 @Override 84 @Nullable onCreateCloudMediaSurfaceController(@onNull Bundle config, CloudMediaSurfaceStateChangedCallback callback)85 public CloudMediaSurfaceController onCreateCloudMediaSurfaceController(@NonNull Bundle config, 86 CloudMediaSurfaceStateChangedCallback callback) { 87 final String authority = config.getString(EXTRA_AUTHORITY); 88 if (authority == null) { 89 throw new IllegalArgumentException("No cloud provider authority available"); 90 } 91 92 final boolean enableLoop = config.getBoolean(EXTRA_LOOPING_PLAYBACK_ENABLED, false); 93 final boolean muteAudio = config.getBoolean(EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED, 94 false); 95 return new RemoteSurfaceController(getContext(), authority, enableLoop, muteAudio, 96 callback); 97 } 98 99 /** 100 * {@link CloudMediaSurfaceController} implementation that proxies all requests to a 'remote' 101 * {@link RemoteSurfaceController}. 102 */ 103 public static class SurfaceControllerProxy extends CloudMediaSurfaceController { 104 private final ICloudMediaSurfaceController mController; 105 SurfaceControllerProxy(ICloudMediaSurfaceController controller)106 public SurfaceControllerProxy(ICloudMediaSurfaceController controller) { 107 mController = controller; 108 } 109 110 @Override onPlayerCreate()111 public void onPlayerCreate() { 112 try { 113 mController.onPlayerCreate(); 114 } catch (RemoteException e) { 115 Log.e(TAG, "onPlayerCreate failed", e); 116 } 117 } 118 119 @Override onPlayerRelease()120 public void onPlayerRelease() { 121 try { 122 mController.onPlayerRelease(); 123 } catch (RemoteException e) { 124 Log.e(TAG, "onPlayerRelease failed", e); 125 } 126 } 127 128 @Override onSurfaceCreated(int surfaceId, @NonNull Surface surface, @NonNull String mediaId)129 public void onSurfaceCreated(int surfaceId, @NonNull Surface surface, 130 @NonNull String mediaId) { 131 try { 132 mController.onSurfaceCreated(surfaceId, surface, mediaId); 133 } catch (RemoteException e) { 134 Log.e(TAG, "onSurfaceCreated failed", e); 135 } 136 } 137 138 @Override onSurfaceChanged(int surfaceId, int format, int width, int height)139 public void onSurfaceChanged(int surfaceId, int format, int width, int height) { 140 try { 141 mController.onSurfaceChanged(surfaceId, format, width, height); 142 } catch (RemoteException e) { 143 Log.e(TAG, "onSurfaceChanged failed", e); 144 } 145 } 146 147 @Override onSurfaceDestroyed(int surfaceId)148 public void onSurfaceDestroyed(int surfaceId) { 149 try { 150 mController.onSurfaceDestroyed(surfaceId); 151 } catch (RemoteException e) { 152 Log.e(TAG, "onSurfaceDestroyed failed", e); 153 } 154 } 155 156 @Override onMediaPlay(int surfaceId)157 public void onMediaPlay(int surfaceId) { 158 try { 159 mController.onMediaPlay(surfaceId); 160 } catch (RemoteException e) { 161 Log.e(TAG, "onMediaPlay failed", e); 162 } 163 } 164 165 @Override onMediaPause(int surfaceId)166 public void onMediaPause(int surfaceId) { 167 try { 168 mController.onMediaPause(surfaceId); 169 } catch (RemoteException e) { 170 Log.e(TAG, "onMediaPause failed", e); 171 } 172 } 173 174 @Override onMediaSeekTo(int surfaceId, long timestampMillis)175 public void onMediaSeekTo(int surfaceId, long timestampMillis) { 176 try { 177 mController.onMediaSeekTo(surfaceId, timestampMillis); 178 } catch (RemoteException e) { 179 Log.e(TAG, "onMediaSeekTo failed", e); 180 } 181 } 182 183 @Override onConfigChange(@onNull Bundle config)184 public void onConfigChange(@NonNull Bundle config) { 185 try { 186 mController.onConfigChange(config); 187 } catch (RemoteException e) { 188 Log.e(TAG, "onConfigChange failed", e); 189 } 190 } 191 192 @Override onDestroy()193 public void onDestroy() { 194 try { 195 mController.onDestroy(); 196 } catch (RemoteException e) { 197 Log.e(TAG, "onDestroy failed", e); 198 } 199 } 200 } 201 } 202