ContextHubTransaction.java revision 4493e1498455147a4aefc3c0a8534e43d64177c3
1b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro/*
2b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * Copyright 2017 The Android Open Source Project
3b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
4b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * Licensed under the Apache License, Version 2.0 (the "License");
5b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * you may not use this file except in compliance with the License.
6b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * You may obtain a copy of the License at
7b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
8b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *      http://www.apache.org/licenses/LICENSE-2.0
9b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
10b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * Unless required by applicable law or agreed to in writing, software
11b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * distributed under the License is distributed on an "AS IS" BASIS,
12b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * See the License for the specific language governing permissions and
14b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * limitations under the License.
15b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro */
16b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguropackage android.hardware.location;
17b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
18b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguroimport android.annotation.IntDef;
196c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguroimport android.annotation.NonNull;
20b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguroimport android.os.Handler;
216c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguroimport android.os.Looper;
226c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguroimport android.util.Log;
23b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
24b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguroimport java.lang.annotation.Retention;
25b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguroimport java.lang.annotation.RetentionPolicy;
266c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguroimport java.util.concurrent.CountDownLatch;
27b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguroimport java.util.concurrent.TimeUnit;
286c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguroimport java.util.concurrent.TimeoutException;
29b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
30b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro/**
31b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * A class describing a request sent to the Context Hub Service.
32b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
33b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * This object is generated as a result of an asynchronous request sent to the Context Hub
34b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * through the ContextHubManager APIs. The caller can either retrieve the result
35b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * synchronously through a blocking call ({@link #waitForResponse(long, TimeUnit)}) or
36b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * asynchronously through a user-defined callback
376c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro * ({@link #setCallbackOnComplete(ContextHubTransaction.Callback, Handler)}).
38b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
39b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * @param <T> the type of the contents in the transaction response
40b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro *
41b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro * @hide
42b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro */
43b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguropublic class ContextHubTransaction<T> {
446c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    private static final String TAG = "ContextHubTransaction";
456c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
46b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
47b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Constants describing the type of a transaction through the Context Hub Service.
48b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
49b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @Retention(RetentionPolicy.SOURCE)
50b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @IntDef({
51b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TYPE_LOAD_NANOAPP,
52b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TYPE_UNLOAD_NANOAPP,
53b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TYPE_ENABLE_NANOAPP,
54b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TYPE_DISABLE_NANOAPP,
55b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TYPE_QUERY_NANOAPPS})
56b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public @interface Type {}
57b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TYPE_LOAD_NANOAPP = 0;
58b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TYPE_UNLOAD_NANOAPP = 1;
59b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TYPE_ENABLE_NANOAPP = 2;
60b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TYPE_DISABLE_NANOAPP = 3;
61b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TYPE_QUERY_NANOAPPS = 4;
62b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
63b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
64b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Constants describing the result of a transaction or request through the Context Hub Service.
65b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
66b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @Retention(RetentionPolicy.SOURCE)
67b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @IntDef({
68b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_SUCCESS,
69b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_FAILED_UNKNOWN,
70b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_FAILED_BAD_PARAMS,
71b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_FAILED_UNINITIALIZED,
72b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_FAILED_PENDING,
73b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            TRANSACTION_FAILED_AT_HUB,
746c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            TRANSACTION_FAILED_TIMEOUT,
75e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro            TRANSACTION_FAILED_SERVICE_INTERNAL_FAILURE,
76e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro            TRANSACTION_FAILED_HAL_UNAVAILABLE})
77b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public @interface Result {}
78b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_SUCCESS = 0;
79b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
80b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Generic failure mode.
81b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
82b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_UNKNOWN = 1;
83b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
84b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Failure mode when the request parameters were not valid.
85b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
86b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_BAD_PARAMS = 2;
87b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
88b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Failure mode when the Context Hub is not initialized.
89b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
90b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_UNINITIALIZED = 3;
91b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
92b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Failure mode when there are too many transactions pending.
93b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
94b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_PENDING = 4;
95b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
96b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Failure mode when the request went through, but failed asynchronously at the hub.
97b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
98b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_AT_HUB = 5;
99b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
100b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Failure mode when the transaction has timed out.
101b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
102b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static final int TRANSACTION_FAILED_TIMEOUT = 6;
1036c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    /**
1046c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * Failure mode when the transaction has failed internally at the service.
1056c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     */
1066c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    public static final int TRANSACTION_FAILED_SERVICE_INTERNAL_FAILURE = 7;
107e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro    /**
108e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro     * Failure mode when the Context Hub HAL was not available.
109e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro     */
110e1ade4368f8b3739e93bc3f6aefabda8b2b4424cArthur Ishiguro    public static final int TRANSACTION_FAILED_HAL_UNAVAILABLE = 8;
111b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
112b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
113b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * A class describing the response for a ContextHubTransaction.
114b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
115b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param <R> the type of the contents in the response
116b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
117b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public static class Response<R> {
118b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        /*
119b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         * The result of the transaction.
120b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         */
121b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        @ContextHubTransaction.Result
122b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        private int mResult;
123b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
124b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        /*
125b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         * The contents of the response from the Context Hub.
126b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         */
127b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        private R mContents;
128b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
129b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        Response(@ContextHubTransaction.Result int result, R contents) {
130b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            mResult = result;
131b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            mContents = contents;
132b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        }
133b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
134b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        @ContextHubTransaction.Result
135b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        public int getResult() {
136b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            return mResult;
137b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        }
138b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
139b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        public R getContents() {
140b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro            return mContents;
141b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        }
142b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
143b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
144b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
145b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * An interface describing the callback to be invoked when a transaction completes.
146b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
147b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param <C> the type of the contents in the transaction response
148b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
149b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @FunctionalInterface
150b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public interface Callback<C> {
151b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        /**
152b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         * The callback to invoke when the transaction completes.
153b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         *
154b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         * @param transaction the transaction that this callback was attached to.
155b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         * @param response the response of the transaction.
156b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro         */
157b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        void onComplete(
158b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro                ContextHubTransaction<C> transaction, ContextHubTransaction.Response<C> response);
159b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
160b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
161b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /*
162b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * The type of the transaction.
163b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
164b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @Type
165b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    private int mTransactionType;
166b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
167b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /*
168b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * The response of the transaction.
169b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
170b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    private ContextHubTransaction.Response<T> mResponse;
171b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
172b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /*
173b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * The handler to invoke the aynsc response supplied by onComplete.
174b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
175b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    private Handler mHandler = null;
176b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
177b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /*
178b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * The callback to invoke when the transaction completes.
179b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
180b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    private ContextHubTransaction.Callback<T> mCallback = null;
181b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
1826c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    /*
1836c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * Synchronization latch used to block on response.
1846c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     */
1856c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    private final CountDownLatch mDoneSignal = new CountDownLatch(1);
1866c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
1876c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    /*
1886c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * true if the response has been set throught setResponse, false otherwise.
1896c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     */
1906c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    private boolean mIsResponseSet = false;
1916c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
1926c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    ContextHubTransaction(@Type int type) {
193b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        mTransactionType = type;
194b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
195b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
196b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
1974493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     * Converts a transaction type to a human-readable string
1984493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     *
1994493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     * @param type the type of a transaction
2004493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     * @param upperCase {@code true} if upper case the first letter, {@code false} otherwise
2014493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     * @return a string describing the transaction
2024493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     */
2034493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro    public static String typeToString(@Type int type, boolean upperCase) {
2044493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro        switch (type) {
2054493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            case ContextHubTransaction.TYPE_LOAD_NANOAPP:
2064493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Load" : "load";
2074493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            case ContextHubTransaction.TYPE_UNLOAD_NANOAPP:
2084493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Unload" : "unload";
2094493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            case ContextHubTransaction.TYPE_ENABLE_NANOAPP:
2104493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Enable" : "enable";
2114493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            case ContextHubTransaction.TYPE_DISABLE_NANOAPP:
2124493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Disable" : "disable";
2134493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            case ContextHubTransaction.TYPE_QUERY_NANOAPPS:
2144493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Query" : "query";
2154493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro            default:
2164493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro                return upperCase ? "Unknown" : "unknown";
2174493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro        }
2184493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro    }
2194493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro
2204493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro    /**
221b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @return the type of the transaction
222b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
223b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    @Type
224b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    public int getType() {
225b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro        return mTransactionType;
226b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
227b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
228b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
229b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Waits to receive the asynchronous transaction result.
230b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
231b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * This function blocks until the Context Hub Service has received a response
232b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * for the transaction represented by this object by the Context Hub, or a
233b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * specified timeout period has elapsed.
234b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
2356c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * If the specified timeout has passed, a TimeoutException will be thrown and the caller may
2366c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * retry the invocation of this method at a later time.
237b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
238b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param timeout the timeout duration
239b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param unit the unit of the timeout
240b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
241b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @return the transaction response
2426c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
2436c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws InterruptedException if the current thread is interrupted while waiting for response
2446c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws TimeoutException if the timeout period has passed
245b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
2466c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    public ContextHubTransaction.Response<T> waitForResponse(
2476c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
2486c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        boolean success = mDoneSignal.await(timeout, unit);
2496c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
2506c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        if (!success) {
2516c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            throw new TimeoutException("Timed out while waiting for transaction");
2526c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        }
2536c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
2546c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        return mResponse;
255b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
256b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
257b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    /**
258b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * Sets a callback to be invoked when the transaction completes.
259b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
260b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * This function provides an asynchronous approach to retrieve the result of the
261b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * transaction. When the transaction response has been provided by the Context Hub,
262b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * the given callback will be posted by the provided handler.
263b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
264b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * If the transaction has already completed at the time of invocation, the callback
265b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * will be immediately posted by the handler. If the transaction has been invalidated,
266b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * the callback will never be invoked.
267b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     *
2686c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * A transaction can be invalidated if the process owning the transaction is no longer active
2696c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * and the reference to this object is lost.
2706c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
2714493e1498455147a4aefc3c0a8534e43d64177c3Arthur Ishiguro     * This method or {@link #setCallbackOnComplete(ContextHubTransaction.Callback)} can only be
2726c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * invoked once, or an IllegalStateException will be thrown.
2736c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
274b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param callback the callback to be invoked upon completion
275b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     * @param handler the handler to post the callback
2766c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
2776c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws IllegalStateException if this method is called multiple times
2786c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws NullPointerException if the callback or handler is null
279b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro     */
2806c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    public void setCallbackOnComplete(
2816c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            @NonNull ContextHubTransaction.Callback<T> callback, @NonNull Handler handler) {
2826c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        synchronized (this) {
2836c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (callback == null) {
2846c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                throw new NullPointerException("Callback cannot be null");
2856c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
2866c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (handler == null) {
2876c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                throw new NullPointerException("Handler cannot be null");
2886c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
2896c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (mCallback != null) {
2906c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                throw new IllegalStateException(
2916c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                        "Cannot set ContextHubTransaction callback multiple times");
2926c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
2936c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
2946c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            mCallback = callback;
2956c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            mHandler = handler;
2966c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
2976c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (mDoneSignal.getCount() == 0) {
2986c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                boolean callbackPosted = mHandler.post(() -> {
2996c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                    mCallback.onComplete(this, mResponse);
3006c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                });
3016c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
3026c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                if (!callbackPosted) {
3036c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                    Log.e(TAG, "Failed to post callback to Handler");
3046c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                }
3056c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
3066c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        }
307b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
308b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro
3096c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    /**
3106c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * Sets a callback to be invoked when the transaction completes.
3116c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3126c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * Equivalent to {@link #setCallbackOnComplete(ContextHubTransaction.Callback, Handler)}
3136c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * with the handler being that of the main thread's Looper.
3146c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3156c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * This method or {@link #setCallbackOnComplete(ContextHubTransaction.Callback, Handler)}
3166c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * can only be invoked once, or an IllegalStateException will be thrown.
3176c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3186c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @param callback the callback to be invoked upon completion
3196c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3206c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws IllegalStateException if this method is called multiple times
3216c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws NullPointerException if the callback is null
3226c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     */
3236c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    public void setCallbackOnComplete(@NonNull ContextHubTransaction.Callback<T> callback) {
3246c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        setCallbackOnComplete(callback, new Handler(Looper.getMainLooper()));
3256c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    }
3266c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
3276c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    /**
3286c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * Sets the response of the transaction.
3296c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3306c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * This method should only be invoked by ContextHubManager as a result of a callback from
3316c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * the Context Hub Service indicating the response from a transaction. This method should not be
3326c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * invoked more than once.
3336c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3346c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @param response the response to set
3356c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     *
3366c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws IllegalStateException if this method is invoked multiple times
3376c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     * @throws NullPointerException if the response is null
3386c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro     */
3396c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro    void setResponse(ContextHubTransaction.Response<T> response) {
3406c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        synchronized (this) {
3416c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (response == null) {
3426c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                throw new NullPointerException("Response cannot be null");
3436c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
3446c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (mIsResponseSet) {
3456c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                throw new IllegalStateException(
3466c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                        "Cannot set response of ContextHubTransaction multiple times");
3476c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
3486c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
3496c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            mResponse = response;
3506c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            mIsResponseSet = true;
3516c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
3526c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            mDoneSignal.countDown();
3536c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            if (mCallback != null) {
3546c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                boolean callbackPosted = mHandler.post(() -> {
3556c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                    mCallback.onComplete(this, mResponse);
3566c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                });
3576c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro
3586c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                if (!callbackPosted) {
3596c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                    Log.e(TAG, "Failed to post callback to Handler");
3606c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro                }
3616c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro            }
3626c37fd0f538c4a6f40589ba1e91d95449f0b8195Arthur Ishiguro        }
363b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro    }
364b9ae7bd8389deeb4abbe034dc97f151c60c13044Arthur Ishiguro}
365