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

Commit fff0707f authored by Hyundo Moon's avatar Hyundo Moon Committed by Android (Google) Code Review
Browse files

Merge "Add BluetoothPbapObexServerTest" into tm-qpr-dev

parents 590cbecc 6b3d7011
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import android.util.Log;

import com.android.bluetooth.Utils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.obex.HeaderSet;

import java.io.IOException;

/**
 * Proxy class for method calls to help with unit testing
@@ -63,11 +66,26 @@ public class BluetoothPbapMethodProxy {
    }

    /**
     * Return the result of {@link ContentResolver#query(Uri, String[], String, String[], String)}.
     * Proxies {@link ContentResolver#query(Uri, String[], String, String[], String)}.
     */
    public Cursor contentResolverQuery(ContentResolver contentResolver, final Uri contentUri,
            final String[] projection, final String selection, final String[] selectionArgs,
            final String sortOrder) {
        return contentResolver.query(contentUri, projection, selection, selectionArgs, sortOrder);
    }

    /**
     * Proxies {@link HeaderSet#setHeader}.
     */
    public void setHeader(HeaderSet headerSet, int headerId, Object headerValue)
            throws IOException {
        headerSet.setHeader(headerId, headerValue);
    }

    /**
     * Proxies {@link HeaderSet#getHeader}.
     */
    public Object getHeader(HeaderSet headerSet, int headerId) throws IOException {
        return headerSet.getHeader(headerId);
    }
}
+9 −5
Original line number Diff line number Diff line
@@ -223,6 +223,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {

    private PbapStateMachine mStateMachine;

    private BluetoothPbapMethodProxy mPbapMethodProxy;

    private enum ContactsType {
        TYPE_PHONEBOOK , TYPE_SIM ;
    }
@@ -251,6 +253,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        mVcardManager = new BluetoothPbapVcardManager(mContext);
        mVcardSimManager = new BluetoothPbapSimVcardManager(mContext);
        mStateMachine = stateMachine;
        mPbapMethodProxy = BluetoothPbapMethodProxy.getInstance();
    }

    @Override
