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

Commit e98351f3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I1f880aa6,Ie8ba8208,Ic45aa87c,I04c1263a

* changes:
  Add tests for UWB AdapterStateListener
  Implement UWB AdapterStateListener
  Implement UwbManager functions
  Expose UwbManager through Context.getSystemService
parents 3ae4d1c8 26728aef
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ import android.telephony.TelephonyRegistryManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.uwb.UwbManager;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.WindowManager;
@@ -719,6 +720,14 @@ public final class SystemServiceRegistry {
                return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
            }});

        registerService(Context.UWB_SERVICE, UwbManager.class,
                new CachedServiceFetcher<UwbManager>() {
                    @Override
                    public UwbManager createService(ContextImpl ctx) {
                        return UwbManager.getInstance();
                    }
                });

        registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
                new CachedServiceFetcher<Vibrator>() {
            @Override
+10 −0
Original line number Diff line number Diff line
@@ -3513,6 +3513,7 @@ public abstract class Context {
            //@hide: TIME_ZONE_DETECTOR_SERVICE,
            PERMISSION_SERVICE,
            LIGHTS_SERVICE,
            UWB_SERVICE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ServiceName {}
@@ -5177,6 +5178,15 @@ public abstract class Context {
     */
    public static final String LIGHTS_SERVICE = "lights";

    /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link android.uwb.UwbManager}.
     *
     * @see #getSystemService(String)
     * @hide
     */
    public static final String UWB_SERVICE = "uwb";

    /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link android.app.DreamManager} for controlling Dream states.
+9 −0
Original line number Diff line number Diff line
@@ -2498,6 +2498,15 @@ public abstract class PackageManager {
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device is capable of communicating with
     * other devices via ultra wideband.
     * @hide
     */
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_UWB = "android.hardware.uwb";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports connecting to USB devices
+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
Loading