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

Commit 568e01f1 authored by Yanting Yang's avatar Yanting Yang Committed by Android (Google) Code Review
Browse files

Merge "Integrate SliceBackgroundWorker to ConnectedDeviceSlice"

parents 675f8436 282a691a
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