All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robolectric.shadows.ShadowContextHubManager Maven / Gradle / Ivy

package org.robolectric.shadows;

import static org.robolectric.util.reflector.Reflector.reflector;

import android.app.PendingIntent;
import android.content.Context;
import android.hardware.location.ContextHubClient;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubManager;
import android.hardware.location.ContextHubTransaction;
import android.hardware.location.NanoAppInstanceInfo;
import android.hardware.location.NanoAppState;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.Nullable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
import org.robolectric.util.reflector.Accessor;
import org.robolectric.util.reflector.ForType;

/** Shadow for {@link ContextHubManager}. */
@Implements(
    value = ContextHubManager.class,
    minSdk = VERSION_CODES.N,
    isInAndroidSdk = false,
    looseSignatures = true)
public class ShadowContextHubManager {
  private static final List contextHubInfoList = new ArrayList<>();
  private static final List contextHubClientWithPendingIntentList =
      new ArrayList<>();
  private final Map nanoAppUidToInfo = new ConcurrentHashMap<>();
  private final Multimap contextHubToNanoappUid =
      Multimaps.synchronizedMultimap(HashMultimap.create());
  private final HashMultimap attributionTagToClientMap =
      HashMultimap.create();

  static {
    contextHubInfoList.add(new ContextHubInfo());
  }

  /** Adds a nanoApp to the list of nanoApps that are supported by the provided contexthubinfo. */
  public void addNanoApp(ContextHubInfo info, int nanoAppUid, long nanoAppId, int nanoAppVersion) {
    contextHubToNanoappUid.put(info, nanoAppUid);
    NanoAppInstanceInfo instanceInfo =
        createInstanceInfo(info, nanoAppUid, nanoAppId, nanoAppVersion);
    nanoAppUidToInfo.put(nanoAppUid, instanceInfo);
  }

  /** Creates and returns a {@link NanoAppInstanceInfo}. */
  public NanoAppInstanceInfo createInstanceInfo(
      ContextHubInfo info, int nanoAppUid, long nanoAppId, int nanoAppVersion) {
    if (VERSION.SDK_INT >= VERSION_CODES.P) {
      return new NanoAppInstanceInfo(nanoAppUid, nanoAppId, nanoAppVersion, info.getId());
    } else {
      NanoAppInstanceInfo instanceInfo = new NanoAppInstanceInfo();
      ReflectorNanoAppInstanceInfo reflectedInfo =
          reflector(ReflectorNanoAppInstanceInfo.class, instanceInfo);
      reflectedInfo.setAppId(nanoAppId);
      reflectedInfo.setAppVersion(nanoAppVersion);
      return instanceInfo;
    }
  }

  /**
   * Provides a list with fake {@link ContextHubInfo}s.
   *
   * 

{@link ContextHubInfo} describes an optional physical chip on the device. This does not * exist in test; this implementation allows to avoid possible NPEs. */ @Implementation(minSdk = VERSION_CODES.P) @HiddenApi protected List getContextHubs() { return contextHubInfoList; } @Implementation(minSdk = VERSION_CODES.P) @HiddenApi protected Object /* ContextHubClient */ createClient( Object /* ContextHubInfo */ contextHubInfo, Object /* ContextHubClientCallback */ contextHubClientCallback) { return ReflectionHelpers.newInstance(ContextHubClient.class); } @Implementation(minSdk = VERSION_CODES.P) @HiddenApi protected Object /* ContextHubClient */ createClient( Object /* ContextHubInfo */ contextHubInfo, Object /* ContextHubClientCallback */ contextHubClientCallback, Object /* Executor */ executor) { return ReflectionHelpers.newInstance(ContextHubClient.class); } @Implementation(minSdk = VERSION_CODES.S) @HiddenApi protected Object /* ContextHubClient */ createClient( Object /* Context */ context, Object /* ContextHubInfo */ contextHubInfo, Object /* Executor */ executor, Object /* ContextHubClientCallback */ contextHubClientCallback) { ContextHubClient client = ReflectionHelpers.newInstance(ContextHubClient.class); if (context != null && ((Context) context).getAttributionTag() != null) { attributionTagToClientMap.put(((Context) context).getAttributionTag(), client); } return client; } @Implementation(minSdk = VERSION_CODES.S) @HiddenApi protected Object /* ContextHubClient */ createClient( Context context, ContextHubInfo hubInfo, PendingIntent pendingIntent, long nanoAppId) { ContextHubClient client = Shadow.newInstance( ContextHubClient.class, new Class[] {ContextHubInfo.class, Boolean.TYPE}, new Object[] {hubInfo, false}); contextHubClientWithPendingIntentList.add(client); return client; } @Nullable public List getClientsWithAttributionTag(String attributionTag) { return ImmutableList.copyOf(attributionTagToClientMap.get(attributionTag)); } @Nullable public List getContextHubClientWithPendingIntentList() { return ImmutableList.copyOf(contextHubClientWithPendingIntentList); } @Implementation(minSdk = VERSION_CODES.P) @HiddenApi protected Object queryNanoApps(ContextHubInfo hubInfo) { @SuppressWarnings("unchecked") ContextHubTransaction> transaction = ReflectionHelpers.callConstructor( ContextHubTransaction.class, ClassParameter.from(int.class, ContextHubTransaction.TYPE_QUERY_NANOAPPS)); Collection uids = contextHubToNanoappUid.get(hubInfo); List nanoAppStates = new ArrayList<>(); for (Integer uid : uids) { NanoAppInstanceInfo info = nanoAppUidToInfo.get(uid); if (info != null) { nanoAppStates.add( new NanoAppState(info.getAppId(), info.getAppVersion(), true /* enabled */)); } } @SuppressWarnings("unchecked") ContextHubTransaction.Response> response = ReflectionHelpers.newInstance(ContextHubTransaction.Response.class); ReflectorContextHubTransactionResponse reflectedResponse = reflector(ReflectorContextHubTransactionResponse.class, response); reflectedResponse.setResult(ContextHubTransaction.RESULT_SUCCESS); reflectedResponse.setContents(nanoAppStates); reflector(ReflectorContextHubTransaction.class, transaction).setResponse(response); return transaction; } /** * Provides an array of fake handles. * *

These describe an optional physical chip on the device which does not exist during testing. * This implementation enables testing of classes that utilize these APIs. */ @Implementation @HiddenApi protected int[] getContextHubHandles() { int[] handles = new int[contextHubInfoList.size()]; for (int i = 0; i < handles.length; i++) { handles[i] = i; } return handles; } @Implementation @HiddenApi protected ContextHubInfo getContextHubInfo(int hubHandle) { if (hubHandle < 0 || hubHandle >= contextHubInfoList.size()) { return null; } return contextHubInfoList.get(hubHandle); } @Implementation @HiddenApi protected NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) { return nanoAppUidToInfo.get(nanoAppHandle); } /** Accessor interface for {@link NanoAppInstanceInfo}'s internals. */ @ForType(NanoAppInstanceInfo.class) private interface ReflectorNanoAppInstanceInfo { void setAppId(long nanoAppId); void setAppVersion(int nanoAppVersion); } /** Accessor interface for {@link ContextHubTransaction}'s internals. */ @ForType(ContextHubTransaction.class) private interface ReflectorContextHubTransaction { void setResponse(ContextHubTransaction.Response> response); } /** Accessor interface for {@link ContextHubTransaction.Response}'s internals. */ @ForType(ContextHubTransaction.Response.class) private interface ReflectorContextHubTransactionResponse { @Accessor("mResult") void setResult(int result); @Accessor("mContents") void setContents(List contents); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy