Integrate SliceBackgroundWorker to ConnectedDeviceSlice
Bug: 114807655 Test: visual, robotest Change-Id: I11a8f6b3d1464ec1e932e03668c462a72346565b
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@@ -18,7 +18,6 @@ package com.android.settings.homepage.contextualcards.slices;
|
|||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -28,7 +27,6 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
@@ -55,10 +53,9 @@ import com.android.settingslib.core.instrumentation.Instrumentable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO(b/114807655): Contextual Home Page - Connected Device
|
* 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
|
* Show connected device info if one is currently connected. UI for connected device should
|
||||||
* match Connected Devices > Currently Connected Devices
|
* match Connected Devices > Currently Connected Devices
|
||||||
*
|
*
|
||||||
* This Slice will show multiple currently connected devices, which includes:
|
* TODO This class will be refactor for Bluetooth connected devices only.
|
||||||
* 1) Bluetooth.
|
|
||||||
* 2) Docks.
|
|
||||||
* ...
|
|
||||||
* TODO Other device types are under checking to support, will update later.
|
|
||||||
*/
|
*/
|
||||||
public class ConnectedDeviceSlice implements CustomSliceable {
|
public class ConnectedDeviceSlice implements CustomSliceable {
|
||||||
|
|
||||||
@@ -138,7 +131,6 @@ public class ConnectedDeviceSlice implements CustomSliceable {
|
|||||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
|
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
|
||||||
|
|
||||||
// Get row builders by connected devices, e.g. Bluetooth.
|
// 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);
|
final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder(primarySliceAction);
|
||||||
|
|
||||||
// Return a header with IsError flag, if no connected devices.
|
// Return a header with IsError flag, if no connected devices.
|
||||||
@@ -181,13 +173,18 @@ public class ConnectedDeviceSlice implements CustomSliceable {
|
|||||||
public void onNotifyChange(Intent intent) {
|
public void onNotifyChange(Intent intent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getBackgroundWorkerClass() {
|
||||||
|
return BluetoothUpdateWorker.class;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
List<CachedBluetoothDevice> getBluetoothConnectedDevices() {
|
List<CachedBluetoothDevice> getBluetoothConnectedDevices() {
|
||||||
final List<CachedBluetoothDevice> connectedBluetoothList = new ArrayList<>();
|
final List<CachedBluetoothDevice> connectedBluetoothList = new ArrayList<>();
|
||||||
|
|
||||||
// If Bluetooth is disable, skip to get the bluetooth devices.
|
// If Bluetooth is disable, skip to get the bluetooth devices.
|
||||||
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
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;
|
return connectedBluetoothList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,25 +192,15 @@ public class ConnectedDeviceSlice implements CustomSliceable {
|
|||||||
final LocalBluetoothManager bluetoothManager =
|
final LocalBluetoothManager bluetoothManager =
|
||||||
com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
|
com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
|
||||||
if (bluetoothManager == null) {
|
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;
|
return connectedBluetoothList;
|
||||||
}
|
}
|
||||||
final Collection<CachedBluetoothDevice> cachedDevices =
|
final Collection<CachedBluetoothDevice> cachedDevices =
|
||||||
bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy();
|
bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy();
|
||||||
|
|
||||||
// Get all connected Bluetooth devices and use Map to filter duplicated Bluetooth.
|
// Get connected Bluetooth devices and sort them.
|
||||||
final Map<BluetoothDevice, CachedBluetoothDevice> connectedBluetoothMap = new ArrayMap<>();
|
return cachedDevices.stream().filter(device -> device.isConnected()).sorted(
|
||||||
for (CachedBluetoothDevice device : cachedDevices) {
|
COMPARATOR).collect(Collectors.toList());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user