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

Commit 69bac978 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I1f880aa6,Ie8ba8208,Ic45aa87c,I04c1263a am: e98351f3 am: 460fe6a1

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1504104

Change-Id: If541c5fcba1ac444d359741c5f5b12090c57003b
parents c57e2123 460fe6a1
Loading
Loading
Loading
Loading
+149 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.uwb;

import android.annotation.NonNull;
import android.os.Binder;
import android.os.RemoteException;
import android.util.Log;
import android.uwb.UwbManager.AdapterStateCallback;
import android.uwb.UwbManager.AdapterStateCallback.StateChangedReason;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * @hide
 */
public class AdapterStateListener extends IUwbAdapterStateCallbacks.Stub {
    private static final String TAG = "Uwb.StateListener";

    private final IUwbAdapter mAdapter;
    private boolean mIsRegistered = false;

    private final Map<AdapterStateCallback, Executor> mCallbackMap = new HashMap<>();

    @StateChangedReason
    private int mAdapterStateChangeReason = AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN;
    private boolean mAdapterEnabledState = false;

    public AdapterStateListener(@NonNull IUwbAdapter adapter) {
        mAdapter = adapter;
    }

    /**
     * Register an {@link AdapterStateCallback} with this {@link AdapterStateListener}
     *
     * @param executor an {@link Executor} to execute given callback
     * @param callback user implementation of the {@link AdapterStateCallback}
     */
    public void register(@NonNull Executor executor, @NonNull AdapterStateCallback callback) {
        synchronized (this) {
            if (mCallbackMap.containsKey(callback)) {
                return;
            }

            mCallbackMap.put(callback, executor);

            if (!mIsRegistered) {
                try {
                    mAdapter.registerAdapterStateCallbacks(this);
                    mIsRegistered = true;
                } catch (RemoteException e) {
                    Log.w(TAG, "Failed to register adapter state callback");
                    executor.execute(() -> callback.onStateChanged(false,
                            AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN));
                }
            } else {
                sendCurrentState(callback);
            }
        }
    }

    /**
     * Unregister the specified {@link AdapterStateCallback}
     *
     * @param callback user implementation of the {@link AdapterStateCallback}
     */
    public void unregister(@NonNull AdapterStateCallback callback) {
        synchronized (this) {
            if (!mCallbackMap.containsKey(callback)) {
                return;
            }

            mCallbackMap.remove(callback);

            if (mCallbackMap.isEmpty() && mIsRegistered) {
                try {
                    mAdapter.unregisterAdapterStateCallbacks(this);
                } catch (RemoteException e) {
                    Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
                }
                mIsRegistered = false;
            }
        }
    }

