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

Commit 282a691a authored by Yanting Yang's avatar Yanting Yang
Browse files

Integrate SliceBackgroundWorker to ConnectedDeviceSlice

Bug: 114807655
Test: visual, robotest
Change-Id: I11a8f6b3d1464ec1e932e03668c462a72346565b
parent 6daa13b4
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.settings.homepage.contextualcards.slices;

import android.content.Context;
import android.net.Uri;
import android.util.Log;

import com.android.settings.bluetooth.Utils;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;

public class BluetoothUpdateWorker extends SliceBackgroundWorker implements BluetoothCallback {

    private static final String TAG = "BluetoothUpdateWorker";

    private final Context mContext;
    private final Uri mUri;
    private final LocalBluetoothManager mLocalBluetoothManager;

    public BluetoothUpdateWorker(Context context, Uri uri) {
        super(context, uri);

        mContext = context;
        mUri = uri;
        mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
    }

    @Override
    protected void onSlicePinned() {
        if (mLocalBluetoothManager == null) {
            Log.i(TAG, "onSlicePinned() Bluetooth is unsupported.");
            return;
        }
        mLocalBluetoothManager.getEventManager().registerCallback(this);
    }

    @Override
    protected void onSliceUnpinned() {
        if (mLocalBluetoothManager == null) {
            Log.i(TAG, "onSliceUnpinned() Bluetooth is unsupported.");
            return;
        }
        mLocalBluetoothManager.getEventManager().unregisterCallback(this);
    }

    @Override
    public void close() {
    }

    @Override
    public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
        notifySliceChange();
    }

    @Override
    public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
        notifySliceChange();
    }

    @Override
    public void onBluetoothStateChanged(int bluetoothState) {
        notifySliceChange();
    }

    @Override
    public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
        notifySliceChange();
    }

    @Override
    public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
            int bluetoothProfile) {
        notifySliceChange();
    }

    private void notifySliceChange() {
        mContext.getContentResolver().notifyChange(mUri, null);
    }
}
 No newline at end of file
+12 −25
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.settings.homepage.contextualcards.slices;

import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -28,7 +27,6 @@ import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;

@@ -55,10 +53,9 @@ import com.android.settingslib.core.instrumentation.Instrumentable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * TODO(b/114807655): Contextual Home Page - Connected Device
@@ -66,11 +63,7 @@ import java.util.Map;
 * Show connected device info if one is currently connected. UI for connected device should
 * match Connected Devices > Currently Connected Devices
 *
 * This Slice will show multiple currently connected devices, which includes:
 * 1) Bluetooth.
 * 2) Docks.
 * ...
 * TODO Other device types are under checking to support, will update later.
 * TODO This class will be refactor for Bluetooth connected devices only.
 */
public class ConnectedDeviceSlice implements CustomSliceable {

@@ -138,7 +131,6 @@ public class ConnectedDeviceSlice implements CustomSliceable {
                        .setAccentColor(Utils.getColorAccentDefaultColor(mContext));

        // Get row builders by connected devices, e.g. Bluetooth.
        // TODO Add other type connected devices, e.g. Docks.
        final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder(primarySliceAction);

        // Return a header with IsError flag, if no connected devices.
@@ -181,13 +173,18 @@ public class ConnectedDeviceSlice implements CustomSliceable {
    public void onNotifyChange(Intent intent) {
    }

    @Override
    public Class getBackgroundWorkerClass() {
        return BluetoothUpdateWorker.class;
    }

    @VisibleForTesting
    List<CachedBluetoothDevice> getBluetoothConnectedDevices() {
        final List<CachedBluetoothDevice> connectedBluetoothList = new ArrayList<>();

        // If Bluetooth is disable, skip to get the bluetooth devices.
        if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
            Log.d(TAG, "Cannot get Bluetooth connected devices, Bluetooth is disabled.");
            Log.i(TAG, "Cannot get Bluetooth connected devices, Bluetooth is disabled.");
            return connectedBluetoothList;
        }

@@ -195,25 +192,15 @@ public class ConnectedDeviceSlice implements CustomSliceable {
        final LocalBluetoothManager bluetoothManager =
                com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
        if (bluetoothManager == null) {
            Log.d(TAG, "Cannot get Bluetooth connected devices, Bluetooth is not supported.");
            Log.i(TAG, "Cannot get Bluetooth connected devices, Bluetooth is unsupported.");
            return connectedBluetoothList;
        }
        final Collection<CachedBluetoothDevice> cachedDevices =
                bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy();

        // Get all connected Bluetooth devices and use Map to filter duplicated Bluetooth.
        final Map<BluetoothDevice, CachedBluetoothDevice> connectedBluetoothMap = new ArrayMap<>();
        for (CachedBluetoothDevice device : cachedDevices) {
            if (device.isConnected() && !connectedBluetoothMap.containsKey(device.getDevice())) {
                connectedBluetoothMap.put(device.getDevice(), device);
            }
        }

        // Sort connected Bluetooth devices.
        connectedBluetoothList.addAll(connectedBluetoothMap.values());
        Collections.sort(connectedBluetoothList, COMPARATOR);

        return connectedBluetoothList;
        // Get connected Bluetooth devices and sort them.
        return cachedDevices.stream().filter(device -> device.isConnected()).sorted(
                COMPARATOR).collect(Collectors.toList());
    }

    @VisibleForTesting
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.settings.homepage.contextualcards.slices;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;

import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothUpdateWorkerTest {

    private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");

    private BluetoothUpdateWorker mBluetoothUpdateWorker;
    private ContentResolver mResolver;
    private Context mContext;

    @Before
    public void setUp() {
        mContext = spy(RuntimeEnvironment.application);
        mBluetoothUpdateWorker = new BluetoothUpdateWorker(mContext, URI);
        mResolver = mock(ContentResolver.class);
        doReturn(mResolver).when(mContext).getContentResolver();
    }

    @Test
    public void onAclConnectionStateChanged_shouldNotifyChange() {
        mBluetoothUpdateWorker.onAclConnectionStateChanged(null, 0);

        verify(mResolver).notifyChange(URI, null);
    }

    @Test
    public void onActiveDeviceChanged_shouldNotifyChange() {
        mBluetoothUpdateWorker.onActiveDeviceChanged(null, 0);

        verify(mResolver).notifyChange(URI, null);
    }

    @Test
    public void onBluetoothStateChanged_shouldNotifyChange() {
        mBluetoothUpdateWorker.onBluetoothStateChanged(0);

        verify(mResolver).notifyChange(URI, null);
    }

    @Test
    public void onConnectionStateChanged_shouldNotifyChange() {
        mBluetoothUpdateWorker.onConnectionStateChanged(null, 0);

        verify(mResolver).notifyChange(URI, null);
    }

    @Test
    public void onProfileConnectionStateChanged_shouldNotifyChange() {
        mBluetoothUpdateWorker.onProfileConnectionStateChanged(null, 0, 0);

        verify(mResolver).notifyChange(URI, null);
    }
}
 No newline at end of file