Wifi: Set package name on the intent

Set package name on the intent for EapFailureNotifier and
SimRequiredNotifier

Bug: 156008365
Test: atest FrameworksWifiTests
Test: Make sure notification can be popped up
Test: Verified that the app can no longer hijack the intent. (Was able
to to repro the log from the app before the fix)

Change-Id: I7e66e50d9fd8e953f4a8c75f654448e940389913
diff --git a/service/java/com/android/server/wifi/EapFailureNotifier.java b/service/java/com/android/server/wifi/EapFailureNotifier.java
index cdb1203..1d82082 100644
--- a/service/java/com/android/server/wifi/EapFailureNotifier.java
+++ b/service/java/com/android/server/wifi/EapFailureNotifier.java
@@ -16,23 +16,29 @@
 
 package com.android.server.wifi;
 
+import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Icon;
 import android.net.wifi.WifiConfiguration;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 
+import java.util.List;
+
 /**
  * This class may be used to launch notifications when EAP failure occurs.
  */
@@ -92,13 +98,29 @@
         showNotification(errorMessage, config.SSID);
     }
 
+    private String getSettingsPackageName() {
+        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DEFAULT_ONLY,
+                UserHandle.of(ActivityManager.getCurrentUser()));
+        if (resolveInfos == null || resolveInfos.isEmpty()) {
+            Log.e(TAG, "Failed to resolve wifi settings activity");
+            return null;
+        }
+        // Pick the first one if there are more than 1 since the list is ordered from best to worst.
+        return resolveInfos.get(0).activityInfo.packageName;
+    }
+
     /**
      * Display eap error notification which defined by carrier.
      *
      * @param ssid Error Message which defined by carrier
      */
     private void showNotification(String errorMessage, String ssid) {
-        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
+        String settingsPackage = getSettingsPackageName();
+        if (settingsPackage == null) return;
+        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS)
+                .setPackage(settingsPackage);
         Notification.Builder builder = mFrameworkFacade.makeNotificationBuilder(mContext,
                 WifiService.NOTIFICATION_NETWORK_ALERTS)
                 .setAutoCancel(true)
diff --git a/service/java/com/android/server/wifi/SimRequiredNotifier.java b/service/java/com/android/server/wifi/SimRequiredNotifier.java
index 8e3d22d..fed7bd8 100644
--- a/service/java/com/android/server/wifi/SimRequiredNotifier.java
+++ b/service/java/com/android/server/wifi/SimRequiredNotifier.java
@@ -16,22 +16,31 @@
 
 package com.android.server.wifi;
 
+import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
 import android.net.wifi.WifiConfiguration;
+import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Log;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.wifi.resources.R;
+
+import java.util.List;
+
 /**
  * Helper class to generate SIM required notification
  *
  */
 public class SimRequiredNotifier {
 
+    private static final String TAG = "SimRequiredNotifier";
     private final WifiContext mContext;
     private final FrameworkFacade mFrameworkFacade;
     private final NotificationManager mNotificationManager;
@@ -53,8 +62,7 @@
         } else {
             name = config.SSID;
         }
