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

Commit 7f42e118 authored by Hakjun Choi's avatar Hakjun Choi Committed by Android (Google) Code Review
Browse files

Merge "Show a system notification when satellite is connected for the first time" into main

parents 6c31d46f 4a9a1531
Loading
Loading
Loading
Loading
+90 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony.satellite;

import static android.provider.Settings.ACTION_SATELLITE_SETTING;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
@@ -33,6 +34,10 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCC
import android.annotation.ArrayRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -42,6 +47,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.nfc.NfcAdapter;
import android.os.AsyncResult;
@@ -62,6 +68,7 @@ import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
@@ -335,6 +342,16 @@ public class SatelliteController extends Handler {
    @GuardedBy("mSupportedSatelliteServicesLock")
    private final SparseArray<List<String>> mMergedPlmnListPerCarrier = new SparseArray<>();

    /** Key used to read/write satellite system notification done in shared preferences. */
    private static final String SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY =
            "satellite_system_notification_done_key";
    // The notification tag used when showing a notification. The combination of notification tag
    // and notification id should be unique within the phone app.
    private static final String NOTIFICATION_TAG = "SatelliteController";
    private static final int NOTIFICATION_ID = 1;
    private static final String NOTIFICATION_CHANNEL = "satelliteChannel";
    private static final String NOTIFICATION_CHANNEL_ID = "satellite";

    /**
     * @return The singleton instance of SatelliteController.
     */
@@ -3462,6 +3479,7 @@ public class SatelliteController extends Handler {

    private void handleEventServiceStateChanged() {
        handleServiceStateForSatelliteConnectionViaCarrier();
        determineSystemNotification();
    }

    private void handleServiceStateForSatelliteConnectionViaCarrier() {
@@ -3598,6 +3616,78 @@ public class SatelliteController extends Handler {
        return true;
    }

    private void determineSystemNotification() {
        if (isUsingNonTerrestrialNetworkViaCarrier()) {
            if (mSharedPreferences == null) {
                try {
                    mSharedPreferences = mContext.getSharedPreferences(SATELLITE_SHARED_PREF,
                            Context.MODE_PRIVATE);
                } catch (Exception e) {
                    loge("Cannot get default shared preferences: " + e);
                }
            }
            if (mSharedPreferences == null) {
                loge("handleEventServiceStateChanged: Cannot get default shared preferences");
                return;
            }
            if (!mSharedPreferences.getBoolean(SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY, false)) {
                showSatelliteSystemNotification();
                mSharedPreferences.edit().putBoolean(SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY,
                        true).apply();
            }
        }
    }

    private void showSatelliteSystemNotification() {
        logd("showSatelliteSystemNotification");
        final NotificationChannel notificationChannel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL,
                NotificationManager.IMPORTANCE_DEFAULT
        );
        notificationChannel.setSound(null, null);
        NotificationManager notificationManager = mContext.getSystemService(
                NotificationManager.class);
        notificationManager.createNotificationChannel(notificationChannel);

        Notification.Builder notificationBuilder = new Notification.Builder(mContext)
                .setContentTitle(mContext.getResources().getString(
                        R.string.satellite_notification_title))
                .setContentText(mContext.getResources().getString(
                        R.string.satellite_notification_summary))
                .setSmallIcon(R.drawable.ic_satellite_alt_24px)
                .setChannelId(NOTIFICATION_CHANNEL_ID)
                .setAutoCancel(true)
                .setColor(mContext.getColor(
                        com.android.internal.R.color.system_notification_accent_color))
                .setVisibility(Notification.VISIBILITY_PUBLIC);

        // Add action to invoke `What to expect` dialog of Messaging application.
        Intent intentOpenMessage = new Intent(Intent.ACTION_VIEW);
        intentOpenMessage.setData(Uri.parse("sms:"));
        // TODO : b/322733285 add putExtra to invoke "What to expect" dialog.
        PendingIntent pendingIntentOpenMessage = PendingIntent.getActivity(mContext, 0,
                intentOpenMessage, PendingIntent.FLAG_IMMUTABLE);

        Notification.Action actionOpenMessage = new Notification.Action.Builder(0,
                mContext.getResources().getString(R.string.satellite_notification_open_message),
                pendingIntentOpenMessage).build();
        notificationBuilder.addAction(actionOpenMessage);

        // Add action to invoke Satellite setting activity in Settings.
        Intent intentSatelliteSetting = new Intent(ACTION_SATELLITE_SETTING);
        PendingIntent pendingIntentSatelliteSetting = PendingIntent.getActivity(mContext, 0,
                intentSatelliteSetting, PendingIntent.FLAG_IMMUTABLE);

        Notification.Action actionOpenSatelliteSetting = new Notification.Action.Builder(null,
                mContext.getResources().getString(R.string.satellite_notification_how_it_works),
                pendingIntentSatelliteSetting).build();
        notificationBuilder.addAction(actionOpenSatelliteSetting);

        notificationManager.notifyAsUser(NOTIFICATION_TAG, NOTIFICATION_ID,
                notificationBuilder.build(), UserHandle.ALL);
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
+39 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncResult;
@@ -159,7 +160,10 @@ public class SatelliteControllerTest extends TelephonyTest {
    private static final String TEST_NEXT_SATELLITE_TOKEN = "TEST_NEXT_SATELLITE_TOKEN";
    private static final String[] EMPTY_STRING_ARRAY = {};
    private static final List<String> EMPTY_STRING_LIST = new ArrayList<>();
    private static final String SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY =
            "satellite_system_notification_done_key";
    private static final int[] ACTIVE_SUB_IDS = {SUB_ID};

    private List<Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener>>
            mCarrierConfigChangedListenerList = new ArrayList<>();

@@ -176,6 +180,7 @@ public class SatelliteControllerTest extends TelephonyTest {
    @Mock private ProvisionMetricsStats mMockProvisionMetricsStats;
    @Mock private SessionMetricsStats mMockSessionMetricsStats;
    @Mock private SubscriptionManagerService mMockSubscriptionManagerService;
    @Mock private NotificationManager mMockNotificationManager;
    private List<Integer> mIIntegerConsumerResults =  new ArrayList<>();
    @Mock private ISatelliteTransmissionUpdateCallback mStartTransmissionUpdateCallback;
    @Mock private ISatelliteTransmissionUpdateCallback mStopTransmissionUpdateCallback;
@@ -503,6 +508,13 @@ public class SatelliteControllerTest extends TelephonyTest {
        doNothing().when(mMockProvisionMetricsStats).reportProvisionMetrics();
        doNothing().when(mMockControllerMetricsStats).reportDeprovisionCount(anyInt());
        when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
        doReturn(mSST).when(mPhone).getServiceStateTracker();
        doReturn(mSST).when(mPhone2).getServiceStateTracker();
        doReturn(mServiceState).when(mSST).getServiceState();
        doReturn(Context.NOTIFICATION_SERVICE).when(mContext).getSystemServiceName(
                NotificationManager.class);
        doReturn(mMockNotificationManager).when(mContext).getSystemService(
                Context.NOTIFICATION_SERVICE);
        mSatelliteControllerUT =
                new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags);
        verify(mMockSatelliteModemInterface).registerForSatelliteProvisionStateChanged(
@@ -2869,6 +2881,33 @@ public class SatelliteControllerTest extends TelephonyTest {
        assertEquals(true, satelliteEnabledPerCarrier.get(SUB_ID1));
    }

    @Test
    public void testHandleEventServiceStateChanged() throws Exception {
        when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
        // Do nothing when the satellite is not connected
        doReturn(false).when(mServiceState).isUsingNonTerrestrialNetwork();
        sendServiceStateChangedEvent();
        processAllMessages();
        assertEquals(false,
                mSharedPreferences.getBoolean(SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY, false));
        verify(mMockNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any());

        // Check sending a system notification when the satellite is connected
        doReturn(true).when(mServiceState).isUsingNonTerrestrialNetwork();
        sendServiceStateChangedEvent();
        processAllMessages();
        verify(mMockNotificationManager, times(1)).notifyAsUser(anyString(), anyInt(), any(),
                any());
        assertEquals(true,
                mSharedPreferences.getBoolean(SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY, false));

        // Check don't display again after displayed already a system notification.
        sendServiceStateChangedEvent();
        processAllMessages();
        verify(mMockNotificationManager, times(1)).notifyAsUser(anyString(), anyInt(), any(),
                any());
    }

    private void resetSatelliteControllerUTEnabledState() {
        logd("resetSatelliteControllerUTEnabledState");
        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);