/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.federatedcompute; import android.annotation.NonNull; import android.federatedcompute.ExampleStoreService.QueryCallback; import android.federatedcompute.aidl.IExampleStoreCallback; import android.federatedcompute.aidl.IExampleStoreIterator; import android.federatedcompute.aidl.IExampleStoreIteratorCallback; import android.os.Bundle; import android.os.RemoteException; import com.android.federatedcompute.internal.util.LogUtil; import com.android.internal.util.Preconditions; /** * Forward results from the app to the wrapped AIDL callback. * * @hide */ public class ExampleStoreQueryCallbackImpl implements QueryCallback { private static final String TAG = "ExampleStoreQueryCallbackImpl"; private final IExampleStoreCallback mExampleStoreQueryCallback; public ExampleStoreQueryCallbackImpl(IExampleStoreCallback exampleStoreQueryCallback) { this.mExampleStoreQueryCallback = exampleStoreQueryCallback; } @Override public void onStartQuerySuccess(@NonNull ExampleStoreIterator iterator) { Preconditions.checkNotNull(iterator, "iterator must not be null"); IteratorAdapter iteratorAdapter = new IteratorAdapter(iterator); try { mExampleStoreQueryCallback.onStartQuerySuccess(iteratorAdapter); } catch (RemoteException e) { LogUtil.w(TAG, e, "onIteratorNextSuccess AIDL call failed, closing iterator"); iteratorAdapter.close(); } } @Override public void onStartQueryFailure(int errorCode) { try { mExampleStoreQueryCallback.onStartQueryFailure(errorCode); } catch (RemoteException e) { LogUtil.w(TAG, e, "onIteratorNextFailure AIDL call failed, closing iterator"); } } /** * The implementation of {@link IExampleStoreIterator}. * * @hide */ public static class IteratorAdapter extends IExampleStoreIterator.Stub { private final ExampleStoreIterator mIterator; private final Object mLock = new Object(); private boolean mClosed = false; public IteratorAdapter(ExampleStoreIterator iterator) { this.mIterator = iterator; } @Override public void next(IExampleStoreIteratorCallback callback) { Preconditions.checkNotNull(callback, "callback must not be null"); synchronized (mLock) { if (mClosed) { LogUtil.w(TAG, "IExampleStoreIterator.next called after close"); return; } IteratorCallbackAdapter callbackAdapter = new IteratorCallbackAdapter(callback, this); mIterator.next(callbackAdapter); } } @Override public void close() { synchronized (mLock) { if (mClosed) { LogUtil.w(TAG, "IExampleStoreIterator.close called more than once"); return; } mClosed = true; } mIterator.close(); } } /** * The implementation of {@link ExampleStoreIterator.IteratorCallback} that FederatedCompute * pass to the apps. * * @hide */ public static final class IteratorCallbackAdapter implements ExampleStoreIterator.IteratorCallback { private final IExampleStoreIteratorCallback mExampleStoreIteratorCallback; private final IteratorAdapter mIteratorAdapter; public IteratorCallbackAdapter( IExampleStoreIteratorCallback exampleStoreIteratorCallback, IteratorAdapter iteratorAdapter) { this.mExampleStoreIteratorCallback = exampleStoreIteratorCallback; this.mIteratorAdapter = iteratorAdapter; } @Override public boolean onIteratorNextSuccess(Bundle result) { try { mExampleStoreIteratorCallback.onIteratorNextSuccess(result); return true; } catch (RemoteException e) { LogUtil.w(TAG, e, "onIteratorNextSuccess AIDL call failed, closing iterator"); mIteratorAdapter.close(); } return false; } @Override public void onIteratorNextFailure(int errorCode) { try { mExampleStoreIteratorCallback.onIteratorNextFailure(errorCode); } catch (RemoteException e) { LogUtil.w(TAG, e, "onIteratorNextFailure AIDL call failed, closing iterator"); mIteratorAdapter.close(); } } } }