11d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi/*
21d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Copyright (C) 2016 The Android Open Source Project
31d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *
41d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Licensed under the Apache License, Version 2.0 (the "License");
51d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * you may not use this file except in compliance with the License.
61d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * You may obtain a copy of the License at
71d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *
81d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *      http://www.apache.org/licenses/LICENSE-2.0
91d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *
101d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Unless required by applicable law or agreed to in writing, software
111d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * distributed under the License is distributed on an "AS IS" BASIS,
121d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * See the License for the specific language governing permissions and
141d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * limitations under the License.
151d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi */
161d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshipackage android.hardware.location;
171d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
181d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.annotation.SystemApi;
191d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.content.Context;
209ff7d2235427b211344fa58b608424805a21aa24Peng Xuimport android.os.Handler;
211d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.os.IBinder;
229ff7d2235427b211344fa58b608424805a21aa24Peng Xuimport android.os.Looper;
231d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.os.RemoteException;
249ff7d2235427b211344fa58b608424805a21aa24Peng Xuimport android.os.ServiceManager;
251d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.util.Log;
261d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
271d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi/**
288bad3fec0f54959958352c0bef90b813cd0d823adestradaa * A class that exposes the Context hubs on a device to applications.
291d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *
308bad3fec0f54959958352c0bef90b813cd0d823adestradaa * Please note that this class is not expected to be used by unbundled applications. Also, calling
318bad3fec0f54959958352c0bef90b813cd0d823adestradaa * applications are expected to have LOCATION_HARDWARE permissions to use this class.
321d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi *
331d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * @hide
341d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi */
351d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi@SystemApi
361d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshipublic final class ContextHubManager {
371d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
381d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    private static final String TAG = "ContextHubManager";
391d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
409ff7d2235427b211344fa58b608424805a21aa24Peng Xu    private final Looper mMainLooper;
411d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    private IContextHubService mContextHubService;
426ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser    private Callback mCallback;
439ff7d2235427b211344fa58b608424805a21aa24Peng Xu    private Handler mCallbackHandler;
441d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
451d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
4678cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @deprecated Use {@code mCallback} instead.
4778cebca7204f85ebb7c583bab2fc9891367cd403destradaa     */
4878cebca7204f85ebb7c583bab2fc9891367cd403destradaa    @Deprecated
4978cebca7204f85ebb7c583bab2fc9891367cd403destradaa    private ICallback mLocalCallback;
5078cebca7204f85ebb7c583bab2fc9891367cd403destradaa
5178cebca7204f85ebb7c583bab2fc9891367cd403destradaa    /**
528bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * An interface to receive asynchronous communication from the context hub.
539ff7d2235427b211344fa58b608424805a21aa24Peng Xu     */
546ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser    public abstract static class Callback {
556ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser        protected Callback() {}
568bad3fec0f54959958352c0bef90b813cd0d823adestradaa
579ff7d2235427b211344fa58b608424805a21aa24Peng Xu        /**
588bad3fec0f54959958352c0bef90b813cd0d823adestradaa         * Callback function called on message receipt from context hub.
599ff7d2235427b211344fa58b608424805a21aa24Peng Xu         *
608bad3fec0f54959958352c0bef90b813cd0d823adestradaa         * @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
61b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi         * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
628bad3fec0f54959958352c0bef90b813cd0d823adestradaa         * @param message The context hub message.
639ff7d2235427b211344fa58b608424805a21aa24Peng Xu         *
649ff7d2235427b211344fa58b608424805a21aa24Peng Xu         * @see ContextHubMessage
659ff7d2235427b211344fa58b608424805a21aa24Peng Xu         */
668bad3fec0f54959958352c0bef90b813cd0d823adestradaa        public abstract void onMessageReceipt(
678bad3fec0f54959958352c0bef90b813cd0d823adestradaa                int hubHandle,
688bad3fec0f54959958352c0bef90b813cd0d823adestradaa                int nanoAppHandle,
698bad3fec0f54959958352c0bef90b813cd0d823adestradaa                ContextHubMessage message);
709ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
711d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
721d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
7378cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @deprecated Use {@link Callback} instead.
7478cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @hide
7578cebca7204f85ebb7c583bab2fc9891367cd403destradaa     */
7678cebca7204f85ebb7c583bab2fc9891367cd403destradaa    @Deprecated
7778cebca7204f85ebb7c583bab2fc9891367cd403destradaa    public interface ICallback {
7878cebca7204f85ebb7c583bab2fc9891367cd403destradaa        /**
7978cebca7204f85ebb7c583bab2fc9891367cd403destradaa         * Callback function called on message receipt from context hub.
8078cebca7204f85ebb7c583bab2fc9891367cd403destradaa         *
8178cebca7204f85ebb7c583bab2fc9891367cd403destradaa         * @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
8278cebca7204f85ebb7c583bab2fc9891367cd403destradaa         * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
8378cebca7204f85ebb7c583bab2fc9891367cd403destradaa         * @param message The context hub message.
8478cebca7204f85ebb7c583bab2fc9891367cd403destradaa         *
8578cebca7204f85ebb7c583bab2fc9891367cd403destradaa         * @see ContextHubMessage
8678cebca7204f85ebb7c583bab2fc9891367cd403destradaa         */
8778cebca7204f85ebb7c583bab2fc9891367cd403destradaa        void onMessageReceipt(int hubHandle, int nanoAppHandle, ContextHubMessage message);
8878cebca7204f85ebb7c583bab2fc9891367cd403destradaa    }
8978cebca7204f85ebb7c583bab2fc9891367cd403destradaa
9078cebca7204f85ebb7c583bab2fc9891367cd403destradaa    /**
911d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * Get a handle to all the context hubs in the system
921d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @return array of context hub handles
931d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
949ff7d2235427b211344fa58b608424805a21aa24Peng Xu    public int[] getContextHubHandles() {
951d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        int[] retVal = null;
969ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
979ff7d2235427b211344fa58b608424805a21aa24Peng Xu            retVal = getBinder().getContextHubHandles();
989ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
99b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not fetch context hub handles : " + e);
1001d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
1011d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
1021d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
1031d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1041d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
1051d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * Get more information about a specific hub.
1061d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1078bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @param hubHandle Handle (system-wide unique identifier) of a context hub.
1088bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @return ContextHubInfo Information about the requested context hub.
1091d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1101d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @see ContextHubInfo
1111d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
1128bad3fec0f54959958352c0bef90b813cd0d823adestradaa    public ContextHubInfo getContextHubInfo(int hubHandle) {
1131d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        ContextHubInfo retVal = null;
1149ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
1158bad3fec0f54959958352c0bef90b813cd0d823adestradaa            retVal = getBinder().getContextHubInfo(hubHandle);
1169ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
117b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not fetch context hub info :" + e);
1181d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
1191d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1209ff7d2235427b211344fa58b608424805a21aa24Peng Xu        return retVal;
1211d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
1221d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1231d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
1248bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * Load a nano app on a specified context hub.
1251d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1261d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param hubHandle handle of context hub to load the app on.
1271d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param app the nanoApp to load on the hub
1281d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1291d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @return int nanoAppInstance of the loaded nanoApp on success,
1301d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *         -1 otherwise
1311d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1321d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @see NanoApp
1331d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
1341d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    public int loadNanoApp(int hubHandle, NanoApp app) {
1351d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        int retVal = -1;
136b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi
1379ff7d2235427b211344fa58b608424805a21aa24Peng Xu        if (app == null) {
1389ff7d2235427b211344fa58b608424805a21aa24Peng Xu            return retVal;
1399ff7d2235427b211344fa58b608424805a21aa24Peng Xu        }
1401d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1419ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
1429ff7d2235427b211344fa58b608424805a21aa24Peng Xu            retVal = getBinder().loadNanoApp(hubHandle, app);
1439ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
144b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not load nanoApp :" + e);
1451d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
1461d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1471d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
1481d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
1491d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1501d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
1511d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * Unload a specified nanoApp
1521d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1538bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @param nanoAppHandle handle of the nanoApp to load
1541d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1558bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @return int  0 on success, -1 otherwise
1561d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
1578bad3fec0f54959958352c0bef90b813cd0d823adestradaa    public int unloadNanoApp(int nanoAppHandle) {
1581d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        int retVal = -1;
1591d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1609ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
1618bad3fec0f54959958352c0bef90b813cd0d823adestradaa            retVal = getBinder().unloadNanoApp(nanoAppHandle);
1629ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
163b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not fetch unload nanoApp :" + e);
1641d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
1651d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1661d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
1671d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
1681d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1691d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
1701d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * get information about the nano app instance
1711d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1728bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @param nanoAppHandle handle of the nanoAppInstance
1738bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @return NanoAppInstanceInfo Information about the nano app instance.
1741d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1751d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @see NanoAppInstanceInfo
1761d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
1778bad3fec0f54959958352c0bef90b813cd0d823adestradaa    public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) {
1781d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        NanoAppInstanceInfo retVal = null;
1791d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1809ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
1818bad3fec0f54959958352c0bef90b813cd0d823adestradaa            retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
1829ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
183b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not fetch nanoApp info :" + e);
1841d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
1851d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1861d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
1871d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
1881d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
1891d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
1901d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * Find a specified nano app on the system
1911d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1921d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param hubHandle handle of hub to search for nano app
1931d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param filter filter specifying the search criteria for app
1941d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1951d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @see NanoAppFilter
1961d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
1978bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @return int[] Array of handles to any found nano apps
1981d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
1998bad3fec0f54959958352c0bef90b813cd0d823adestradaa    public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) {
2008bad3fec0f54959958352c0bef90b813cd0d823adestradaa        int[] retVal = null;
2019ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
2028bad3fec0f54959958352c0bef90b813cd0d823adestradaa            retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
2039ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
204b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not query nanoApp instance :" + e);
2051d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
2061d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
2071d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
2081d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
2091d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    /**
2108bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * Send a message to a specific nano app instance on a context hub.
2111d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
2121d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param hubHandle handle of the hub to send the message to
2131d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @param nanoAppHandle  handle of the nano app to send to
2148bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @param message Message to be sent
2151d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
2161d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @see ContextHubMessage
2171d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     *
2181d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     * @return int 0 on success, -1 otherwise
2191d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi     */
2209ff7d2235427b211344fa58b608424805a21aa24Peng Xu    public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
2211d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        int retVal = -1;
2221d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
223b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi        if (message == null || message.getData() == null) {
224b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "null ptr");
225b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            return retVal;
226b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi        }
2279ff7d2235427b211344fa58b608424805a21aa24Peng Xu        try {
2289ff7d2235427b211344fa58b608424805a21aa24Peng Xu            retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
2299ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } catch (RemoteException e) {
230b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "Could not send message :" + e.toString());
2311d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
2321d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
2331d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        return retVal;
2341d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    }
2351d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
2369ff7d2235427b211344fa58b608424805a21aa24Peng Xu    /**
2379ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * Set a callback to receive messages from the context hub
2389ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2399ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @param callback Callback object
2409ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2416ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser     * @see Callback
2429ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2439ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @return int 0 on success, -1 otherwise
2449ff7d2235427b211344fa58b608424805a21aa24Peng Xu     */
2456ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser    public int registerCallback(Callback callback) {
2466ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser        return registerCallback(callback, null);
2479ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
2489ff7d2235427b211344fa58b608424805a21aa24Peng Xu
2499ff7d2235427b211344fa58b608424805a21aa24Peng Xu    /**
25078cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @deprecated Use {@link #registerCallback(Callback)} instead.
25178cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @hide
25278cebca7204f85ebb7c583bab2fc9891367cd403destradaa     */
25378cebca7204f85ebb7c583bab2fc9891367cd403destradaa    @Deprecated
25478cebca7204f85ebb7c583bab2fc9891367cd403destradaa    public int registerCallback(ICallback callback) {
25578cebca7204f85ebb7c583bab2fc9891367cd403destradaa        if (mLocalCallback != null) {
25678cebca7204f85ebb7c583bab2fc9891367cd403destradaa            Log.w(TAG, "Max number of local callbacks reached!");
25778cebca7204f85ebb7c583bab2fc9891367cd403destradaa            return -1;
25878cebca7204f85ebb7c583bab2fc9891367cd403destradaa        }
25978cebca7204f85ebb7c583bab2fc9891367cd403destradaa        mLocalCallback = callback;
26078cebca7204f85ebb7c583bab2fc9891367cd403destradaa        return 0;
26178cebca7204f85ebb7c583bab2fc9891367cd403destradaa    }
26278cebca7204f85ebb7c583bab2fc9891367cd403destradaa
26378cebca7204f85ebb7c583bab2fc9891367cd403destradaa    /**
2649ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * Set a callback to receive messages from the context hub
2659ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2669ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @param callback Callback object
2678bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * @param handler Handler object
2689ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2696ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser     * @see Callback
2709ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2719ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @return int 0 on success, -1 otherwise
2729ff7d2235427b211344fa58b608424805a21aa24Peng Xu     */
2736ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser    public int registerCallback(Callback callback, Handler handler) {
2749ff7d2235427b211344fa58b608424805a21aa24Peng Xu        synchronized(this) {
2759ff7d2235427b211344fa58b608424805a21aa24Peng Xu            if (mCallback != null) {
276b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi                Log.w(TAG, "Max number of callbacks reached!");
2779ff7d2235427b211344fa58b608424805a21aa24Peng Xu                return -1;
2789ff7d2235427b211344fa58b608424805a21aa24Peng Xu            }
2799ff7d2235427b211344fa58b608424805a21aa24Peng Xu            mCallback = callback;
2809ff7d2235427b211344fa58b608424805a21aa24Peng Xu            mCallbackHandler = handler;
2819ff7d2235427b211344fa58b608424805a21aa24Peng Xu        }
2829ff7d2235427b211344fa58b608424805a21aa24Peng Xu        return 0;
2839ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
2849ff7d2235427b211344fa58b608424805a21aa24Peng Xu
2859ff7d2235427b211344fa58b608424805a21aa24Peng Xu    /**
2868bad3fec0f54959958352c0bef90b813cd0d823adestradaa     * Unregister a callback for receive messages from the context hub.
2879ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2886ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser     * @see Callback
2899ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2909ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @param callback method to deregister
2919ff7d2235427b211344fa58b608424805a21aa24Peng Xu     *
2929ff7d2235427b211344fa58b608424805a21aa24Peng Xu     * @return int 0 on success, -1 otherwise
2939ff7d2235427b211344fa58b608424805a21aa24Peng Xu     */
2946ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser    public int unregisterCallback(Callback callback) {
2959ff7d2235427b211344fa58b608424805a21aa24Peng Xu      synchronized(this) {
2969ff7d2235427b211344fa58b608424805a21aa24Peng Xu          if (callback != mCallback) {
297b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi              Log.w(TAG, "Cannot recognize callback!");
2989ff7d2235427b211344fa58b608424805a21aa24Peng Xu              return -1;
2999ff7d2235427b211344fa58b608424805a21aa24Peng Xu          }
3009ff7d2235427b211344fa58b608424805a21aa24Peng Xu
3019ff7d2235427b211344fa58b608424805a21aa24Peng Xu          mCallback = null;
3029ff7d2235427b211344fa58b608424805a21aa24Peng Xu          mCallbackHandler = null;
3039ff7d2235427b211344fa58b608424805a21aa24Peng Xu      }
3049ff7d2235427b211344fa58b608424805a21aa24Peng Xu      return 0;
3059ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
3069ff7d2235427b211344fa58b608424805a21aa24Peng Xu
30778cebca7204f85ebb7c583bab2fc9891367cd403destradaa    /**
30878cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @deprecated Use {@link #unregisterCallback(Callback)} instead.
30978cebca7204f85ebb7c583bab2fc9891367cd403destradaa     * @hide
31078cebca7204f85ebb7c583bab2fc9891367cd403destradaa     */
31178cebca7204f85ebb7c583bab2fc9891367cd403destradaa    public synchronized int unregisterCallback(ICallback callback) {
31278cebca7204f85ebb7c583bab2fc9891367cd403destradaa        if (callback != mLocalCallback) {
31378cebca7204f85ebb7c583bab2fc9891367cd403destradaa            Log.w(TAG, "Cannot recognize local callback!");
31478cebca7204f85ebb7c583bab2fc9891367cd403destradaa            return -1;
31578cebca7204f85ebb7c583bab2fc9891367cd403destradaa        }
31678cebca7204f85ebb7c583bab2fc9891367cd403destradaa        mLocalCallback = null;
31778cebca7204f85ebb7c583bab2fc9891367cd403destradaa        return 0;
31878cebca7204f85ebb7c583bab2fc9891367cd403destradaa    }
31978cebca7204f85ebb7c583bab2fc9891367cd403destradaa
3201d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
3211d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        @Override
3229ff7d2235427b211344fa58b608424805a21aa24Peng Xu        public void onMessageReceipt(final int hubId, final int nanoAppId,
3238bad3fec0f54959958352c0bef90b813cd0d823adestradaa                final ContextHubMessage message) {
3249ff7d2235427b211344fa58b608424805a21aa24Peng Xu            if (mCallback != null) {
3259ff7d2235427b211344fa58b608424805a21aa24Peng Xu                synchronized(this) {
3266ba60e60491c79896bc97c5712cedac32b6a67eaGreg Kaiser                    final Callback callback = mCallback;
3279ff7d2235427b211344fa58b608424805a21aa24Peng Xu                    Handler handler = mCallbackHandler == null ?
3289ff7d2235427b211344fa58b608424805a21aa24Peng Xu                            new Handler(mMainLooper) : mCallbackHandler;
3299ff7d2235427b211344fa58b608424805a21aa24Peng Xu                    handler.post(new Runnable() {
3309ff7d2235427b211344fa58b608424805a21aa24Peng Xu                        @Override
3319ff7d2235427b211344fa58b608424805a21aa24Peng Xu                        public void run() {
3329ff7d2235427b211344fa58b608424805a21aa24Peng Xu                            callback.onMessageReceipt(hubId, nanoAppId, message);
3339ff7d2235427b211344fa58b608424805a21aa24Peng Xu                        }
3349ff7d2235427b211344fa58b608424805a21aa24Peng Xu                    });
3359ff7d2235427b211344fa58b608424805a21aa24Peng Xu                }
33678cebca7204f85ebb7c583bab2fc9891367cd403destradaa            } else if (mLocalCallback != null) {
33778cebca7204f85ebb7c583bab2fc9891367cd403destradaa                // we always ensure that mCallback takes precedence, because mLocalCallback is only
33878cebca7204f85ebb7c583bab2fc9891367cd403destradaa                // for internal compatibility
33978cebca7204f85ebb7c583bab2fc9891367cd403destradaa                synchronized (this) {
34078cebca7204f85ebb7c583bab2fc9891367cd403destradaa                    mLocalCallback.onMessageReceipt(hubId, nanoAppId, message);
34178cebca7204f85ebb7c583bab2fc9891367cd403destradaa                }
3429ff7d2235427b211344fa58b608424805a21aa24Peng Xu            } else {
3439ff7d2235427b211344fa58b608424805a21aa24Peng Xu                Log.d(TAG, "Context hub manager client callback is NULL");
3449ff7d2235427b211344fa58b608424805a21aa24Peng Xu            }
3451d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
3461d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi    };
3471d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
3489ff7d2235427b211344fa58b608424805a21aa24Peng Xu    /** @hide */
3499ff7d2235427b211344fa58b608424805a21aa24Peng Xu    public ContextHubManager(Context context, Looper mainLooper) {
3509ff7d2235427b211344fa58b608424805a21aa24Peng Xu        mMainLooper = mainLooper;
3511d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
3529ff7d2235427b211344fa58b608424805a21aa24Peng Xu        IBinder b = ServiceManager.getService(ContextHubService.CONTEXTHUB_SERVICE);
3539ff7d2235427b211344fa58b608424805a21aa24Peng Xu        if (b != null) {
3549ff7d2235427b211344fa58b608424805a21aa24Peng Xu            mContextHubService = IContextHubService.Stub.asInterface(b);
3551d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
3561d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi            try {
3579ff7d2235427b211344fa58b608424805a21aa24Peng Xu                getBinder().registerCallback(mClientCallback);
3581d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi            } catch (RemoteException e) {
359b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi                Log.w(TAG, "Could not register callback:" + e);
3601d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi            }
3611d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
3629ff7d2235427b211344fa58b608424805a21aa24Peng Xu        } else {
363b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi            Log.w(TAG, "failed to getService");
3641d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi        }
3659ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
3661d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi
3679ff7d2235427b211344fa58b608424805a21aa24Peng Xu    private IContextHubService getBinder() throws RemoteException {
3689ff7d2235427b211344fa58b608424805a21aa24Peng Xu        if (mContextHubService == null) {
3699ff7d2235427b211344fa58b608424805a21aa24Peng Xu            throw new RemoteException("Service not connected.");
3709ff7d2235427b211344fa58b608424805a21aa24Peng Xu        }
3719ff7d2235427b211344fa58b608424805a21aa24Peng Xu        return mContextHubService;
3729ff7d2235427b211344fa58b608424805a21aa24Peng Xu    }
3731d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi}
374