Merge "Use Activity Context for CDM ListView Adapter" into sc-dev am: 0bf57f5302
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13677874 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ieeca3fc0b7887285adf64c6b4bb4612836bfd9e3
This commit is contained in:
@@ -41,13 +41,13 @@
|
|||||||
android:supportsRtl="true">
|
android:supportsRtl="true">
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".DeviceDiscoveryService"
|
android:name=".CompanionDeviceDiscoveryService"
|
||||||
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
|
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".DeviceChooserActivity"
|
android:name=".CompanionDeviceActivity"
|
||||||
android:theme="@style/ChooserActivity"
|
android:theme="@style/ChooserActivity"
|
||||||
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
|
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE
|
|||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.companion.AssociationRequest;
|
import android.companion.AssociationRequest;
|
||||||
@@ -31,41 +32,52 @@ import android.companion.CompanionDeviceManager;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.companiondevicemanager.DeviceDiscoveryService.DeviceFilterPair;
|
import com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DeviceFilterPair;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
|
|
||||||
public class DeviceChooserActivity extends Activity {
|
public class CompanionDeviceActivity extends Activity {
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final String LOG_TAG = "DeviceChooserActivity";
|
private static final String LOG_TAG = CompanionDeviceActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
static CompanionDeviceActivity sInstance;
|
||||||
|
|
||||||
View mLoadingIndicator = null;
|
View mLoadingIndicator = null;
|
||||||
ListView mDeviceListView;
|
ListView mDeviceListView;
|
||||||
private View mPairButton;
|
private View mPairButton;
|
||||||
private View mCancelButton;
|
private View mCancelButton;
|
||||||
|
|
||||||
|
DevicesAdapter mDevicesAdapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (DEBUG) Log.i(LOG_TAG, "Started with intent " + getIntent());
|
Log.i(LOG_TAG, "Starting UI for " + getService().mRequest);
|
||||||
|
|
||||||
if (getService().mDevicesFound.isEmpty()) {
|
if (getService().mDevicesFound.isEmpty()) {
|
||||||
Log.e(LOG_TAG, "About to show UI, but no devices to show");
|
Log.e(LOG_TAG, "About to show UI, but no devices to show");
|
||||||
}
|
}
|
||||||
|
|
||||||
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||||
|
sInstance = this;
|
||||||
|
|
||||||
String deviceProfile = getRequest().getDeviceProfile();
|
String deviceProfile = getRequest().getDeviceProfile();
|
||||||
String profilePrivacyDisclaimer = emptyIfNull(getRequest()
|
String profilePrivacyDisclaimer = emptyIfNull(getRequest()
|
||||||
@@ -96,17 +108,14 @@ public class DeviceChooserActivity extends Activity {
|
|||||||
profileName,
|
profileName,
|
||||||
getCallingAppName()), 0));
|
getCallingAppName()), 0));
|
||||||
mDeviceListView = findViewById(R.id.device_list);
|
mDeviceListView = findViewById(R.id.device_list);
|
||||||
final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
|
mDevicesAdapter = new DevicesAdapter();
|
||||||
mDeviceListView.setAdapter(adapter);
|
mDeviceListView.setAdapter(mDevicesAdapter);
|
||||||
mDeviceListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
mDeviceListView.setOnItemClickListener((adapterView, view, pos, l) -> {
|
||||||
@Override
|
getService().mSelectedDevice =
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
|
(DeviceFilterPair) adapterView.getItemAtPosition(pos);
|
||||||
getService().mSelectedDevice =
|
mDevicesAdapter.notifyDataSetChanged();
|
||||||
(DeviceFilterPair) adapterView.getItemAtPosition(pos);
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
adapter.registerDataSetObserver(new DataSetObserver() {
|
mDevicesAdapter.registerDataSetObserver(new DataSetObserver() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged() {
|
public void onChanged() {
|
||||||
onSelectionUpdate();
|
onSelectionUpdate();
|
||||||
@@ -133,6 +142,12 @@ public class DeviceChooserActivity extends Activity {
|
|||||||
mCancelButton.setOnClickListener(v -> cancel());
|
mCancelButton.setOnClickListener(v -> cancel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void notifyDevicesChanged() {
|
||||||
|
if (sInstance != null && !sInstance.isFinishing()) {
|
||||||
|
sInstance.mDevicesAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private AssociationRequest getRequest() {
|
private AssociationRequest getRequest() {
|
||||||
return getService().mRequest;
|
return getService().mRequest;
|
||||||
}
|
}
|
||||||
@@ -156,6 +171,7 @@ public class DeviceChooserActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void cancel() {
|
private void cancel() {
|
||||||
|
Log.i(LOG_TAG, "cancel()");
|
||||||
getService().onCancel();
|
getService().onCancel();
|
||||||
setResult(RESULT_CANCELED);
|
setResult(RESULT_CANCELED);
|
||||||
finish();
|
finish();
|
||||||
@@ -170,6 +186,14 @@ public class DeviceChooserActivity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (sInstance == this) {
|
||||||
|
sInstance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private CharSequence getCallingAppName() {
|
private CharSequence getCallingAppName() {
|
||||||
try {
|
try {
|
||||||
final PackageManager packageManager = getPackageManager();
|
final PackageManager packageManager = getPackageManager();
|
||||||
@@ -217,15 +241,91 @@ public class DeviceChooserActivity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeviceDiscoveryService getService() {
|
private CompanionDeviceDiscoveryService getService() {
|
||||||
return DeviceDiscoveryService.sInstance;
|
return CompanionDeviceDiscoveryService.sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onDeviceConfirmed(DeviceFilterPair selectedDevice) {
|
protected void onDeviceConfirmed(DeviceFilterPair selectedDevice) {
|
||||||
|
Log.i(LOG_TAG, "onDeviceConfirmed(selectedDevice = " + selectedDevice + ")");
|
||||||
getService().onDeviceSelected(
|
getService().onDeviceSelected(
|
||||||
getCallingPackage(), getDeviceMacAddress(selectedDevice.device));
|
getCallingPackage(), getDeviceMacAddress(selectedDevice.device));
|
||||||
setResult(RESULT_OK,
|
setResult(RESULT_OK,
|
||||||
new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice.device));
|
new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice.device));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DevicesAdapter extends BaseAdapter {
|
||||||
|
private final Drawable mBluetoothIcon = icon(android.R.drawable.stat_sys_data_bluetooth);
|
||||||
|
private final Drawable mWifiIcon = icon(com.android.internal.R.drawable.ic_wifi_signal_3);
|
||||||
|
|
||||||
|
private SparseArray<Integer> mColors = new SparseArray();
|
||||||
|
|
||||||
|
private Drawable icon(int drawableRes) {
|
||||||
|
Drawable icon = getResources().getDrawable(drawableRes, null);
|
||||||
|
icon.setTint(Color.DKGRAY);
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(
|
||||||
|
int position,
|
||||||
|
@Nullable View convertView,
|
||||||
|
@NonNull ViewGroup parent) {
|
||||||
|
TextView view = convertView instanceof TextView
|
||||||
|
? (TextView) convertView
|
||||||
|
: newView();
|
||||||
|
bind(view, getItem(position));
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bind(TextView textView, DeviceFilterPair device) {
|
||||||
|
textView.setText(device.getDisplayName());
|
||||||
|
textView.setBackgroundColor(
|
||||||
|
device.equals(getService().mSelectedDevice)
|
||||||
|
? getColor(android.R.attr.colorControlHighlight)
|
||||||
|
: Color.TRANSPARENT);
|
||||||
|
textView.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
device.device instanceof android.net.wifi.ScanResult
|
||||||
|
? mWifiIcon
|
||||||
|
: mBluetoothIcon,
|
||||||
|
null, null, null);
|
||||||
|
textView.getCompoundDrawables()[0].setTint(getColor(android.R.attr.colorForeground));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextView newView() {
|
||||||
|
final TextView textView = new TextView(CompanionDeviceActivity.this);
|
||||||
|
textView.setTextColor(getColor(android.R.attr.colorForeground));
|
||||||
|
final int padding = CompanionDeviceActivity.getPadding(getResources());
|
||||||
|
textView.setPadding(padding, padding, padding, padding);
|
||||||
|
textView.setCompoundDrawablePadding(padding);
|
||||||
|
return textView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getColor(int colorAttr) {
|
||||||
|
if (mColors.contains(colorAttr)) {
|
||||||
|
return mColors.get(colorAttr);
|
||||||
|
}
|
||||||
|
TypedValue typedValue = new TypedValue();
|
||||||
|
TypedArray a = obtainStyledAttributes(typedValue.data, new int[] { colorAttr });
|
||||||
|
int result = a.getColor(0, 0);
|
||||||
|
a.recycle();
|
||||||
|
mColors.put(colorAttr, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return getService().mDevicesFound.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceFilterPair getItem(int position) {
|
||||||
|
return getService().mDevicesFound.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -50,9 +50,6 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -60,12 +57,6 @@ import android.os.Parcelable;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.internal.infra.AndroidFuture;
|
import com.android.internal.infra.AndroidFuture;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
@@ -76,14 +67,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class DeviceDiscoveryService extends Service {
|
public class CompanionDeviceDiscoveryService extends Service {
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final String LOG_TAG = "DeviceDiscoveryService";
|
private static final String LOG_TAG = CompanionDeviceDiscoveryService.class.getSimpleName();
|
||||||
|
|
||||||
private static final long SCAN_TIMEOUT = 20000;
|
private static final long SCAN_TIMEOUT = 20000;
|
||||||
|
|
||||||
static DeviceDiscoveryService sInstance;
|
static CompanionDeviceDiscoveryService sInstance;
|
||||||
|
|
||||||
private BluetoothManager mBluetoothManager;
|
private BluetoothManager mBluetoothManager;
|
||||||
private BluetoothAdapter mBluetoothAdapter;
|
private BluetoothAdapter mBluetoothAdapter;
|
||||||
@@ -102,12 +93,12 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
AssociationRequest mRequest;
|
AssociationRequest mRequest;
|
||||||
List<DeviceFilterPair> mDevicesFound;
|
List<DeviceFilterPair> mDevicesFound;
|
||||||
DeviceFilterPair mSelectedDevice;
|
DeviceFilterPair mSelectedDevice;
|
||||||
DevicesAdapter mDevicesAdapter;
|
|
||||||
IFindDeviceCallback mFindCallback;
|
IFindDeviceCallback mFindCallback;
|
||||||
|
|
||||||
AndroidFuture<Association> mServiceCallback;
|
AndroidFuture<Association> mServiceCallback;
|
||||||
boolean mIsScanning = false;
|
boolean mIsScanning = false;
|
||||||
@Nullable DeviceChooserActivity mActivity = null;
|
@Nullable
|
||||||
|
CompanionDeviceActivity mActivity = null;
|
||||||
|
|
||||||
private final ICompanionDeviceDiscoveryService mBinder =
|
private final ICompanionDeviceDiscoveryService mBinder =
|
||||||
new ICompanionDeviceDiscoveryService.Stub() {
|
new ICompanionDeviceDiscoveryService.Stub() {
|
||||||
@@ -125,7 +116,8 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
mFindCallback = findCallback;
|
mFindCallback = findCallback;
|
||||||
mServiceCallback = serviceCallback;
|
mServiceCallback = serviceCallback;
|
||||||
Handler.getMain().sendMessage(obtainMessage(
|
Handler.getMain().sendMessage(obtainMessage(
|
||||||
DeviceDiscoveryService::startDiscovery, DeviceDiscoveryService.this, request));
|
CompanionDeviceDiscoveryService::startDiscovery,
|
||||||
|
CompanionDeviceDiscoveryService.this, request));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,7 +143,6 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
mWifiManager = getSystemService(WifiManager.class);
|
mWifiManager = getSystemService(WifiManager.class);
|
||||||
|
|
||||||
mDevicesFound = new ArrayList<>();
|
mDevicesFound = new ArrayList<>();
|
||||||
mDevicesAdapter = new DevicesAdapter();
|
|
||||||
|
|
||||||
sInstance = this;
|
sInstance = this;
|
||||||
}
|
}
|
||||||
@@ -165,7 +156,8 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class);
|
mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class);
|
||||||
mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class);
|
mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class);
|
||||||
mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLeDeviceFilter.class);
|
mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLeDeviceFilter.class);
|
||||||
mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLeDeviceFilter::getScanFilter);
|
mBLEScanFilters
|
||||||
|
= CollectionUtils.map(mBLEFilters, BluetoothLeDeviceFilter::getScanFilter);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
} else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
|
} else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
|
||||||
@@ -223,7 +215,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
}
|
}
|
||||||
mIsScanning = true;
|
mIsScanning = true;
|
||||||
Handler.getMain().sendMessageDelayed(
|
Handler.getMain().sendMessageDelayed(
|
||||||
obtainMessage(DeviceDiscoveryService::stopScan, this),
|
obtainMessage(CompanionDeviceDiscoveryService::stopScan, this),
|
||||||
SCAN_TIMEOUT);
|
SCAN_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +229,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
stopScan();
|
stopScan();
|
||||||
mDevicesFound.clear();
|
mDevicesFound.clear();
|
||||||
mSelectedDevice = null;
|
mSelectedDevice = null;
|
||||||
mDevicesAdapter.notifyDataSetChanged();
|
CompanionDeviceActivity.notifyDevicesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -252,7 +244,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
if (!mIsScanning) return;
|
if (!mIsScanning) return;
|
||||||
mIsScanning = false;
|
mIsScanning = false;
|
||||||
|
|
||||||
DeviceChooserActivity activity = mActivity;
|
CompanionDeviceActivity activity = mActivity;
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
if (activity.mDeviceListView != null) {
|
if (activity.mDeviceListView != null) {
|
||||||
activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
|
activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
|
||||||
@@ -276,7 +268,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
if (device == null) return;
|
if (device == null) return;
|
||||||
|
|
||||||
Handler.getMain().sendMessage(obtainMessage(
|
Handler.getMain().sendMessage(obtainMessage(
|
||||||
DeviceDiscoveryService::onDeviceFoundMainThread, this, device));
|
CompanionDeviceDiscoveryService::onDeviceFoundMainThread, this, device));
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
@@ -292,7 +284,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
onReadyToShowUI();
|
onReadyToShowUI();
|
||||||
}
|
}
|
||||||
mDevicesFound.add(device);
|
mDevicesFound.add(device);
|
||||||
mDevicesAdapter.notifyDataSetChanged();
|
CompanionDeviceActivity.notifyDevicesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO also, on timeout -> call onFailure
|
//TODO also, on timeout -> call onFailure
|
||||||
@@ -300,7 +292,7 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
try {
|
try {
|
||||||
mFindCallback.onSuccess(PendingIntent.getActivity(
|
mFindCallback.onSuccess(PendingIntent.getActivity(
|
||||||
this, 0,
|
this, 0,
|
||||||
new Intent(this, DeviceChooserActivity.class),
|
new Intent(this, CompanionDeviceActivity.class),
|
||||||
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
|
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
|
||||||
| PendingIntent.FLAG_IMMUTABLE));
|
| PendingIntent.FLAG_IMMUTABLE));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -311,13 +303,13 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
private void onDeviceLost(@Nullable DeviceFilterPair device) {
|
private void onDeviceLost(@Nullable DeviceFilterPair device) {
|
||||||
Log.i(LOG_TAG, "Lost device " + device.getDisplayName());
|
Log.i(LOG_TAG, "Lost device " + device.getDisplayName());
|
||||||
Handler.getMain().sendMessage(obtainMessage(
|
Handler.getMain().sendMessage(obtainMessage(
|
||||||
DeviceDiscoveryService::onDeviceLostMainThread, this, device));
|
CompanionDeviceDiscoveryService::onDeviceLostMainThread, this, device));
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
void onDeviceLostMainThread(@Nullable DeviceFilterPair device) {
|
void onDeviceLostMainThread(@Nullable DeviceFilterPair device) {
|
||||||
mDevicesFound.remove(device);
|
mDevicesFound.remove(device);
|
||||||
mDevicesAdapter.notifyDataSetChanged();
|
CompanionDeviceActivity.notifyDevicesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDeviceSelected(String callingPackage, String deviceAddress) {
|
void onDeviceSelected(String callingPackage, String deviceAddress) {
|
||||||
@@ -331,81 +323,6 @@ public class DeviceDiscoveryService extends Service {
|
|||||||
mServiceCallback.cancel(true);
|
mServiceCallback.cancel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DevicesAdapter extends BaseAdapter {
|
|
||||||
private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
|
|
||||||
private Drawable WIFI_ICON = icon(com.android.internal.R.drawable.ic_wifi_signal_3);
|
|
||||||
|
|
||||||
private SparseArray<Integer> mColors = new SparseArray();
|
|
||||||
|
|
||||||
private Drawable icon(int drawableRes) {
|
|
||||||
Drawable icon = getResources().getDrawable(drawableRes, null);
|
|
||||||
icon.setTint(Color.DKGRAY);
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(
|
|
||||||
int position,
|
|
||||||
@Nullable View convertView,
|
|
||||||
@NonNull ViewGroup parent) {
|
|
||||||
TextView view = convertView instanceof TextView
|
|
||||||
? (TextView) convertView
|
|
||||||
: newView();
|
|
||||||
bind(view, getItem(position));
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bind(TextView textView, DeviceFilterPair device) {
|
|
||||||
textView.setText(device.getDisplayName());
|
|
||||||
textView.setBackgroundColor(
|
|
||||||
device.equals(mSelectedDevice)
|
|
||||||
? getColor(android.R.attr.colorControlHighlight)
|
|
||||||
: Color.TRANSPARENT);
|
|
||||||
textView.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
device.device instanceof android.net.wifi.ScanResult
|
|
||||||
? WIFI_ICON
|
|
||||||
: BLUETOOTH_ICON,
|
|
||||||
null, null, null);
|
|
||||||
textView.getCompoundDrawables()[0].setTint(getColor(android.R.attr.colorForeground));
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView newView() {
|
|
||||||
final TextView textView = new TextView(DeviceDiscoveryService.this);
|
|
||||||
textView.setTextColor(getColor(android.R.attr.colorForeground));
|
|
||||||
final int padding = DeviceChooserActivity.getPadding(getResources());
|
|
||||||
textView.setPadding(padding, padding, padding, padding);
|
|
||||||
textView.setCompoundDrawablePadding(padding);
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getColor(int colorAttr) {
|
|
||||||
if (mColors.contains(colorAttr)) {
|
|
||||||
return mColors.get(colorAttr);
|
|
||||||
}
|
|
||||||
TypedValue typedValue = new TypedValue();
|
|
||||||
TypedArray a = obtainStyledAttributes(typedValue.data, new int[] { colorAttr });
|
|
||||||
int result = a.getColor(0, 0);
|
|
||||||
a.recycle();
|
|
||||||
mColors.put(colorAttr, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return mDevicesFound.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeviceFilterPair getItem(int position) {
|
|
||||||
return mDevicesFound.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pair of device and a filter that matched this device if any.
|
* A pair of device and a filter that matched this device if any.
|
||||||
*
|
*
|
||||||
@@ -142,18 +142,13 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
//TODO onStop schedule unbind in 5 seconds
|
|
||||||
//TODO make sure APIs are only callable from currently focused app
|
|
||||||
//TODO schedule stopScan on activity destroy(except if configuration change)
|
|
||||||
//TODO on associate called again after configuration change -> replace old callback with new
|
|
||||||
//TODO avoid leaking calling activity in IFindDeviceCallback (see PrintManager#print for example)
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@SuppressLint("LongLogTag")
|
@SuppressLint("LongLogTag")
|
||||||
public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient {
|
public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient {
|
||||||
|
|
||||||
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
|
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
|
||||||
CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
|
CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
|
||||||
".DeviceDiscoveryService");
|
".CompanionDeviceDiscoveryService");
|
||||||
|
|
||||||
private static final long DEVICE_DISAPPEARED_TIMEOUT_MS = 10 * 1000;
|
private static final long DEVICE_DISAPPEARED_TIMEOUT_MS = 10 * 1000;
|
||||||
private static final long DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS = 10 * 60 * 1000;
|
private static final long DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS = 10 * 60 * 1000;
|
||||||
|
|||||||
Reference in New Issue
Block a user