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

Commit 475ae2e4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes Iaa590539,If3e25a2f into main am: 880014ba

parents f35d43b7 880014ba
Loading
Loading
Loading
Loading
+0 −131
Original line number Diff line number Diff line
@@ -24,138 +24,10 @@
#include "com_android_bluetooth.h"
#include "hardware/bt_activity_attribution.h"

using bluetooth::activity_attribution::ActivityAttributionCallbacks;
using bluetooth::activity_attribution::ActivityAttributionInterface;

namespace android {
static jmethodID method_onWakeup;
static jmethodID method_onActivityLogsReady;

static ActivityAttributionInterface* sActivityAttributionInterface = nullptr;
static std::shared_timed_mutex interface_mutex;

static jobject mCallbacksObj = nullptr;
static std::shared_timed_mutex callbacks_mutex;

class ActivityAttributionCallbacksImpl : public ActivityAttributionCallbacks {
 public:
  ~ActivityAttributionCallbacksImpl() = default;

  void OnWakeup(const Activity activity, const RawAddress& bd_addr) override {
    LOG(INFO) << __func__;

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;

    ScopedLocalRef<jbyteArray> addr(
        sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      LOG(ERROR)
          << "Failed to allocate jbyteArray for bd_addr of wakeup callback";
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     (jbyte*)&bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWakeup, (jint)activity,
                                 addr.get());
  }

  void OnActivityLogsReady(
      const std::vector<BtaaAggregationEntry> logs) override {
    LOG(INFO) << __func__;

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;

    jsize logs_size = logs.size() * sizeof(BtaaAggregationEntry);
    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(logs_size));
    if (!addr.get()) {
      LOG(ERROR) << "Failed to allocate jbyteArray for logs from activity "
                    "logging callback";
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, logs_size,
                                     (jbyte*)logs.data());
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onActivityLogsReady,
                                 addr.get());
  }
};

static ActivityAttributionCallbacksImpl sActivityAttributionCallbacks;

static void classInitNative(JNIEnv* env, jclass clazz) {
  method_onWakeup = env->GetMethodID(clazz, "onWakeup", "(I[B)V");
  method_onActivityLogsReady =
      env->GetMethodID(clazz, "onActivityLogsReady", "([B)V");

  LOG(INFO) << __func__ << ": succeeds";
}

static void initNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == nullptr) {
    LOG(ERROR) << "Bluetooth module is not loaded";
    return;
  }

  if (sActivityAttributionInterface != nullptr) {
    LOG(INFO)
        << "Cleaning up ActivityAttribution Interface before initializing...";
    sActivityAttributionInterface->Cleanup();
    sActivityAttributionInterface = nullptr;
  }

  if (mCallbacksObj != nullptr) {
    LOG(INFO) << "Cleaning up ActivityAttribution callback object";
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = nullptr;
  }

  if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) {
    LOG(ERROR)
        << "Failed to allocate Global Ref for ActivityAttribution Callbacks";
    return;
  }

  sActivityAttributionInterface =
      (ActivityAttributionInterface*)btInf->get_profile_interface(
          BT_ACTIVITY_ATTRIBUTION_ID);
  if (sActivityAttributionInterface == nullptr) {
    LOG(ERROR) << "Failed to get ActivityAttribution Interface";
    return;
  }

  sActivityAttributionInterface->RegisterCallbacks(
      &sActivityAttributionCallbacks);
}

static void cleanupNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == nullptr) {
    LOG(ERROR) << "Bluetooth module is not loaded";
    return;
  }

  if (sActivityAttributionInterface != nullptr) {
    sActivityAttributionInterface->Cleanup();
    sActivityAttributionInterface = nullptr;
  }

  if (mCallbacksObj != nullptr) {
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = nullptr;
  }
}

static void notifyActivityAttributionInfoNative(JNIEnv* env, jobject object,
                                                jint uid, jstring packageName,
@@ -186,9 +58,6 @@ static void notifyActivityAttributionInfoNative(JNIEnv* env, jobject object,
}

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initNative", "()V", (void*)initNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"notifyActivityAttributionInfoNative",
     "(ILjava/lang/String;Ljava/lang/String;)V",
     (void*)notifyActivityAttributionInfoNative},
+0 −5
Original line number Diff line number Diff line
@@ -718,7 +718,6 @@ public class AdapterService extends Service {
        mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this);

        mActivityAttributionService = new ActivityAttributionService();
        mActivityAttributionService.start();

        setAdapterService(this);

