1 /*
2  * Copyright (C) 2021 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.bedstead.remoteframeworkclasses;
18 
19 import android.accounts.AccountManagerFuture;
20 import android.accounts.AuthenticatorException;
21 import android.accounts.OperationCanceledException;
22 
23 import com.google.android.enterprise.connectedapps.FutureWrapper;
24 import com.google.android.enterprise.connectedapps.Profile;
25 import com.google.android.enterprise.connectedapps.annotations.CustomFutureWrapper;
26 import com.google.android.enterprise.connectedapps.internal.Bundler;
27 import com.google.android.enterprise.connectedapps.internal.BundlerType;
28 import com.google.android.enterprise.connectedapps.internal.CrossProfileCallbackMultiMerger;
29 import com.google.android.enterprise.connectedapps.internal.FutureResultWriter;
30 
31 import java.io.IOException;
32 import java.util.Map;
33 
34 /**
35  * Future wrapper for {@link AccountManagerFuture}.
36  *
37  * @param <V> Wrapped future result
38  */
39 @CustomFutureWrapper(originalType = AccountManagerFuture.class)
40 public class AccountManagerFutureWrapper<V> extends FutureWrapper<V> {
41 
42     private final SimpleAccountManagerFuture<V> mFuture = new SimpleAccountManagerFuture<>();
43 
AccountManagerFutureWrapper(Bundler bundler, BundlerType bundlerType)44     private AccountManagerFutureWrapper(Bundler bundler, BundlerType bundlerType) {
45         super(bundler, bundlerType);
46     }
47 
48     /** Create a {@link AccountManagerFutureWrapper}. */
create( Bundler bundler, BundlerType bundlerType)49     public static <V> AccountManagerFutureWrapper<V> create(
50             Bundler bundler, BundlerType bundlerType) {
51         return new AccountManagerFutureWrapper<>(bundler, bundlerType);
52     }
53 
54     /** Write a result from an {@link AccountManagerFuture}. */
writeFutureResult( AccountManagerFuture<V> future, FutureResultWriter<V> futureResultWriter)55     public static <V> void writeFutureResult(
56             AccountManagerFuture<V> future, FutureResultWriter<V> futureResultWriter) {
57         try {
58             futureResultWriter.onSuccess(future.getResult());
59         } catch (OperationCanceledException | IOException | AuthenticatorException e) {
60             futureResultWriter.onFailure(e);
61         }
62     }
63 
64     /** Group multiple results from {@link AccountManagerFuture}. */
groupResults( Map<Profile, AccountManagerFuture<E>> results)65     public static <E> AccountManagerFuture<Map<Profile, E>> groupResults(
66             Map<Profile, AccountManagerFuture<E>> results) {
67         SimpleAccountManagerFuture<Map<Profile, E>> m = new SimpleAccountManagerFuture<>();
68 
69         CrossProfileCallbackMultiMerger<E> merger =
70                 new CrossProfileCallbackMultiMerger<>(results.size(), m::setResult);
71         for (Map.Entry<Profile, AccountManagerFuture<E>> result : results.entrySet()) {
72             try {
73                 merger.onResult(result.getKey(), result.getValue().getResult());
74             } catch (OperationCanceledException | IOException | AuthenticatorException e) {
75                 merger.missingResult(result.getKey());
76             }
77         }
78         return m;
79     }
80 
81     /** Get the wrapped future. */
getFuture()82     public AccountManagerFuture<V> getFuture() {
83         return mFuture;
84     }
85 
86     @Override
onResult(V result)87     public void onResult(V result) {
88         mFuture.setResult(result);
89     }
90 
91     @Override
onException(Throwable throwable)92     public void onException(Throwable throwable) {
93         mFuture.setException(throwable);
94     }
95 }
96