WifiAwareNativeManager.java revision 448a7b6b7b16cf39ed25729ceaf61edb30368567
164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen/*
264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Copyright (C) 2016 The Android Open Source Project
364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen *
464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * you may not use this file except in compliance with the License.
664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * You may obtain a copy of the License at
764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen *
864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen *
1064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Unless required by applicable law or agreed to in writing, software
1164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
1264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * See the License for the specific language governing permissions and
1464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * limitations under the License.
1564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen */
1664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
1764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenpackage com.android.server.wifi.aware;
1864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
1964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.hardware.wifi.V1_0.IWifiNanIface;
20448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohenimport android.hardware.wifi.V1_0.IfaceType;
2164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.util.Log;
2264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
2364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport com.android.server.wifi.HalDeviceManager;
2464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
2564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen/**
2664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Manages the interface to Wi-Fi Aware HIDL (HAL).
2764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen */
2864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenclass WifiAwareNativeManager {
2964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private static final String TAG = "WifiAwareNativeManager";
3064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private static final boolean DBG = false;
3164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
3264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    // to be used for synchronizing access to any of the WifiAwareNative objects
3364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private final Object mLock = new Object();
3464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
3564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private WifiAwareStateManager mWifiAwareStateManager;
3664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private HalDeviceManager mHalDeviceManager;
3764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private IWifiNanIface mWifiNanIface = null;
3864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private InterfaceDestroyedListener mInterfaceDestroyedListener =
3964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            new InterfaceDestroyedListener();
4064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private InterfaceAvailableForRequestListener mInterfaceAvailableForRequestListener =
4164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            new InterfaceAvailableForRequestListener();
4264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
4364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    WifiAwareNativeManager(WifiAwareStateManager awareStateManager,
4464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            HalDeviceManager halDeviceManager) {
4564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        mWifiAwareStateManager = awareStateManager;
4664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        mHalDeviceManager = halDeviceManager;
473145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen        mHalDeviceManager.registerStatusListener(
483145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                new HalDeviceManager.ManagerStatusListener() {
4964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                    @Override
503145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                    public void onStatusChanged() {
513145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        if (DBG) Log.d(TAG, "onStatusChanged");
523145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        // only care about isStarted (Wi-Fi started) not isReady - since if not
533145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        // ready then Wi-Fi will also be down.
543145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        if (mHalDeviceManager.isStarted()) {
55448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen                            // 1. no problem registering duplicates - only one will be called
56448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen                            // 2. will be called immediately if available
57448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen                            mHalDeviceManager.registerInterfaceAvailableForRequestListener(
58448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen                                    IfaceType.NAN, mInterfaceAvailableForRequestListener, null);
593145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        } else {
603145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                            awareIsDown();
613145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                        }
6264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                    }
6364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                }, null);
643145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen        if (mHalDeviceManager.isStarted()) {
653145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen            tryToGetAware();
663145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen        }
6764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
6864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
6964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    /* package */ IWifiNanIface getWifiNanIface() {
7064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        synchronized (mLock) {
7164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            return mWifiNanIface;
7264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        }
7364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
7464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
7564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private void tryToGetAware() {
7664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        synchronized (mLock) {
77448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen            if (DBG) Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface);
78448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen
793145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen            if (mWifiNanIface != null) {
803145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen                return;
813145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen            }
82448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen            IWifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener,
83448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen                    null);
8464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            if (iface == null) {
8564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                if (DBG) Log.d(TAG, "Was not able to obtain an IWifiNanIface");
8664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            } else {
8764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                if (DBG) Log.d(TAG, "Obtained an IWifiNanIface");
8864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
8964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                mWifiNanIface = iface;
9064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                mWifiAwareStateManager.enableUsage();
9164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            }
9264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        }
9364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
9464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
9564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private void awareIsDown() {
96448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen        synchronized (mLock) {
97448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen            if (DBG) Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface);
98448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen            if (mWifiNanIface != null) {
9964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                mWifiNanIface = null;
10064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen                mWifiAwareStateManager.disableUsage();
10164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            }
10264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        }
10364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
10464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
10564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private class InterfaceDestroyedListener implements
10664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            HalDeviceManager.InterfaceDestroyedListener {
10764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        @Override
10864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        public void onDestroyed() {
10964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            if (DBG) Log.d(TAG, "Interface was destroyed");
11064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            awareIsDown();
11164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        }
11264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
11364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen
11464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    private class InterfaceAvailableForRequestListener implements
11564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            HalDeviceManager.InterfaceAvailableForRequestListener {
11664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        @Override
11764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        public void onAvailableForRequest() {
11864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            if (DBG) Log.d(TAG, "Interface is possibly available");
11964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen            tryToGetAware();
12064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen        }
12164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen    }
12264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen}
123