1 /* 2 * Copyright (C) 2024 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 android.widget.photopicker; 18 19 import android.annotation.RequiresApi; 20 import android.content.res.Configuration; 21 import android.net.Uri; 22 import android.os.Build; 23 import android.os.IBinder; 24 import android.os.RemoteException; 25 import android.view.SurfaceControlViewHost; 26 27 import androidx.annotation.NonNull; 28 29 import java.util.List; 30 31 /** 32 * Wrapper class to {@link EmbeddedPhotoPickerSession} for internal use that helps with IPC between 33 * caller of {@link EmbeddedPhotoPickerProvider#openSession} api and service inside PhotoPicker apk. 34 * 35 * <p> This class implements the {@link EmbeddedPhotoPickerSession} interface to convert incoming 36 * calls on to it from app and send it to the service. It uses {@link IEmbeddedPhotoPickerSession} 37 * as the delegate 38 * 39 * @see EmbeddedPhotoPickerSession 40 * 41 * @hide 42 */ 43 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 44 class EmbeddedPhotoPickerSessionWrapper implements EmbeddedPhotoPickerSession, 45 IBinder.DeathRecipient { 46 private final EmbeddedPhotoPickerProviderFactory mProvider; 47 private final EmbeddedPhotoPickerSessionResponse mSessionResponse; 48 private final IEmbeddedPhotoPickerSession mSession; 49 private final EmbeddedPhotoPickerClient mClient; 50 private final EmbeddedPhotoPickerClientWrapper mClientWrapper; 51 EmbeddedPhotoPickerSessionWrapper(EmbeddedPhotoPickerProviderFactory provider, EmbeddedPhotoPickerSessionResponse mSessionResponse, EmbeddedPhotoPickerClient mClient, EmbeddedPhotoPickerClientWrapper clientWrapper)52 EmbeddedPhotoPickerSessionWrapper(EmbeddedPhotoPickerProviderFactory provider, 53 EmbeddedPhotoPickerSessionResponse mSessionResponse, EmbeddedPhotoPickerClient mClient, 54 EmbeddedPhotoPickerClientWrapper clientWrapper) { 55 this.mProvider = provider; 56 this.mSessionResponse = mSessionResponse; 57 this.mSession = mSessionResponse.getSession(); 58 this.mClient = mClient; 59 this.mClientWrapper = clientWrapper; 60 61 linkDeathRecipient(); 62 } 63 linkDeathRecipient()64 private void linkDeathRecipient() { 65 try { 66 mSession.asBinder().linkToDeath(this, 0 /* flags*/); 67 } catch (RemoteException e) { 68 this.binderDied(); 69 } 70 } 71 72 @Override getSurfacePackage()73 public SurfaceControlViewHost.SurfacePackage getSurfacePackage() { 74 return mSessionResponse.getSurfacePackage(); 75 } 76 77 @Override close()78 public void close() { 79 mProvider.onSessionClosed(mClient); 80 try { 81 mSession.close(); 82 } catch (RemoteException e) { 83 e.rethrowAsRuntimeException(); 84 } 85 } 86 notifyVisibilityChanged(boolean isVisible)87 public void notifyVisibilityChanged(boolean isVisible) { 88 try { 89 mSession.notifyVisibilityChanged(isVisible); 90 } catch (RemoteException e) { 91 e.rethrowAsRuntimeException(); 92 } 93 } 94 95 @Override notifyResized(int width, int height)96 public void notifyResized(int width, int height) { 97 try { 98 mSession.notifyResized(width, height); 99 } catch (RemoteException e) { 100 e.rethrowAsRuntimeException(); 101 } 102 } 103 104 @Override notifyConfigurationChanged(Configuration configuration)105 public void notifyConfigurationChanged(Configuration configuration) { 106 try { 107 mSession.notifyConfigurationChanged(configuration); 108 } catch (RemoteException e) { 109 e.rethrowAsRuntimeException(); 110 } 111 } 112 113 @Override notifyPhotoPickerExpanded(boolean isExpanded)114 public void notifyPhotoPickerExpanded(boolean isExpanded) { 115 try { 116 mSession.notifyPhotopickerExpanded(isExpanded); 117 } catch (RemoteException e) { 118 e.rethrowAsRuntimeException(); 119 } 120 } 121 122 @Override requestRevokeUriPermission(@onNull List<Uri> uris)123 public void requestRevokeUriPermission(@NonNull List<Uri> uris) { 124 try { 125 mSession.requestRevokeUriPermission(uris); 126 } catch (RemoteException e) { 127 e.rethrowAsRuntimeException(); 128 } 129 } 130 131 @Override binderDied()132 public void binderDied() { 133 mClientWrapper.onSessionError(new ParcelableException( 134 new RuntimeException("Binder object hosting this session has died. " 135 + "Clean up resources."))); 136 } 137 138 } 139 140