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

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

Merge "Migrated unit tests and added debug messages" am: fccaace7 am: 1881e1b3

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/2034109

Change-Id: Ia2f5b819fc4b435891950570a6b60206c1c8a808
parents aec1ba04 1881e1b3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -188,6 +188,10 @@ public class KeepaliveTracker extends Handler {
     */
    private void onStartSocketKeepaliveRequested(int slotIndex, @NonNull Duration interval,
            @NonNull KeepalivePacketData packet) {
        log("onStartSocketKeepaliveRequested: slot=" + slotIndex + ", interval="
                + interval.getSeconds() + "s, src=" + packet.getSrcAddress() + ":"
                + packet.getSrcPort() + ", dst=" + packet.getDstAddress() + ":"
                + packet.getDstPort() + ", packet.length=" + packet.getPacket().length);
        if (packet instanceof NattKeepalivePacketData) {
            if (mDataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                mPhone.mCi.startNattKeepalive(mDataNetwork.getId(), packet,
@@ -216,6 +220,7 @@ public class KeepaliveTracker extends Handler {
     * @param slotIndex the hardware slot on which to stop the keepalive.
     */
    private void onStopSocketKeepaliveRequested(int slotIndex) {
        log("onStopSocketKeepaliveRequested: slot=" + slotIndex);
        int handle = getHandleForSlot(slotIndex);
        if (handle < 0) {
            loge("No slot found for stopSocketKeepalive! " + slotIndex);
@@ -271,6 +276,7 @@ public class KeepaliveTracker extends Handler {
     * @param ks Keepalive status.
     */
    private void onSocketKeepaliveStarted(int slotIndex, @NonNull KeepaliveStatus ks) {
        log("onSocketKeepaliveStarted: slot=" + slotIndex + ", keepaliveStatus=" + ks);
        switch (ks.statusCode) {
            case KeepaliveStatus.STATUS_INACTIVE:
                mNetworkAgent.sendSocketKeepaliveEvent(slotIndex,
@@ -295,6 +301,7 @@ public class KeepaliveTracker extends Handler {
     * @param ks Keepalive status.
     */
    private void onKeepaliveStatus(@NonNull KeepaliveStatus ks) {
        log("onKeepaliveStatus: " + ks);
        final KeepaliveRecord kr;
        kr = mKeepalives.get(ks.sessionHandle);

+222 −0
Original line number Diff line number Diff line
/*
 * Copyright 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.internal.telephony.data;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.net.InetAddresses;
import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
import android.net.NetworkAgent;
import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
import android.telephony.AccessNetworkConstants;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.time.Duration;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class KeepAliveTrackerTest extends TelephonyTest {

    private KeepaliveTracker mKeepaliveTrackerUT;

    @Mock
    private DataNetwork mMockedDataNetwork;

    @Mock
    private TelephonyNetworkAgent mMockedTelephonyNetworkAgent;

    private TelephonyNetworkAgentCallback mTelephonyNetworkAgentCallback;

    @Before
    public void setUp() throws Exception {
        logd("KeepAliveTrackerTest +Setup!");
        super.setUp(getClass().getSimpleName());
        replaceInstance(NetworkAgent.class, "mPreConnectedQueue",
                mMockedTelephonyNetworkAgent, new ArrayList<>());
        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .when(mMockedDataNetwork).getTransport();
        mKeepaliveTrackerUT = new KeepaliveTracker(mPhone, Looper.myLooper(), mMockedDataNetwork,
                mMockedTelephonyNetworkAgent);
        ArgumentCaptor<TelephonyNetworkAgentCallback> callbackCaptor =
                ArgumentCaptor.forClass(TelephonyNetworkAgentCallback.class);
        verify(mMockedTelephonyNetworkAgent).registerCallback(callbackCaptor.capture());
        mTelephonyNetworkAgentCallback = callbackCaptor.getValue();
        logd("KeepAliveTrackerTest -Setup!");
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    private void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception {
        final int sessionHandle = 0xF00;
        final int slotId = 3;
        final int interval = 10; // seconds
        // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
        // and check that the packet is sent to the RIL.
        KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
                InetAddresses.parseNumericAddress("1.2.3.4"),
                1234,
                InetAddresses.parseNumericAddress("8.8.8.8"),
                4500);
        mTelephonyNetworkAgentCallback.onStartSocketKeepalive(slotId, Duration.ofSeconds(interval),
                kd);
        processAllMessages();
        verify(mSimulatedCommandsVerifier, times(1))
                .startNattKeepalive(anyInt(), eq(kd), eq((int) TimeUnit.SECONDS.toMillis(interval)),
                        any(Message.class));

        Message kaStarted = mKeepaliveTrackerUT.obtainMessage(1 /*EVENT_KEEPALIVE_STARTED*/,
                slotId, 0);
        processAllMessages();
        if (useCondensedFlow) {
            // Send a singled condensed response that a keepalive have been requested and the
            // activation is completed. This flow should be used if the keepalive offload request
            // is handled by a high-priority signalling path.
            AsyncResult.forMessage(
                    kaStarted, new KeepaliveStatus(
                            sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
            kaStarted.sendToTarget();
        } else {
            // Send the sequential responses indicating first that the request was received and
            // then that the keepalive is running. This should create an active record of the
            // keepalive in keepalive tracker while permitting the status from a low priority or
            // other high-latency handler to activate the keepalive without blocking a request.
            AsyncResult.forMessage(
                    kaStarted, new KeepaliveStatus(
                            sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
            kaStarted.sendToTarget();
            Message kaRunning = mKeepaliveTrackerUT.obtainMessage(3 /*EVENT_KEEPALIVE_STATUS*/);
            AsyncResult.forMessage(
                    kaRunning, new KeepaliveStatus(
                            sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
            kaRunning.sendToTarget();
        }
        processAllMessages();

        // Verify that we can stop the connection, which checks that the record in keepalive tracker
        // has a valid mapping between slotId (from network agent) to sessionHandle (from Radio).
        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
        processAllMessages();
        verify(mSimulatedCommandsVerifier, times(1))
                .stopNattKeepalive(eq(sessionHandle), any(Message.class));

        Message kaStopped = mKeepaliveTrackerUT.obtainMessage(2 /*EVENT_KEEPALIVE_STOPPED*/,
                sessionHandle, slotId);
        AsyncResult.forMessage(kaStopped);
        kaStopped.sendToTarget();
        processAllMessages();
        // Verify that after the connection is stopped, the mapping for a Keepalive Session is
        // removed. Thus, subsequent calls to stop the same keepalive are ignored.
        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
        processAllMessages();
        // Check that the mock has not been called subsequent to the previous invocation
        // while avoiding the use of reset()
        verify(mSimulatedCommandsVerifier, times(1))
                .stopNattKeepalive(anyInt(), any(Message.class));
    }

    @Test
    public void testStartStopNattKeepalive() throws Exception {
        checkStartStopNattKeepalive(false);
    }

    @Test
    public void testStartStopNattKeepaliveCondensed() throws Exception {
        checkStartStopNattKeepalive(true);
    }

    private void checkStartNattKeepaliveFail(boolean useCondensedFlow) throws Exception {
        final int sessionHandle = 0xF00;
        final int slotId = 3;
        final int interval = 10; // seconds
        // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
        // and check that the packet is sent to the RIL.
        KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
                InetAddresses.parseNumericAddress("1.2.3.4"),
                1234,
                InetAddresses.parseNumericAddress("8.8.8.8"),
                4500);
        mTelephonyNetworkAgentCallback.onStartSocketKeepalive(slotId, Duration.ofSeconds(interval),
                kd);
        processAllMessages();
        verify(mSimulatedCommandsVerifier, times(1))
                .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));

        Message kaStarted = mKeepaliveTrackerUT.obtainMessage(1 /*EVENT_KEEPALIVE_STARTED*/,
                slotId, 0);
        processAllMessages();
        if (useCondensedFlow) {
            // Indicate in the response that the keepalive has failed.
            AsyncResult.forMessage(
                    kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED),
                    null);
            kaStarted.sendToTarget();
        } else {
            // Indicate that the keepalive is queued, and then signal a failure from the modem
            // such that a pending keepalive fails to activate.
            AsyncResult.forMessage(
                    kaStarted, new KeepaliveStatus(
                            sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
            kaStarted.sendToTarget();
            Message kaRunning = mKeepaliveTrackerUT.obtainMessage(3 /*EVENT_KEEPALIVE_STATUS*/);
            AsyncResult.forMessage(
                    kaRunning, new KeepaliveStatus(
                            sessionHandle, KeepaliveStatus.STATUS_INACTIVE), null);
            kaRunning.sendToTarget();
        }
        processAllMessages();
        // Verify that a failed connection request cannot be stopped due to no record in
        // the keepalive tracker.
        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
        processAllMessages();
        verify(mSimulatedCommandsVerifier, never()).stopNattKeepalive(anyInt(), any(Message.class));
    }

    @Test
    public void testStartNattKeepaliveFail() throws Exception {
        checkStartNattKeepaliveFail(false);
    }

    @Test
    public void testStartNattKeepaliveFailCondensed() throws Exception {
        checkStartNattKeepaliveFail(true);
    }
}