Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07ea4490 authored by Rebecca Silberstein's avatar Rebecca Silberstein Committed by Android (Google) Code Review
Browse files

Merge changes I8d149ab0,Ia0a52819,If54a89cb,I20faa733,Ib32dfd23 into oc-dev

* changes:
  WifiManager: expose Local Only Hotspot APIs
  WifiManager: implement watch LocalOnlyHotspot
  WifiManager: implement start/stopLocalOnlyHotspot
  WifiManager: add LocalOnlyHotspotObserverProxy
  WifiManager: add LocalOnlyHotspotCallbackProxy
parents f1a4b507 ec18f81e
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -26549,6 +26549,7 @@ package android.net.wifi {
    method public void setTdlsEnabled(java.net.InetAddress, boolean);
    method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
    method public boolean setWifiEnabled(boolean);
    method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
    method public boolean startScan();
    method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
    method public int updateNetwork(android.net.wifi.WifiConfiguration);
@@ -26599,6 +26600,21 @@ package android.net.wifi {
    field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
  }
  public static class WifiManager.LocalOnlyHotspotCallback {
    ctor public WifiManager.LocalOnlyHotspotCallback();
    method public void onFailed(int);
    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
    method public void onStopped();
    field public static final int ERROR_GENERIC = 2; // 0x2
    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
  }
  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
    method public void close();
    method public android.net.wifi.WifiConfiguration getConfig();
  }
  public class WifiManager.MulticastLock {
    method public void acquire();
    method public boolean isHeld();
+16 −0
Original line number Diff line number Diff line
@@ -29130,6 +29130,7 @@ package android.net.wifi {
    method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
    method public boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
    method public boolean setWifiEnabled(boolean);
    method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
    method public deprecated boolean startLocationRestrictedScan(android.os.WorkSource);
    method public boolean startScan();
    method public boolean startScan(android.os.WorkSource);
@@ -29207,6 +29208,21 @@ package android.net.wifi {
    method public abstract void onSuccess();
  }
  public static class WifiManager.LocalOnlyHotspotCallback {
    ctor public WifiManager.LocalOnlyHotspotCallback();
    method public void onFailed(int);
    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
    method public void onStopped();
    field public static final int ERROR_GENERIC = 2; // 0x2
    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
  }
  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
    method public void close();
    method public android.net.wifi.WifiConfiguration getConfig();
  }
  public class WifiManager.MulticastLock {
    method public void acquire();
    method public boolean isHeld();
+16 −0
Original line number Diff line number Diff line
@@ -26657,6 +26657,7 @@ package android.net.wifi {
    method public void setTdlsEnabled(java.net.InetAddress, boolean);
    method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
    method public boolean setWifiEnabled(boolean);
    method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
    method public boolean startScan();
    method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
    method public int updateNetwork(android.net.wifi.WifiConfiguration);
@@ -26707,6 +26708,21 @@ package android.net.wifi {
    field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
  }
  public static class WifiManager.LocalOnlyHotspotCallback {
    ctor public WifiManager.LocalOnlyHotspotCallback();
    method public void onFailed(int);
    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
    method public void onStopped();
    field public static final int ERROR_GENERIC = 2; // 0x2
    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
  }
  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
    method public void close();
    method public android.net.wifi.WifiConfiguration getConfig();
  }
  public class WifiManager.MulticastLock {
    method public void acquire();
    method public boolean isHeld();
+226 −13
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.WorkSource;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
@@ -47,6 +48,7 @@ import com.android.server.net.NetworkPinner;

import dalvik.system.CloseGuard;

import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.util.Collections;
import java.util.List;
@@ -851,6 +853,22 @@ public class WifiManager {
    private CountDownLatch mConnected;
    private Looper mLooper;

    /* LocalOnlyHotspot callback message types */
    /** @hide */
    public static final int HOTSPOT_STARTED = 0;
    /** @hide */
    public static final int HOTSPOT_STOPPED = 1;
    /** @hide */
    public static final int HOTSPOT_FAILED = 2;
    /** @hide */
    public static final int HOTSPOT_OBSERVER_REGISTERED = 3;

    private final Object mLock = new Object(); // lock guarding access to the following vars
    @GuardedBy("mLock")
    private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
    @GuardedBy("mLock")
    private LocalOnlyHotspotObserverProxy mLOHSObserverProxy;

    /**
     * Create a new WifiManager instance.
     * Applications will almost always want to use
@@ -1864,12 +1882,27 @@ public class WifiManager {
     * operating status.
     * @param handler Handler to be used for callbacks.  If the caller passes a null Handler, the
     * main thread will be used.
     *
     * @hide
     */
    public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
            @Nullable Handler handler) {
        throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
        synchronized (mLock) {
            Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
            LocalOnlyHotspotCallbackProxy proxy =
                    new LocalOnlyHotspotCallbackProxy(this, looper, callback);
            try {
                WifiConfiguration config = mService.startLocalOnlyHotspot(
                        proxy.getMessenger(), new Binder());
                if (config == null) {
                    // Send message to the proxy to make sure we call back on the correct thread
                    proxy.notifyFailed(
                            LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
                    return;
                }
                mLOHSCallbackProxy = proxy;
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -1886,7 +1919,9 @@ public class WifiManager {
     * @hide
     */
    public void cancelLocalOnlyHotspotRequest() {
        throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
        synchronized (mLock) {
            stopLocalOnlyHotspot();
        }
    }

    /**
@@ -1900,7 +1935,18 @@ public class WifiManager {
     *  method on their LocalOnlyHotspotReservation.
     */
    private void stopLocalOnlyHotspot() {
        throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
        synchronized (mLock) {
            if (mLOHSCallbackProxy == null) {
                // nothing to do, the callback was already cleaned up.
                return;
            }
            mLOHSCallbackProxy = null;
            try {
                mService.stopLocalOnlyHotspot();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -1922,7 +1968,18 @@ public class WifiManager {
     */
    public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
            @Nullable Handler handler) {
        throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
        synchronized (mLock) {
            Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
            mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer);
            try {
                mService.startWatchLocalOnlyHotspot(
                        mLOHSObserverProxy.getMessenger(), new Binder());
                mLOHSObserverProxy.registered();
            } catch (RemoteException e) {
                mLOHSObserverProxy = null;
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -1932,9 +1989,19 @@ public class WifiManager {
     * @hide
     */
    public void unregisterLocalOnlyHotspotObserver() {
        throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
        synchronized (mLock) {
            if (mLOHSObserverProxy == null) {
                // nothing to do, the callback was already cleaned up
                return;
            }
            mLOHSObserverProxy = null;
            try {
                mService.stopWatchLocalOnlyHotspot();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }


    /**
     * Gets the Wi-Fi enabled state.
@@ -2205,8 +2272,6 @@ public class WifiManager {
     * any further callbacks. If the LocalOnlyHotspot is stopped due to a
     * user triggered mode change, applications will be notified via the {@link
     * LocalOnlyHotspotCallback#onStopped()} callback.
     *
     * @hide
     */
    public class LocalOnlyHotspotReservation implements AutoCloseable {

@@ -2249,8 +2314,6 @@ public class WifiManager {

    /**
     * Callback class for applications to receive updates about the LocalOnlyHotspot status.
     *
     * @hide
     */
    public static class LocalOnlyHotspotCallback {
        public static final int ERROR_NO_CHANNEL = 1;
@@ -2282,6 +2345,88 @@ public class WifiManager {
        public void onFailed(int reason) { };
    }

    /**
     * Callback proxy for LocalOnlyHotspotCallback objects.
     */
    private static class LocalOnlyHotspotCallbackProxy {
        private final Handler mHandler;
        private final WeakReference<WifiManager> mWifiManager;
        private final Looper mLooper;
        private final Messenger mMessenger;

        /**
         * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper.  All callbacks
         * will be delivered on the thread of the specified looper.
         *
         * @param manager WifiManager
         * @param looper Looper for delivering callbacks
         * @param callback LocalOnlyHotspotCallback to notify the calling application.
         */
        LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper,
                final LocalOnlyHotspotCallback callback) {
            mWifiManager = new WeakReference<>(manager);
            mLooper = looper;

            mHandler = new Handler(looper) {
                @Override
                public void handleMessage(Message msg) {
                    Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: "
                            + msg.what + " msg: " + msg);

                    WifiManager manager = mWifiManager.get();
                    if (manager == null) {
                        Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC");
                        return;
                    }

                    switch (msg.what) {
                        case HOTSPOT_STARTED:
                            WifiConfiguration config = (WifiConfiguration) msg.obj;
                            if (config == null) {
                                Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
                                callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
                                return;
                            }
                            callback.onStarted(manager.new LocalOnlyHotspotReservation(config));
                            break;
                        case HOTSPOT_STOPPED:
                            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
                            callback.onStopped();
                            break;
                        case HOTSPOT_FAILED:
                            int reasonCode = msg.arg1;
                            Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start.  reason: "
                                    + reasonCode);
                            callback.onFailed(reasonCode);
                            Log.w(TAG, "done with the callback...");
                            break;
                        default:
                            Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message.  type: "
                                    + msg.what);
                    }
                }
            };
            mMessenger = new Messenger(mHandler);
        }

        public Messenger getMessenger() {
            return mMessenger;
        }

        /**
         * Helper method allowing the the incoming application call to move the onFailed callback
         * over to the desired callback thread.
         *
         * @param reason int representing the error type
         */
        public void notifyFailed(int reason) throws RemoteException {
            Message msg = Message.obtain();
            msg.what = HOTSPOT_FAILED;
            msg.arg1 = reason;
            mMessenger.send(msg);
        }
    }

    /**
     * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
     * watching for LocalOnlyHotspot changes.
@@ -2291,7 +2436,6 @@ public class WifiManager {
    public class LocalOnlyHotspotSubscription implements AutoCloseable {
        private final CloseGuard mCloseGuard = CloseGuard.get();

        /** @hide */
        @VisibleForTesting
        public LocalOnlyHotspotSubscription() {
            mCloseGuard.open("close");
@@ -2343,6 +2487,75 @@ public class WifiManager {
        public void onStopped() {};
    }

    /**
     * Callback proxy for LocalOnlyHotspotObserver objects.
     */
    private static class LocalOnlyHotspotObserverProxy {
        private final Handler mHandler;
        private final WeakReference<WifiManager> mWifiManager;
        private final Looper mLooper;
        private final Messenger mMessenger;

        /**
         * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
         * All callbacks will be delivered on the thread of the specified looper.
         *
         * @param manager WifiManager
         * @param looper Looper for delivering callbacks
         * @param observer LocalOnlyHotspotObserver to notify the calling application.
         */
        LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper,
                final LocalOnlyHotspotObserver observer) {
            mWifiManager = new WeakReference<>(manager);
            mLooper = looper;

            mHandler = new Handler(looper) {
                @Override
                public void handleMessage(Message msg) {
                    Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: "
                            + msg.what + " msg: " + msg);

                    WifiManager manager = mWifiManager.get();
                    if (manager == null) {
                        Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC");
                        return;
                    }

                    switch (msg.what) {
                        case HOTSPOT_OBSERVER_REGISTERED:
                            observer.onRegistered(manager.new LocalOnlyHotspotSubscription());
                            break;
                        case HOTSPOT_STARTED:
                            WifiConfiguration config = (WifiConfiguration) msg.obj;
                            if (config == null) {
                                Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
                                return;
                            }
                            observer.onStarted(config);
                            break;
                        case HOTSPOT_STOPPED:
                            observer.onStopped();
                            break;
                        default:
                            Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message.  type: "
                                    + msg.what);
                    }
                }
            };
            mMessenger = new Messenger(mHandler);
        }

        public Messenger getMessenger() {
            return mMessenger;
        }

        public void registered() throws RemoteException {
            Message msg = Message.obtain();
            msg.what = HOTSPOT_OBSERVER_REGISTERED;
            mMessenger.send(msg);
        }
    }

    // Ensure that multiple ServiceHandler threads do not interleave message dispatch.
    private static final Object sServiceHandlerDispatchLock = new Object();

+761 −0

File added.

Preview size limit exceeded, changes collapsed.