@@ -260,7 +263,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        }
        notifyUpdateWakeLock();
        try {
            byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
            byte[] uuid = (byte[]) mPbapMethodProxy.getHeader(request, HeaderSet.TARGET);
            if (uuid == null) {
                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
            }
@@ -278,19 +281,19 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
                    return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
                }
            }
            reply.setHeader(HeaderSet.WHO, uuid);
            mPbapMethodProxy.setHeader(reply, HeaderSet.WHO, uuid);
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }

        try {
            byte[] remote = (byte[]) request.getHeader(HeaderSet.WHO);
            byte[] remote = (byte[]) mPbapMethodProxy.getHeader(request, HeaderSet.WHO);
            if (remote != null) {
                if (D) {
                    Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote));
                }
                reply.setHeader(HeaderSet.TARGET, remote);
                mPbapMethodProxy.setHeader(reply, HeaderSet.TARGET, remote);
            }
        } catch (IOException e) {
            Log.e(TAG, e.toString());
@@ -300,7 +303,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
        try {
            byte[] appParam = null;
            mConnAppParamValue = new AppParamValue();
            appParam = (byte[]) request.getHeader(HeaderSet.APPLICATION_PARAMETER);
            appParam = (byte[])
                    mPbapMethodProxy.getHeader(request, HeaderSet.APPLICATION_PARAMETER);
            if ((appParam != null) && !parseApplicationParameter(appParam, mConnAppParamValue)) {
                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
            }
+299 −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.bluetooth.pbap;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.os.Handler;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.obex.HeaderSet;
import com.android.obex.Operation;
import com.android.obex.ResponseCodes;

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

import java.io.IOException;
import java.io.OutputStream;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothPbapObexServerTest {

    @Mock Handler mMockHandler;
    @Mock PbapStateMachine mMockStateMachine;

    @Spy
    BluetoothPbapMethodProxy mPbapMethodProxy = BluetoothPbapMethodProxy.getInstance();

    BluetoothPbapObexServer mServer;

    // 128 bit UUID for PBAP
    private static final byte[] PBAP_TARGET_UUID = new byte[] {
            0x79,
            0x61,
            0x35,
            (byte) 0xf0,
            (byte) 0xf0,
            (byte) 0xc5,
            0x11,
            (byte) 0xd8,
            0x09,
            0x66,
            0x08,
            0x00,
            0x20,
            0x0c,
            (byte) 0x9a,
            0x66
    };

    private static final byte[] WRONG_UUID = new byte[] {
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
    };

    private static final byte[] WRONG_LENGTH_UUID = new byte[] {
            0x79,
            0x61,
            0x35,
    };

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        BluetoothPbapMethodProxy.setInstanceForTesting(mPbapMethodProxy);
        mServer = new BluetoothPbapObexServer(
                mMockHandler, InstrumentationRegistry.getTargetContext(), mMockStateMachine);
    }

    @After
    public void tearDown() throws Exception {
        BluetoothPbapMethodProxy.setInstanceForTesting(null);
    }

    @Test
    public void testOnConnect_whenUuidIsNull() {
        // Create an empty header set.
        HeaderSet request = new HeaderSet();
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE);
    }

    @Test
    public void testOnConnect_whenUuidLengthIsWrong() {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, WRONG_LENGTH_UUID);
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE);
    }

    @Test
    public void testOnConnect_whenUuidIsWrong() {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, WRONG_UUID);
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE);
    }

    @Test
    public void testOnConnect_whenIoExceptionIsThrownFromSettingWhoHeader() throws Exception {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, PBAP_TARGET_UUID);

        HeaderSet reply = new HeaderSet();
        doThrow(IOException.class).when(mPbapMethodProxy)
                .setHeader(eq(reply), eq(HeaderSet.WHO), any());

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
    }

    @Test
    public void testOnConnect_whenIoExceptionIsThrownFromSettingTargetHeader() throws Exception {
        HeaderSet request = new HeaderSet();
        byte[] whoHeader = new byte[] {0x00, 0x01, 0x02};
        request.setHeader(HeaderSet.WHO, whoHeader);
        request.setHeader(HeaderSet.TARGET, PBAP_TARGET_UUID);

        HeaderSet reply = new HeaderSet();
        doThrow(IOException.class).when(mPbapMethodProxy)
                .setHeader(eq(reply), eq(HeaderSet.TARGET), any());

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
    }

    @Test
    public void testOnConnect_whenIoExceptionIsThrownFromGettingApplicationParameterHeader()
            throws Exception {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, PBAP_TARGET_UUID);
        HeaderSet reply = new HeaderSet();

        doThrow(IOException.class).when(mPbapMethodProxy)
                .getHeader(request, HeaderSet.APPLICATION_PARAMETER);

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR);
    }

    @Test
    public void testOnConnect_whenApplicationParameterIsWrong() {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, PBAP_TARGET_UUID);
        HeaderSet reply = new HeaderSet();

        byte[] badApplicationParameter = new byte[] {0x00, 0x01, 0x02};
        request.setHeader(HeaderSet.APPLICATION_PARAMETER, badApplicationParameter);

        assertThat(mServer.onConnect(request, reply))
                .isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST);
    }

    @Test
    public void testOnConnect_success() {
        HeaderSet request = new HeaderSet();
        request.setHeader(HeaderSet.TARGET, PBAP_TARGET_UUID);
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onConnect(request, reply)).isEqualTo(ResponseCodes.OBEX_HTTP_OK);
    }

    @Test
    public void testOnDisconnect() throws Exception {
        HeaderSet request = new HeaderSet();
        HeaderSet response = new HeaderSet();

        mServer.onDisconnect(request, response);

        assertThat(response.getResponseCode()).isEqualTo(ResponseCodes.OBEX_HTTP_OK);
    }

    @Test
    public void testOnAbort() throws Exception {
        HeaderSet request = new HeaderSet();
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onAbort(request, reply)).isEqualTo(ResponseCodes.OBEX_HTTP_OK);
        assertThat(mServer.sIsAborted).isTrue();
    }

    @Test
    public void testOnPut_notSupported() {
        Operation operation = mock(Operation.class);
        assertThat(mServer.onPut(operation)).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST);
    }

    @Test
    public void testOnDelete_notSupported() {
        HeaderSet request = new HeaderSet();
        HeaderSet reply = new HeaderSet();

        assertThat(mServer.onDelete(request, reply)).isEqualTo(ResponseCodes.OBEX_HTTP_BAD_REQUEST);
    }

    @Test
    public void testOnClose() {
        mServer.onClose();
        verify(mMockStateMachine).sendMessage(PbapStateMachine.DISCONNECT);
    }

    @Test
    public void testCloseStream_success() throws Exception{
        OutputStream outputStream = mock(OutputStream.class);
        Operation operation = mock(Operation.class);

        assertThat(BluetoothPbapObexServer.closeStream(outputStream, operation)).isTrue();
        verify(outputStream).close();
        verify(operation).close();
    }

    @Test
    public void testCloseStream_failOnClosingOutputStream() throws Exception {
        OutputStream outputStream = mock(OutputStream.class);
        doThrow(IOException.class).when(outputStream).close();
        Operation operation = mock(Operation.class);

        assertThat(BluetoothPbapObexServer.closeStream(outputStream, operation)).isFalse();
    }

    @Test
    public void testCloseStream_failOnClosingOperation() throws Exception {
        OutputStream outputStream = mock(OutputStream.class);
        Operation operation = mock(Operation.class);
        doThrow(IOException.class).when(operation).close();

        assertThat(BluetoothPbapObexServer.closeStream(outputStream, operation)).isFalse();
    }

    @Test
    public void testOnAuthenticationFailure() {
        byte[] userName = {0x57, 0x68, 0x79};
        try {
            mServer.onAuthenticationFailure(userName);
        } catch (Exception ex) {
            assertWithMessage("Exception should not happen.").fail();
        }
    }

    @Test
    public void testLogHeader() throws Exception{
        HeaderSet headerSet = new HeaderSet();
        try {
            BluetoothPbapObexServer.logHeader(headerSet);
        } catch (Exception ex) {
            assertWithMessage("Exception should not happen.").fail();
        }
    }
}