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

Commit 5badd9c7 authored by Hyundo Moon's avatar Hyundo Moon Committed by Cherrypicker Worker
Browse files

Pull out an inner class HandlerForStringBuffer

This CL merges two identical inner classes into one:
- BluetoothPbapVcardManager.HandlerForStringBuffer
- BluetoothPbapSimVcardManager.HandlerForStringBuffer

And add test for it.

Bug: 237467631
Test: atest HandlerForStringBufferTest
Change-Id: I8060e2762638725d3b310c7ced1fc61c77a28198
(cherry picked from commit a4ff6857)
Merged-In: I8060e2762638725d3b310c7ced1fc61c77a28198
parent 35e73bbb
Loading
Loading
Loading
Loading
+6 −64
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@ import com.android.vcard.VCardBuilder;
import com.android.vcard.VCardConfig;
import com.android.vcard.VCardUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -386,7 +384,7 @@ public class BluetoothPbapSimVcardManager {
            composer = new BluetoothPbapSimVcardManager(context);
            buffer = new HandlerForStringBuffer(op, ownerVCard);

            if (!composer.init(SIM_URI, null, null, null) || !buffer.onInit(context)) {
            if (!composer.init(SIM_URI, null, null, null) || !buffer.init()) {
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }
            composer.moveToPosition(startPoint -1, false);
@@ -402,75 +400,19 @@ public class BluetoothPbapSimVcardManager {
                            + composer.getErrorReason() + ", count:" + count);
                    return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
                }
                buffer.onEntryCreated(vcard);
                buffer.writeVCard(vcard);
            }
        } finally {
            if (composer != null) {
                composer.terminate();
            }
            if (buffer != null) {
                buffer.onTerminate();
                buffer.terminate();
            }
        }
        return ResponseCodes.OBEX_HTTP_OK;
    }

    /**
     * Handler to emit vCards to PCE.
     */
    public static class HandlerForStringBuffer {
        private Operation operation;

        private OutputStream outputStream;

        private String phoneOwnVCard = null;

        public HandlerForStringBuffer(Operation op, String ownerVCard) {
            operation = op;
            if (ownerVCard != null) {
                phoneOwnVCard = ownerVCard;
                if (V) Log.v(TAG, "phoneOwnVCard \n " + phoneOwnVCard);
            }
        }

        private boolean write(String vCard) {
            try {
                if (vCard != null) {
                    outputStream.write(vCard.getBytes());
                    return true;
                }
            } catch (IOException e) {
                Log.e(TAG, "write outputstrem failed" + e.toString());
            }
            return false;
        }

        public boolean onInit(Context context) {
            try {
                outputStream = operation.openOutputStream();
                if (phoneOwnVCard != null) {
                    return write(phoneOwnVCard);
                }
                return true;
            } catch (IOException e) {
                Log.e(TAG, "open outputstrem failed" + e.toString());
            }
            return false;
        }

        public boolean onEntryCreated(String vcard) {
            return write(vcard);
        }

        public void onTerminate() {
            if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) {
                if (V) Log.v(TAG, "CloseStream failed!");
            } else {
                if (V) Log.v(TAG, "CloseStream ok!");
            }
        }
    }

    public static final int composeAndSendSIMPhonebookOneVcard(Context context, Operation op,
            final int offset, final boolean vcardType21, String ownerVCard,
            int orderByWhat) {
@@ -484,7 +426,7 @@ public class BluetoothPbapSimVcardManager {
        try {
            composer = new BluetoothPbapSimVcardManager(context);
            buffer = new HandlerForStringBuffer(op, ownerVCard);
            if (!composer.init(SIM_URI, null, null, null) || !buffer.onInit(context)) {
            if (!composer.init(SIM_URI, null, null, null) || !buffer.init()) {
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }
            if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) {
@@ -502,13 +444,13 @@ public class BluetoothPbapSimVcardManager {
                            + composer.getErrorReason());
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }
            buffer.onEntryCreated(vcard);
            buffer.writeVCard(vcard);
        } finally {
            if (composer != null) {
                composer.terminate();
            }
            if (buffer != null) {
                buffer.onTerminate();
                buffer.terminate();
            }
        }

+10 −78
Original line number Diff line number Diff line
@@ -62,8 +62,6 @@ import com.android.vcard.VCardComposer;
import com.android.vcard.VCardConfig;
import com.android.vcard.VCardPhoneNumberTranslationCallback;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -752,7 +750,7 @@ public class BluetoothPbapVcardManager {
            });
            buffer = new HandlerForStringBuffer(op, ownerVCard);
            Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount());
            if (!composer.init(contactIdCursor) || !buffer.onInit(mContext)) {
            if (!composer.init(contactIdCursor) || !buffer.init()) {
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }
            int idColumn = contactIdCursor.getColumnIndex(Data.CONTACT_ID);
@@ -789,7 +787,7 @@ public class BluetoothPbapVcardManager {
                    Log.v(TAG, "vCard after cleanup: " + vcard);
                }

                if (!buffer.onEntryCreated(vcard)) {
                if (!buffer.writeVCard(vcard)) {
                    // onEntryCreate() already emits error.
                    return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
                }
@@ -799,7 +797,7 @@ public class BluetoothPbapVcardManager {
                composer.terminate();
            }
            if (buffer != null) {
                buffer.onTerminate();
                buffer.terminate();
            }
        }

@@ -857,7 +855,7 @@ public class BluetoothPbapVcardManager {
            });
            buffer = new HandlerForStringBuffer(op, ownerVCard);
            Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount());
            if (!composer.init(contactIdCursor) || !buffer.onInit(mContext)) {
            if (!composer.init(contactIdCursor) || !buffer.init()) {
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }
            int idColumn = contactIdCursor.getColumnIndex(Data.CONTACT_ID);
@@ -904,7 +902,7 @@ public class BluetoothPbapVcardManager {
                        Log.v(TAG, "vCard after cleanup: " + vcard);
                    }

                    if (!buffer.onEntryCreated(vcard)) {
                    if (!buffer.writeVCard(vcard)) {
                        // onEntryCreate() already emits error.
                        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
                    }
@@ -919,7 +917,7 @@ public class BluetoothPbapVcardManager {
                composer.terminate();
            }
            if (buffer != null) {
                buffer.onTerminate();
                buffer.terminate();
            }
        }

@@ -949,7 +947,7 @@ public class BluetoothPbapVcardManager {
            composer = new BluetoothPbapCallLogComposer(mContext);
            buffer = new HandlerForStringBuffer(op, ownerVCard);
            if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null, CALLLOG_SORT_ORDER)
                    || !buffer.onInit(mContext)) {
                    || !buffer.init()) {
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
            }

