1 /* 2 * Copyright (C) 2023 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.federatedcompute; 18 19 import android.annotation.NonNull; 20 import android.federatedcompute.ExampleStoreService.QueryCallback; 21 import android.federatedcompute.aidl.IExampleStoreCallback; 22 import android.federatedcompute.aidl.IExampleStoreIterator; 23 import android.federatedcompute.aidl.IExampleStoreIteratorCallback; 24 import android.os.Bundle; 25 import android.os.RemoteException; 26 import android.util.Log; 27 28 import com.android.internal.util.Preconditions; 29 30 /** 31 * Forward results from the app to the wrapped AIDL callback. 32 * 33 * @hide 34 */ 35 public class ExampleStoreQueryCallbackImpl implements QueryCallback { 36 private static final String TAG = "ExampleStoreQueryCallbackImpl"; 37 private final IExampleStoreCallback mExampleStoreQueryCallback; 38 ExampleStoreQueryCallbackImpl(IExampleStoreCallback exampleStoreQueryCallback)39 public ExampleStoreQueryCallbackImpl(IExampleStoreCallback exampleStoreQueryCallback) { 40 this.mExampleStoreQueryCallback = exampleStoreQueryCallback; 41 } 42 43 @Override onStartQuerySuccess(@onNull ExampleStoreIterator iterator)44 public void onStartQuerySuccess(@NonNull ExampleStoreIterator iterator) { 45 Preconditions.checkNotNull(iterator, "iterator must not be null"); 46 IteratorAdapter iteratorAdapter = new IteratorAdapter(iterator); 47 try { 48 mExampleStoreQueryCallback.onStartQuerySuccess(iteratorAdapter); 49 } catch (RemoteException e) { 50 Log.w(TAG, "onIteratorNextSuccess AIDL call failed, closing iterator", e); 51 iteratorAdapter.close(); 52 } 53 } 54 55 @Override onStartQueryFailure(int errorCode)56 public void onStartQueryFailure(int errorCode) { 57 try { 58 mExampleStoreQueryCallback.onStartQueryFailure(errorCode); 59 } catch (RemoteException e) { 60 Log.w(TAG, "onIteratorNextFailure AIDL call failed, closing iterator", e); 61 } 62 } 63 /** 64 * The implementation of {@link IExampleStoreIterator}. 65 * 66 * @hide 67 */ 68 public static class IteratorAdapter extends IExampleStoreIterator.Stub { 69 private final ExampleStoreIterator mIterator; 70 private final Object mLock = new Object(); 71 private boolean mClosed = false; 72 IteratorAdapter(ExampleStoreIterator iterator)73 public IteratorAdapter(ExampleStoreIterator iterator) { 74 this.mIterator = iterator; 75 } 76 77 @Override next(IExampleStoreIteratorCallback callback)78 public void next(IExampleStoreIteratorCallback callback) { 79 Preconditions.checkNotNull(callback, "callback must not be null"); 80 synchronized (mLock) { 81 if (mClosed) { 82 Log.w(TAG, "IExampleStoreIterator.next called after close"); 83 return; 84 } 85 IteratorCallbackAdapter callbackAdapter = 86 new IteratorCallbackAdapter(callback, this); 87 mIterator.next(callbackAdapter); 88 } 89 } 90 91 @Override close()92 public void close() { 93 synchronized (mLock) { 94 if (mClosed) { 95 Log.w(TAG, "IExampleStoreIterator.close called more than once"); 96 return; 97 } 98 mClosed = true; 99 } 100 mIterator.close(); 101 } 102 } 103 /** 104 * The implementation of {@link ExampleStoreIterator.IteratorCallback} that FederatedCompute 105 * pass to the apps. 106 * 107 * @hide 108 */ 109 public static final class IteratorCallbackAdapter 110 implements ExampleStoreIterator.IteratorCallback { 111 private final IExampleStoreIteratorCallback mExampleStoreIteratorCallback; 112 private final IteratorAdapter mIteratorAdapter; 113 IteratorCallbackAdapter( IExampleStoreIteratorCallback exampleStoreIteratorCallback, IteratorAdapter iteratorAdapter)114 public IteratorCallbackAdapter( 115 IExampleStoreIteratorCallback exampleStoreIteratorCallback, 116 IteratorAdapter iteratorAdapter) { 117 this.mExampleStoreIteratorCallback = exampleStoreIteratorCallback; 118 this.mIteratorAdapter = iteratorAdapter; 119 } 120 121 @Override onIteratorNextSuccess(Bundle result)122 public boolean onIteratorNextSuccess(Bundle result) { 123 try { 124 mExampleStoreIteratorCallback.onIteratorNextSuccess(result); 125 return true; 126 } catch (RemoteException e) { 127 Log.w(TAG, "onIteratorNextSuccess AIDL call failed, closing iterator", e); 128 mIteratorAdapter.close(); 129 } 130 return false; 131 } 132 133 @Override onIteratorNextFailure(int errorCode)134 public void onIteratorNextFailure(int errorCode) { 135 try { 136 mExampleStoreIteratorCallback.onIteratorNextFailure(errorCode); 137 } catch (RemoteException e) { 138 Log.w(TAG, "onIteratorNextFailure AIDL call failed, closing iterator", e); 139 mIteratorAdapter.close(); 140 } 141 } 142 } 143 } 144