-        mNotificationManager.notify(SystemMessage.NOTE_ID_WIFI_SIM_REQUIRED,
-                buildSimRequiredNotification(name, carrier));
+        showNotification(name, carrier);
     }
 
     /**
@@ -64,15 +72,33 @@
         mNotificationManager.cancel(null, SystemMessage.NOTE_ID_WIFI_SIM_REQUIRED);
     }
 
-    private Notification buildSimRequiredNotification(String ssid, String carrier) {
+    private String getSettingsPackageName() {
+        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
+        List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DEFAULT_ONLY,
+                UserHandle.of(ActivityManager.getCurrentUser()));
+        if (resolveInfos == null || resolveInfos.isEmpty()) {
+            Log.e(TAG, "Failed to resolve wifi settings activity");
+            return null;
+        }
+        // Pick the first one if there are more than 1 since the list is ordered from best to worst.
+        return resolveInfos.get(0).activityInfo.packageName;
+    }
+
+    private void showNotification(String ssid, String carrier) {
+        String settingsPackage = getSettingsPackageName();
+        if (settingsPackage == null) return;
+        Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                .setPackage(settingsPackage);
+
         String title = mContext.getResources().getString(
                 R.string.wifi_sim_required_title);
         String message = mContext.getResources().getString(
                 R.string.wifi_sim_required_message,
                 (ssid == null ? "" : ssid),
                 (carrier == null ? "" : carrier));
-
-        return mFrameworkFacade.makeNotificationBuilder(mContext,
+        Notification.Builder builder = mFrameworkFacade.makeNotificationBuilder(mContext,
                 WifiService.NOTIFICATION_NETWORK_ALERTS)
                 .setAutoCancel(true)
                 .setShowWhen(false)
@@ -85,14 +111,9 @@
                 .setStyle(new Notification.BigTextStyle().bigText(message))
                 .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
                         R.drawable.stat_notify_wifi_in_range))
-                .setContentIntent(launchWirelessSettings())
-                .build();
-    }
-
-    private PendingIntent launchWirelessSettings() {
-        Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return mFrameworkFacade.getActivity(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                .setContentIntent(mFrameworkFacade.getActivity(
+                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+        mNotificationManager.notify(SystemMessage.NOTE_ID_WIFI_SIM_REQUIRED,
+                builder.build());
     }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
index d2a3ac0..2639133 100644
--- a/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
@@ -21,12 +21,17 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.net.wifi.WifiConfiguration;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.telephony.SubscriptionManager;
@@ -42,13 +47,18 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoSession;
 
+import java.util.Arrays;
+
 /**
  * Unit tests for {@link com.android.server.wifi.EapFailureNotifier}.
  */
 @SmallTest
 public class EapFailureNotifierTest extends WifiBaseTest {
+    private static final String TEST_SETTINGS_PACKAGE = "android";
+
     @Mock WifiContext mContext;
     @Mock Resources mResources;
+    @Mock PackageManager mPackageManager;
     @Mock NotificationManager mNotificationManager;
     @Mock FrameworkFacade mFrameworkFacade;
     @Mock Notification mNotification;
@@ -65,6 +75,7 @@
     private static final String UNDEFINED_ERROR_RESOURCE_NAME = "wifi_eap_error_message_code_12345";
     private MockitoSession mStaticMockSession = null;
 
+
     EapFailureNotifier mEapFailureNotifier;
 
     /**
@@ -73,15 +84,26 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        ResolveInfo settingsResolveInfo = new ResolveInfo();
+        settingsResolveInfo.activityInfo = new ActivityInfo();
+        settingsResolveInfo.activityInfo.packageName = TEST_SETTINGS_PACKAGE;
+        when(mPackageManager.queryIntentActivitiesAsUser(
+                argThat(((intent) -> intent.getAction().equals(Settings.ACTION_WIFI_SETTINGS))),
+                anyInt(), any()))
+                .thenReturn(Arrays.asList(settingsResolveInfo));
+        // static mocking
         mStaticMockSession = mockitoSession()
             .mockStatic(SubscriptionManager.class)
+            .mockStatic(ActivityManager.class, withSettings().lenient())
             .startMocking();
+        when(ActivityManager.getCurrentUser()).thenReturn(UserHandle.USER_SYSTEM);
         when(mContext.getSystemService(NotificationManager.class))
                 .thenReturn(mNotificationManager);
         when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(mWifiConfiguration)).thenReturn(0);
         lenient().when(SubscriptionManager.getResourcesForSubId(eq(mContext), anyInt()))
                 .thenReturn(mResources);
         when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mResources.getIdentifier(eq(DEFINED_ERROR_RESOURCE_NAME), anyString(),
                 anyString())).thenReturn(1);
         when(mResources.getIdentifier(eq(UNDEFINED_ERROR_RESOURCE_NAME), anyString(),
@@ -97,7 +119,10 @@
 
     @After
     public void cleanUp() throws Exception {
-        mStaticMockSession.finishMocking();
+        validateMockitoUsage();
+        if (mStaticMockSession != null) {
+            mStaticMockSession.finishMocking();
+        }
     }
 
     /**
@@ -120,6 +145,7 @@
         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
         verify(mFrameworkFacade).getActivity(
                 eq(mContext), eq(0), intent.capture(), eq(PendingIntent.FLAG_UPDATE_CURRENT));
+        assertEquals(TEST_SETTINGS_PACKAGE, intent.getValue().getPackage());
         assertEquals(Settings.ACTION_WIFI_SETTINGS, intent.getValue().getAction());
     }
 
@@ -146,6 +172,7 @@
         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
         verify(mFrameworkFacade).getActivity(
                 eq(mContext), eq(0), intent.capture(), eq(PendingIntent.FLAG_UPDATE_CURRENT));
+        assertEquals(TEST_SETTINGS_PACKAGE, intent.getValue().getPackage());
         assertEquals(Settings.ACTION_WIFI_SETTINGS, intent.getValue().getAction());
     }