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

Commit 1bfc472f authored by Wei Wang's avatar Wei Wang Committed by android-build-merger
Browse files

Merge "Use ConnectivityThread for RttManager." into nyc-dev

am: f49b51e0

* commit 'f49b51e0':
  Use ConnectivityThread for RttManager.

Change-Id: Icd3e0adf47fabb86f812b1875aca49379f65ca59
parents 30931560 f49b51e0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -542,7 +542,8 @@ final class SystemServiceRegistry {
            public RttManager createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(Context.WIFI_RTT_SERVICE);
                IRttManager service = IRttManager.Stub.asInterface(b);
                return new RttManager(ctx.getOuterContext(), service);
                return new RttManager(ctx.getOuterContext(), service,
                        ConnectivityThread.getInstanceLooper());
            }});

        registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
+58 −93
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -19,8 +18,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;

import java.util.concurrent.CountDownLatch;

/** @hide */
@SystemApi
public class RttManager {
@@ -311,7 +308,7 @@ public class RttManager {
    }

    public RttCapabilities getRttCapabilities() {
        synchronized (sCapabilitiesLock) {
        synchronized (mCapabilitiesLock) {
            if (mRttCapabilities == null) {
                try {
                    mRttCapabilities = mService.getRttCapabilities();
@@ -932,13 +929,13 @@ public class RttManager {
        validateChannel();
        ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
        Log.i(TAG, "Send RTT request to RTT Service");
        sAsyncChannel.sendMessage(CMD_OP_START_RANGING,
        mAsyncChannel.sendMessage(CMD_OP_START_RANGING,
                0, putListener(listener), parcelableParams);
    }

    public void stopRanging(RttListener listener) {
        validateChannel();
        sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
        mAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
    }

    /**
@@ -975,7 +972,7 @@ public class RttManager {
        }
        validateChannel();
        int key = putListenerIfAbsent(callback);
        sAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
        mAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
    }

    /**
@@ -998,7 +995,7 @@ public class RttManager {
            Log.e(TAG, "responder not enabled yet");
            return;
        }
        sAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
        mAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
    }

    /**
@@ -1110,23 +1107,17 @@ public class RttManager {
    public static final int
            CMD_OP_ENALBE_RESPONDER_FAILED              = BASE + 8;

    private Context mContext;
    private IRttManager mService;
    private RttCapabilities mRttCapabilities;

    private static final int INVALID_KEY = 0;
    private static int sListenerKey = 1;

    private static final SparseArray sListenerMap = new SparseArray();
    private static final Object sListenerMapLock = new Object();
    private static final Object sCapabilitiesLock = new Object();
    private final Context mContext;
    private final IRttManager mService;
    private final SparseArray mListenerMap = new SparseArray();
    private final Object mListenerMapLock = new Object();
    private final Object mCapabilitiesLock = new Object();

    private static AsyncChannel sAsyncChannel;
    private static CountDownLatch sConnected;

    private static final Object sThreadRefLock = new Object();
    private static int sThreadRefCount;
    private static HandlerThread sHandlerThread;
    private RttCapabilities mRttCapabilities;
    private int mListenerKey = 1;
    private AsyncChannel mAsyncChannel;

    /**
     * Create a new WifiScanner instance.
@@ -1135,122 +1126,107 @@ public class RttManager {
     * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
     * @param context the application context
     * @param service the Binder interface
     * @param looper Looper for running the callbacks.
     *
     * @hide
     */

    public RttManager(Context context, IRttManager service) {
    public RttManager(Context context, IRttManager service, Looper looper) {
        mContext = context;
        mService = service;
        init();
    }

    private void init() {
        synchronized (sThreadRefLock) {
            if (++sThreadRefCount == 1) {
        Messenger messenger = null;
        try {
            Log.d(TAG, "Get the messenger from " + mService);
            messenger = mService.getMessenger();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
                } catch (SecurityException e) {
                    /* do nothing */
        }

        if (messenger == null) {
                    sAsyncChannel = null;
                    return;
            throw new IllegalStateException("getMessenger() returned null!  This is invalid.");
        }

                sHandlerThread = new HandlerThread("RttManager");
                sAsyncChannel = new AsyncChannel();
                sConnected = new CountDownLatch(1);
        mAsyncChannel = new AsyncChannel();

                sHandlerThread.start();
                Handler handler = new ServiceHandler(sHandlerThread.getLooper());
                sAsyncChannel.connect(mContext, handler, messenger);
                try {
                    sConnected.await();
                } catch (InterruptedException e) {
                    Log.e(TAG, "interrupted wait at init");
                }
            }
        }
        Handler handler = new ServiceHandler(looper);
        mAsyncChannel.connectSync(mContext, handler, messenger);
        // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
        // synchronously, which causes RttService to receive the wrong replyTo value.
        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
    }

    private void validateChannel() {
        if (sAsyncChannel == null) throw new IllegalStateException(
        if (mAsyncChannel == null) throw new IllegalStateException(
                "No permission to access and change wifi or a bad initialization");
    }

    private static int putListener(Object listener) {
    private int putListener(Object listener) {
        if (listener == null) return INVALID_KEY;
        int key;
        synchronized (sListenerMapLock) {
        synchronized (mListenerMapLock) {
            do {
                key = sListenerKey++;
                key = mListenerKey++;
            } while (key == INVALID_KEY);
            sListenerMap.put(key, listener);
            mListenerMap.put(key, listener);
        }
        return key;
    }

    // Insert a listener if it doesn't exist in sListenerMap. Returns the key of the listener.
    private static int putListenerIfAbsent(Object listener) {
    // Insert a listener if it doesn't exist in mListenerMap. Returns the key of the listener.
    private int putListenerIfAbsent(Object listener) {
        if (listener == null) return INVALID_KEY;
        synchronized (sListenerMapLock) {
        synchronized (mListenerMapLock) {
            int key = getListenerKey(listener);
            if (key != INVALID_KEY) {
                return key;
            }
            do {
                key = sListenerKey++;
                key = mListenerKey++;
            } while (key == INVALID_KEY);
            sListenerMap.put(key, listener);
            mListenerMap.put(key, listener);
            return key;
        }

    }

    private static Object getListener(int key) {
    private Object getListener(int key) {
        if (key == INVALID_KEY) return null;
        synchronized (sListenerMapLock) {
            Object listener = sListenerMap.get(key);
        synchronized (mListenerMapLock) {
            Object listener = mListenerMap.get(key);
            return listener;
        }
    }

    private static int getListenerKey(Object listener) {
    private int getListenerKey(Object listener) {
        if (listener == null) return INVALID_KEY;
        synchronized (sListenerMapLock) {
            int index = sListenerMap.indexOfValue(listener);
        synchronized (mListenerMapLock) {
            int index = mListenerMap.indexOfValue(listener);
            if (index == -1) {
                return INVALID_KEY;
            } else {
                return sListenerMap.keyAt(index);
                return mListenerMap.keyAt(index);
            }
        }
    }

    private static Object removeListener(int key) {
    private Object removeListener(int key) {
        if (key == INVALID_KEY) return null;
        synchronized (sListenerMapLock) {
            Object listener = sListenerMap.get(key);
            sListenerMap.remove(key);
        synchronized (mListenerMapLock) {
            Object listener = mListenerMap.get(key);
            mListenerMap.remove(key);
            return listener;
        }
    }

    private static int removeListener(Object listener) {
    private int removeListener(Object listener) {
        int key = getListenerKey(listener);
        if (key == INVALID_KEY) return key;
        synchronized (sListenerMapLock) {
            sListenerMap.remove(key);
        synchronized (mListenerMapLock) {
            mListenerMap.remove(key);
            return key;
        }
    }

    private static class ServiceHandler extends Handler {
    private class ServiceHandler extends Handler {
        ServiceHandler(Looper looper) {
            super(looper);
        }
@@ -1258,24 +1234,13 @@ public class RttManager {
        public void handleMessage(Message msg) {
            Log.i(TAG, "RTT manager get message: " + msg.what);
            switch (msg.what) {
                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                        sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
                    } else {
                        Log.e(TAG, "Failed to set up channel connection");
                        // This will cause all further async API calls on the WifiManager
                        // to fail and throw an exception
                        sAsyncChannel = null;
                    }
                    return;
                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
                    sConnected.countDown();
                    return;
                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                    Log.e(TAG, "Channel connection lost");
                    // This will cause all further async API calls on the WifiManager
                    // to fail and throw an exception
                    sAsyncChannel = null;
                    mAsyncChannel = null;
                    getLooper().quit();
                    return;
            }