@@ -982,7 +980,7 @@ public class BluetoothPbapVcardManager {
                            Log.v(TAG, "Vcard Entry:");
                            Log.v(TAG, vcard);
                        }
                        buffer.onEntryCreated(vcard);
                        buffer.writeVCard(vcard);
                    }
                } else {
                    if (vcard == null) {
@@ -994,7 +992,7 @@ public class BluetoothPbapVcardManager {
                        Log.v(TAG, "Vcard Entry:");
                        Log.v(TAG, vcard);
                    }
                    buffer.onEntryCreated(vcard);
                    buffer.writeVCard(vcard);
                }
            }
            if (needSendBody != NEED_SEND_BODY && vCardSelct) {
@@ -1005,7 +1003,7 @@ public class BluetoothPbapVcardManager {
                composer.terminate();
            }
            if (buffer != null) {
                buffer.onTerminate();
                buffer.terminate();
            }
        }

@@ -1050,72 +1048,6 @@ public class BluetoothPbapVcardManager {
        return stripedVCard;
    }

    // TODO: Merge this class with BluetoothPbapSimVcardManager.HandlerForStringBuffer
    /**
     * Handler to emit vCards to PCE.
     */
    public class HandlerForStringBuffer {
        private Operation mOperation;

        private OutputStream mOutputStream;

        private String mPhoneOwnVCard = null;

        public HandlerForStringBuffer(Operation op, String ownerVCard) {
            mOperation = op;
            if (ownerVCard != null) {
                mPhoneOwnVCard = ownerVCard;
                if (V) {
                    Log.v(TAG, "phone own number vcard:");
                }
                if (V) {
                    Log.v(TAG, mPhoneOwnVCard);
                }
            }
        }

        private boolean write(String vCard) {
            try {
                if (vCard != null) {
                    mOutputStream.write(vCard.getBytes());
                    return true;
                }
            } catch (IOException e) {
                Log.e(TAG, "write outputstrem failed" + e.toString());
            }
            return false;
        }

        public boolean onInit(Context context) {
            try {
                mOutputStream = mOperation.openOutputStream();
                if (mPhoneOwnVCard != null) {
                    return write(mPhoneOwnVCard);
                }
                return true;
            } catch (IOException e) {
                Log.e(TAG, "open outputstrem failed" + e.toString());
            }
            return false;
        }

        public boolean onEntryCreated(String vcard) {
            return write(vcard);
        }

        public void onTerminate() {
            if (!BluetoothPbapObexServer.closeStream(mOutputStream, mOperation)) {
                if (V) {
                    Log.v(TAG, "CloseStream failed!");
                }
            } else {
                if (V) {
                    Log.v(TAG, "CloseStream ok!");
                }
            }
        }
    }

    public static class VCardFilter {
        private enum FilterBit {
            //       bit  property                  onlyCheckV21  excludeForV21
+80 −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 android.util.Log;

import com.android.obex.Operation;

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

/**
 * Handler to emit vCards to PCE.
 */
public class HandlerForStringBuffer {
    private static final String TAG = "HandlerForStringBuffer";

    private final Operation mOperation;
    private final String mOwnerVCard;

    private OutputStream mOutputStream;

    public HandlerForStringBuffer(Operation op, String ownerVCard) {
        mOperation = op;
        mOwnerVCard = ownerVCard;
        if (BluetoothPbapService.VERBOSE) {
            Log.v(TAG, "ownerVCard \n " + mOwnerVCard);
        }
    }

    public boolean init() {
        try {
            mOutputStream = mOperation.openOutputStream();
            if (mOwnerVCard != null) {
                return writeVCard(mOwnerVCard);
            }
            return true;
        } catch (IOException e) {
            Log.e(TAG, "openOutputStream failed", e);
        }
        return false;
    }

    public boolean writeVCard(String vCard) {
        try {
            if (vCard != null) {
                mOutputStream.write(vCard.getBytes());
                return true;
            }
        } catch (IOException e) {
            Log.e(TAG, "write failed", e);
        }
        return false;
    }

    public void terminate() {
        boolean result = BluetoothPbapObexServer.closeStream(mOutputStream, mOperation);
        if (BluetoothPbapService.VERBOSE) {
            if (result) {
                Log.v(TAG, "closeStream succeeded!");
            } else {
                Log.v(TAG, "closeStream failed!");
            }
        }
    }
}
+128 −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 org.mockito.Mockito.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

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

import com.android.obex.Operation;

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

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

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

    @Mock
    private Operation mOperation;

    @Mock
    private OutputStream mOutputStream;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        when(mOperation.openOutputStream()).thenReturn(mOutputStream);
    }

    @Test
    public void init_withNonNullOwnerVCard_returnsTrue() throws Exception {
        String ownerVcard = "testOwnerVcard";
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);

        assertThat(buffer.init()).isTrue();
        verify(mOutputStream).write(ownerVcard.getBytes());
    }

    @Test
    public void init_withNullOwnerVCard_returnsTrue() throws Exception {
        String ownerVcard = null;
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);

        assertThat(buffer.init()).isTrue();
        verify(mOutputStream, never()).write(any());
    }

    @Test
    public void init_withIOExceptionWhenOpeningOutputStream_returnsFalse() throws Exception {
        doThrow(new IOException()).when(mOperation).openOutputStream();

        String ownerVcard = "testOwnerVcard";
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);

        assertThat(buffer.init()).isFalse();
    }

    @Test
    public void writeVCard_withNonNullOwnerVCard_returnsTrue() throws Exception {
        String ownerVcard = null;
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);
        buffer.init();

        String newVcard = "newEntryVcard";

        assertThat(buffer.writeVCard(newVcard)).isTrue();
    }

    @Test
    public void writeVCard_withNullOwnerVCard_returnsFalse() throws Exception {
        String ownerVcard = null;
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);
        buffer.init();

        String newVcard = null;

        assertThat(buffer.writeVCard(newVcard)).isFalse();
    }

    @Test
    public void writeVCard_withIOExceptionWhenWritingToStream_returnsFalse() throws Exception {
        doThrow(new IOException()).when(mOutputStream).write(any(byte[].class));
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, /*ownerVcard=*/null);
        buffer.init();

        String newVCard = "newVCard";

        assertThat(buffer.writeVCard(newVCard)).isFalse();
    }

    @Test
    public void terminate() throws Exception {
        String ownerVcard = "testOwnerVcard";
        HandlerForStringBuffer buffer = new HandlerForStringBuffer(mOperation, ownerVcard);
        buffer.init();

        buffer.terminate();

        verify(mOutputStream).close();
    }
}
 No newline at end of file