@@ -1362,10 +1361,6 @@ public class AdapterService extends Service {
            mSdpManager = null;
        }

        if (mActivityAttributionService != null) {
            mActivityAttributionService.cleanup();
        }

        if (mNativeAvailable) {
            debugLog("cleanup() - Cleaning up adapter native");
            cleanupNative();
+1 −41
Original line number Diff line number Diff line
@@ -21,26 +21,15 @@
 */
package com.android.bluetooth.btservice.activityattribution;

import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.util.Arrays;

/** ActivityAttribution Native Interface to/from JNI. */
public class ActivityAttributionNativeInterface {
    private static final boolean DBG = false;
    private static final String TAG = "ActivityAttributionNativeInterface";

    @GuardedBy("INSTANCE_LOCK")
    private static ActivityAttributionNativeInterface sInstance;

    private static final Object INSTANCE_LOCK = new Object();

    static {
        classInitNative();
    }

    /** Get singleton instance. */
    public static ActivityAttributionNativeInterface getInstance() {
        synchronized (INSTANCE_LOCK) {
@@ -51,40 +40,11 @@ public class ActivityAttributionNativeInterface {
        }
    }

    /** Initializes the native interface. */
    public void init() {
        initNative();
    }

    /** Cleanup the native interface. */
    public void cleanup() {
        cleanupNative();
    }

    /** Notify the UID and package name of the app, and the address of associated active device */
    public void notifyActivityAttributionInfo(int uid, String packageName, String deviceAddress) {
        notifyActivityAttributionInfoNative(uid, packageName, deviceAddress);
    }

    // Callbacks from the native stack back into the Java framework.
    // All callbacks are routed via the Service which will disambiguate which
    // state machine the message should be routed to.

    private void onWakeup(int activity, byte[] address) {
        Log.i(TAG, "onWakeup() BTAA: " + activity);
    }

    private void onActivityLogsReady(byte[] logs) {
        Log.i(TAG, "onActivityLogsReady() BTAA: " + Arrays.toString(logs));
    }

    // Native methods that call into the JNI interface
    private static native void classInitNative();

    private native void initNative();

    private native void cleanupNative();

    private native void notifyActivityAttributionInfoNative(
            int uid, String packageName, String deviceAddress);
}
+11 −85
Original line number Diff line number Diff line
@@ -16,105 +16,31 @@

package com.android.bluetooth.btservice.activityattribution;

import android.util.Log;
import static java.util.Objects.requireNonNull;

import java.util.Objects;
import android.util.Log;

/**
 * Service used for attributes wakeup, wakelock and Bluetooth traffic into per-app and per-device
 * based activities.
 */
public class ActivityAttributionService {
    private boolean mCleaningUp;
    private static ActivityAttributionService sActivityAttributionService;
    private static final boolean DBG = false;
    private static final String TAG = "ActivityAttributionService";
    private static final String TAG = ActivityAttributionService.class.getSimpleName();

    private final ActivityAttributionNativeInterface mActivityAttributionNativeInterface =
            Objects.requireNonNull(
            requireNonNull(
                    ActivityAttributionNativeInterface.getInstance(),
                    "ActivityAttributionNativeInterface "
                            + "cannot be null when ActivityAttributionService starts");

    /** Start and initialize the Activity Attribution service. */
    public void start() {
        debugLog("start()");

        if (sActivityAttributionService != null) {
            Log.e(TAG, "start() called twice");
            return;
        }

        // Mark service as started
        setActivityAttributionService(this);
    }

    /** Cleans up the Activity Attribution service. */
    public void cleanup() {
        debugLog("cleanup");
        if (mCleaningUp) {
            debugLog("already doing cleanup");
            return;
        }

        mCleaningUp = true;

        if (sActivityAttributionService == null) {
            debugLog("cleanup() called before start()");
            return;
        }

        // Mark service as stopped
        setActivityAttributionService(null);

        // Cleanup native interface
        mActivityAttributionNativeInterface.cleanup();
    }

    /** Get the ActivityAttributionService instance */
    public static synchronized ActivityAttributionService getActivityAttributionService() {
        if (sActivityAttributionService == null) {
            Log.w(TAG, "getActivityAttributionService(): service is NULL");
            return null;
        }

        if (!sActivityAttributionService.isAvailable()) {
            Log.w(TAG, "getActivityAttributionService(): service is not available");
            return null;
        }
        return sActivityAttributionService;
    }

    /** Init JNI */
    public void initJni() {
        debugLog("initJni()");
        // Initialize native interface
        mActivityAttributionNativeInterface.init();
    }
                    "ActivityAttributionNativeInterface cannot be null");

    /** Notify the UID and package name of the app, and the address of associated active device */
    public void notifyActivityAttributionInfo(int uid, String packageName, String deviceAddress) {
        Log.d(TAG, "notifyActivityAttributionInfo"
                + " UID=" + uid
                + " packageName=" + packageName
                + " deviceAddress=" + deviceAddress);
        Log.d(
                TAG,
                "notifyActivityAttributionInfo()"
                        + (" UID=" + uid)
                        + (" packageName=" + packageName)
                        + (" deviceAddress=" + deviceAddress));
        mActivityAttributionNativeInterface.notifyActivityAttributionInfo(
                uid, packageName, deviceAddress);
    }

    private boolean isAvailable() {
        return !mCleaningUp;
    }

    private static synchronized void setActivityAttributionService(
            ActivityAttributionService instance) {
        debugLog("setActivityAttributionService(): set to: " + instance);
        sActivityAttributionService = instance;
    }

    private static void debugLog(String msg) {
        if (DBG) {
            Log.d(TAG, msg);
        }
    }
}
+0 −15
Original line number Diff line number Diff line
@@ -16,12 +16,9 @@

package com.android.bluetooth.btservice.activityattribution;

import static com.google.common.truth.Truth.assertThat;

import android.os.Binder;
import android.os.Process;

import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -30,24 +27,12 @@ import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public final class ActivityAttributionServiceTest {
    private static final String TAG = "ActivityAttributionServiceTest";
    private ActivityAttributionService mActivityAttributionService;

    @Before
    public void setUp() {
        Assume.assumeTrue("Ignore test when the user is not primary.", isPrimaryUser());
        mActivityAttributionService = new ActivityAttributionService();
        mActivityAttributionService.start();
        assertThat(mActivityAttributionService).isNotNull();
    }

    @After
    public void tearDown() {
        if (!isPrimaryUser()) {
            return;
        }
        mActivityAttributionService.cleanup();
        mActivityAttributionService = null;
    }

    private boolean isPrimaryUser() {
Loading