Merge "[DO NOT MERGE] Add FastPairService in server" into tm-dev
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
index b12e263..6a296c2 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -47,7 +47,6 @@
 public class FastPairAdvHandler {
     Context mContext;
     String mBleAddress;
-
     /** The types about how the bloomfilter is processed. */
     public enum ProcessBloomFilterType {
         IGNORE, // The bloomfilter is not handled. e.g. distance is too far away.
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
index cfac904..42839b2 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
@@ -33,7 +33,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 
-import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
 import com.android.server.nearby.fastpair.FastPairController;
 import com.android.server.nearby.fastpair.cache.DiscoveryItem;
 import com.android.server.nearby.util.Environment;
@@ -47,20 +47,28 @@
  * Fast Pair ux manager for half sheet.
  */
 public class FastPairHalfSheetManager {
-    private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET";
+    static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET";
     private static final String HALF_SHEET_CLASS_NAME =
             "com.android.nearby.halfsheet.HalfSheetActivity";
 
     private String mHalfSheetApkPkgName;
     private Context mContext;
+    private LocatorContextWrapper mLocatorContextWrapper;
 
     /**
      * Construct function
      */
     public FastPairHalfSheetManager(Context context) {
         mContext = context;
+        mLocatorContextWrapper = new LocatorContextWrapper(context);
     }
 
+    /**
+     * Construct function for test
+     */
+    public FastPairHalfSheetManager(LocatorContextWrapper locatorContextWrapper) {
+        mLocatorContextWrapper = locatorContextWrapper;
+    }
 
     /**
      * Invokes half sheet in the other apk. This function can only be called in Nearby because other
@@ -68,13 +76,18 @@
      */
     public void showHalfSheet(Cache.ScanFastPairStoreItem scanFastPairStoreItem) {
         try {
-            if (mContext != null) {
+            if (mLocatorContextWrapper != null) {
                 String packageName = getHalfSheetApkPkgName();
+                if (packageName == null) {
+                    Log.e("FastPairHalfSheetManager", "package name is null");
+                    return;
+                }
                 HalfSheetCallback callback = new HalfSheetCallback();
-                callback.setmFastPairController(Locator.get(mContext, FastPairController.class));
+                callback.setmFastPairController(
+                        mLocatorContextWrapper.getLocator().get(FastPairController.class));
                 Bundle bundle = new Bundle();
                 bundle.putBinder(EXTRA_BINDER, callback);
-                mContext
+                mLocatorContextWrapper
                         .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION)
                                         .putExtra(EXTRA_HALF_SHEET_INFO,
                                                 scanFastPairStoreItem.toByteArray())
@@ -153,7 +166,7 @@
         if (mHalfSheetApkPkgName != null) {
             return mHalfSheetApkPkgName;
         }
-        List<ResolveInfo> resolveInfos = mContext
+        List<ResolveInfo> resolveInfos = mLocatorContextWrapper
                 .getPackageManager().queryIntentActivities(
                         new Intent(ACTION_RESOURCES_APK),
                         PackageManager.MATCH_SYSTEM_ONLY);
diff --git a/nearby/service/java/com/android/server/nearby/util/Environment.java b/nearby/service/java/com/android/server/nearby/util/Environment.java
index e7277cd..d397862 100644
--- a/nearby/service/java/com/android/server/nearby/util/Environment.java
+++ b/nearby/service/java/com/android/server/nearby/util/Environment.java
@@ -33,7 +33,7 @@
 
     /**
      * The path where the Nearby apex is mounted.
-     * Current value = "/apex/com.android.nearby"
+     * Current value = "/apex/com.android.tethering"
      */
     private static final String NEARBY_APEX_PATH =
             new File("/apex", NEARBY_APEX_NAME).getAbsolutePath();
@@ -55,7 +55,7 @@
 
     /**
      * Returns true if the app is in the nearby apex, false otherwise.
-     * Checks if the app's path starts with "/apex/com.android.nearby".
+     * Checks if the app's path starts with "/apex/com.android.tethering".
      */
     public static boolean isAppInNearbyApex(ApplicationInfo appInfo) {
         return appInfo.sourceDir.startsWith(NEARBY_APEX_PATH);
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java
new file mode 100644
index 0000000..ab18f54
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManagerTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.nearby.fastpair.halfsheet;
+
+
+import static com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager.ACTIVITY_INTENT_ACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.FastPairController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import service.proto.Cache;
+
+public class FastPairHalfSheetManagerTest {
+    private static final String BLEADDRESS = "11:22:44:66";
+    private static final String NAME = "device_name";
+    private FastPairHalfSheetManager mFastPairHalfSheetManager;
+    private Cache.ScanFastPairStoreItem mScanFastPairStoreItem;
+    @Mock
+    LocatorContextWrapper mContextWrapper;
+    @Mock
+    ResolveInfo mResolveInfo;
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    Locator mLocator;
+    @Mock
+    FastPairController mFastPairController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+
+        mScanFastPairStoreItem = Cache.ScanFastPairStoreItem.newBuilder()
+                .setAddress(BLEADDRESS)
+                .setDeviceName(NAME)
+                .build();
+    }
+
+    @Test
+    public void verifyFastPairHalfSheetManagerBehavior() {
+        mLocator.overrideBindingForTest(FastPairController.class, mFastPairController);
+        ResolveInfo resolveInfo = new ResolveInfo();
+        List<ResolveInfo> resolveInfoList = new ArrayList<>();
+
+
+        mPackageManager = mock(PackageManager.class);
+        when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager);
+        resolveInfo.activityInfo = new ActivityInfo();
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.sourceDir = "/apex/com.android.tethering";
+        applicationInfo.packageName = "test.package";
+        resolveInfo.activityInfo.applicationInfo = applicationInfo;
+        resolveInfoList.add(resolveInfo);
+        when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList);
+        when(mPackageManager.canRequestPackageInstalls()).thenReturn(false);
+
+        mFastPairHalfSheetManager =
+                new FastPairHalfSheetManager(mContextWrapper);
+
+        when(mContextWrapper.getLocator()).thenReturn(mLocator);
+
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem);
+
+        verify(mContextWrapper, atLeastOnce())
+                .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT));
+        Intent launchIntent = intentArgumentCaptor.getValue();
+        assertThat(launchIntent.getAction()).isEqualTo(ACTIVITY_INTENT_ACTION);
+    }
+
+    @Test
+    public void verifyFastPairHalfSheetManagerHalfSheetApkNotValidBehavior() {
+        mLocator.overrideBindingForTest(FastPairController.class, mFastPairController);
+        ResolveInfo resolveInfo = new ResolveInfo();
+        List<ResolveInfo> resolveInfoList = new ArrayList<>();
+
+
+        mPackageManager = mock(PackageManager.class);
+        when(mContextWrapper.getPackageManager()).thenReturn(mPackageManager);
+        resolveInfo.activityInfo = new ActivityInfo();
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        // application directory is wrong
+        applicationInfo.sourceDir = "/apex/com.android.nearby";
+        applicationInfo.packageName = "test.package";
+        resolveInfo.activityInfo.applicationInfo = applicationInfo;
+        resolveInfoList.add(resolveInfo);
+        when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfoList);
+        when(mPackageManager.canRequestPackageInstalls()).thenReturn(false);
+
+        mFastPairHalfSheetManager =
+                new FastPairHalfSheetManager(mContextWrapper);
+
+        when(mContextWrapper.getLocator()).thenReturn(mLocator);
+
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        mFastPairHalfSheetManager.showHalfSheet(mScanFastPairStoreItem);
+
+        verify(mContextWrapper, never())
+                .startActivityAsUser(intentArgumentCaptor.capture(), eq(UserHandle.CURRENT));
+
+    }
+}