    private void sendCurrentState(@NonNull AdapterStateCallback callback) {
        synchronized (this) {
            Executor executor = mCallbackMap.get(callback);

            final long identity = Binder.clearCallingIdentity();
            try {
                executor.execute(() -> callback.onStateChanged(
                        mAdapterEnabledState, mAdapterStateChangeReason));
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
    }

    @Override
    public void onAdapterStateChanged(boolean isEnabled, int reason) {
        synchronized (this) {
            @StateChangedReason int localReason =
                    convertToStateChangedReason(reason);
            mAdapterEnabledState = isEnabled;
            mAdapterStateChangeReason = localReason;
            for (AdapterStateCallback cb : mCallbackMap.keySet()) {
                sendCurrentState(cb);
            }
        }
    }

    private static @StateChangedReason int convertToStateChangedReason(
            @StateChangeReason int reason) {
        switch (reason) {
            case StateChangeReason.ALL_SESSIONS_CLOSED:
                return AdapterStateCallback.STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED;

            case StateChangeReason.SESSION_STARTED:
                return AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED;

            case StateChangeReason.SYSTEM_POLICY:
                return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY;

            case StateChangeReason.SYSTEM_BOOT:
                return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT;

            case StateChangeReason.UNKNOWN:
            default:
                return AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN;
        }
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -98,11 +98,18 @@ interface IUwbAdapter {
  int getMaxSimultaneousSessions();

  /**
   * Get the maximum number of remote devices per session
   * Get the maximum number of remote devices per session when local device is initiator
   *
   * @return the maximum number of remote devices supported in a single session
   */
  int getMaxRemoteDevicesPerSession();
  int getMaxRemoteDevicesPerInitiatorSession();

  /**
   * Get the maximum number of remote devices per session when local device is responder
   *
   * @return the maximum number of remote devices supported in a single session
   */
  int getMaxRemoteDevicesPerResponderSession();

  /**
   * Provides the capabilities and features of the device
+5 −0
Original line number Diff line number Diff line
@@ -41,5 +41,10 @@ enum StateChangeReason {
   * The adapter state changed because of a device system change.
   */
  SYSTEM_POLICY,

  /**
   * Used to signal the first adapter state message after boot
   */
   SYSTEM_BOOT,
}
+78 −13
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.uwb;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
@@ -23,10 +24,13 @@ import android.annotation.SystemService;
import android.content.Context;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -45,6 +49,8 @@ public final class UwbManager {
    private IUwbAdapter mUwbAdapter;
    private static final String SERVICE_NAME = "uwb";

    private AdapterStateListener mAdapterStateListener;

    /**
     * Interface for receiving UWB adapter state changes
     */
@@ -109,6 +115,7 @@ public final class UwbManager {
     */
    private UwbManager(IUwbAdapter adapter) {
        mUwbAdapter = adapter;
        mAdapterStateListener = new AdapterStateListener(adapter);
    }

    /**
@@ -140,8 +147,9 @@ public final class UwbManager {
     * @param executor an {@link Executor} to execute given callback
     * @param callback user implementation of the {@link AdapterStateCallback}
     */
    public void registerAdapterStateCallback(Executor executor, AdapterStateCallback callback) {
        throw new UnsupportedOperationException();
    public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull AdapterStateCallback callback) {
        mAdapterStateListener.register(executor, callback);
    }

    /**
@@ -153,8 +161,8 @@ public final class UwbManager {
     *
     * @param callback user implementation of the {@link AdapterStateCallback}
     */
    public void unregisterAdapterStateCallback(AdapterStateCallback callback) {
        throw new UnsupportedOperationException();
    public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
        mAdapterStateListener.unregister(callback);
    }

    /**
@@ -167,7 +175,11 @@ public final class UwbManager {
     */
    @NonNull
    public PersistableBundle getSpecificationInfo() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.getSpecificationInfo();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -176,7 +188,11 @@ public final class UwbManager {
     * @return true if ranging is supported
     */
    public boolean isRangingSupported() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.isRangingSupported();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Retention(RetentionPolicy.SOURCE)
@@ -225,7 +241,24 @@ public final class UwbManager {
     */
    @AngleOfArrivalSupportType
    public int getAngleOfArrivalSupport() {
        throw new UnsupportedOperationException();
        try {
            switch (mUwbAdapter.getAngleOfArrivalSupport()) {
                case AngleOfArrivalSupport.TWO_DIMENSIONAL:
                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D;

                case AngleOfArrivalSupport.THREE_DIMENSIONAL_HEMISPHERICAL:
                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL;

                case AngleOfArrivalSupport.THREE_DIMENSIONAL_SPHERICAL:
                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL;

                case AngleOfArrivalSupport.NONE:
                default:
                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE;
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -239,7 +272,15 @@ public final class UwbManager {
     */
    @NonNull
    public List<Integer> getSupportedChannelNumbers() {
        throw new UnsupportedOperationException();
        List<Integer> channels = new ArrayList<>();
        try {
            for (int channel : mUwbAdapter.getSupportedChannels()) {
                channels.add(channel);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return channels;
    }

    /**
@@ -250,7 +291,15 @@ public final class UwbManager {
     */
    @NonNull
    public Set<Integer> getSupportedPreambleCodeIndices() {
        throw new UnsupportedOperationException();
        Set<Integer> preambles = new HashSet<>();
        try {
            for (int preamble : mUwbAdapter.getSupportedPreambleCodes()) {
                preambles.add(preamble);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return preambles;
    }

    /**
@@ -262,7 +311,11 @@ public final class UwbManager {
     */
    @SuppressLint("MethodNameUnits")
    public long elapsedRealtimeResolutionNanos() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.getTimestampResolutionNanos();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -271,7 +324,11 @@ public final class UwbManager {
     * @return the maximum allowed number of simultaneously open {@link RangingSession} instances.
     */
    public int getMaxSimultaneousSessions() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.getMaxSimultaneousSessions();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -281,7 +338,11 @@ public final class UwbManager {
     * @return the maximum number of remote devices per {@link RangingSession}
     */
    public int getMaxRemoteDevicesPerInitiatorSession() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.getMaxRemoteDevicesPerInitiatorSession();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
@@ -291,7 +352,11 @@ public final class UwbManager {
     * @return the maximum number of remote devices per {@link RangingSession}
     */
    public int getMaxRemoteDevicesPerResponderSession() {
        throw new UnsupportedOperationException();
        try {
            return mUwbAdapter.getMaxRemoteDevicesPerResponderSession();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ android_test {
    static_libs: [
        "androidx.test.ext.junit",
        "androidx.test.rules",
        "mockito-target-minus-junit4",
    ],
    libs: [
        "android.test.runner",
Loading