mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2024-10-19 20:09:37 +02:00
Improvements to Wear code for emulator
This commit is contained in:
parent
6ba9bbb03b
commit
3c5e68404b
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2017 microG Project Team
|
* Copyright (C) 2013-2019 microG Project Team
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -66,7 +66,6 @@ public class RemoteListenerProxy<T extends IInterface> implements ServiceConnect
|
|||||||
if (!connecting) Log.d(TAG, "Could not connect to: " + intent);
|
if (!connecting) Log.d(TAG, "Could not connect to: " + intent);
|
||||||
return connecting;
|
return connecting;
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Unable to resolve: " + searchIntent);
|
|
||||||
return false;
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
@ -91,11 +90,17 @@ public class RemoteListenerProxy<T extends IInterface> implements ServiceConnect
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
remote = service;
|
remote = service;
|
||||||
if (!waiting.isEmpty()) {
|
if (!waiting.isEmpty()) {
|
||||||
for (Runnable runnable : waiting) {
|
try {
|
||||||
runnable.run();
|
for (Runnable runnable : waiting) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
waiting.clear();
|
waiting.clear();
|
||||||
context.unbindService(RemoteListenerProxy.this);
|
try {
|
||||||
|
context.unbindService(RemoteListenerProxy.this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
connecting = false;
|
connecting = false;
|
||||||
remote = null;
|
remote = null;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2017 microG Project Team
|
* Copyright (C) 2013-2019 microG Project Team
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,14 +16,15 @@
|
|||||||
|
|
||||||
package org.microg.gms.wearable;
|
package org.microg.gms.wearable;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -37,7 +38,6 @@ import com.google.android.gms.wearable.internal.MessageEventParcelable;
|
|||||||
import com.google.android.gms.wearable.internal.NodeParcelable;
|
import com.google.android.gms.wearable.internal.NodeParcelable;
|
||||||
import com.google.android.gms.wearable.internal.PutDataRequest;
|
import com.google.android.gms.wearable.internal.PutDataRequest;
|
||||||
|
|
||||||
import org.microg.gms.common.MultiListenerProxy;
|
|
||||||
import org.microg.gms.common.PackageUtils;
|
import org.microg.gms.common.PackageUtils;
|
||||||
import org.microg.gms.common.RemoteListenerProxy;
|
import org.microg.gms.common.RemoteListenerProxy;
|
||||||
import org.microg.gms.common.Utils;
|
import org.microg.gms.common.Utils;
|
||||||
@ -52,6 +52,7 @@ import org.microg.wearable.proto.FilePiece;
|
|||||||
import org.microg.wearable.proto.Request;
|
import org.microg.wearable.proto.Request;
|
||||||
import org.microg.wearable.proto.RootMessage;
|
import org.microg.wearable.proto.RootMessage;
|
||||||
import org.microg.wearable.proto.SetAsset;
|
import org.microg.wearable.proto.SetAsset;
|
||||||
|
import org.microg.wearable.proto.SetDataItem;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -70,8 +71,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import okio.ByteString;
|
import okio.ByteString;
|
||||||
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
|
|
||||||
public class WearableImpl {
|
public class WearableImpl {
|
||||||
|
|
||||||
private static final String TAG = "GmsWear";
|
private static final String TAG = "GmsWear";
|
||||||
@ -81,7 +80,7 @@ public class WearableImpl {
|
|||||||
private final Context context;
|
private final Context context;
|
||||||
private final NodeDatabaseHelper nodeDatabase;
|
private final NodeDatabaseHelper nodeDatabase;
|
||||||
private final ConfigurationDatabaseHelper configDatabase;
|
private final ConfigurationDatabaseHelper configDatabase;
|
||||||
private final Map<String, List<IWearableListener>> listeners = new HashMap<String, List<IWearableListener>>();
|
private final Map<String, List<ListenerInfo>> listeners = new HashMap<String, List<ListenerInfo>>();
|
||||||
private final Set<Node> connectedNodes = new HashSet<Node>();
|
private final Set<Node> connectedNodes = new HashSet<Node>();
|
||||||
private final Map<String, WearableConnection> activeConnections = new HashMap<String, WearableConnection>();
|
private final Map<String, WearableConnection> activeConnections = new HashMap<String, WearableConnection>();
|
||||||
private RpcHelper rpcHelper;
|
private RpcHelper rpcHelper;
|
||||||
@ -130,12 +129,10 @@ public class WearableImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
Intent intent = new Intent("com.google.android.gms.wearable.DATA_CHANGED");
|
||||||
getListener(record.packageName, "com.google.android.gms.wearable.DATA_CHANGED", record.dataItem.uri)
|
intent.setPackage(record.packageName);
|
||||||
.onDataChanged(record.toEventDataHolder());
|
intent.setData(record.dataItem.uri);
|
||||||
} catch (RemoteException e) {
|
invokeListeners(intent, listener -> listener.onDataChanged(record.toEventDataHolder()));
|
||||||
Log.w(TAG, e);
|
|
||||||
}
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,8 +244,7 @@ public class WearableImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void syncRecordToAll(DataItemRecord record) {
|
void syncRecordToAll(DataItemRecord record) {
|
||||||
Log.d(TAG, "Syncing record " + record + " over " + activeConnections.size() + " connections.");
|
|
||||||
for (String nodeId : new ArrayList<String>(activeConnections.keySet())) {
|
for (String nodeId : new ArrayList<String>(activeConnections.keySet())) {
|
||||||
syncRecordToPeer(nodeId, record);
|
syncRecordToPeer(nodeId, record);
|
||||||
}
|
}
|
||||||
@ -256,47 +252,45 @@ public class WearableImpl {
|
|||||||
|
|
||||||
private boolean syncRecordToPeer(String nodeId, DataItemRecord record) {
|
private boolean syncRecordToPeer(String nodeId, DataItemRecord record) {
|
||||||
for (Asset asset : record.dataItem.getAssets().values()) {
|
for (Asset asset : record.dataItem.getAssets().values()) {
|
||||||
syncAssetToPeer(nodeId, record, asset);
|
try {
|
||||||
|
syncAssetToPeer(nodeId, record, asset);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Could not sync asset " + asset + " for " + nodeId + " and " + record, e);
|
||||||
|
closeConnection(nodeId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Sync over to " + nodeId + ": " + record);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().setDataItem(record.toSetDataItem()).build());
|
SetDataItem item = record.toSetDataItem();
|
||||||
} catch (IOException e) {
|
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().setDataItem(item).build());
|
||||||
closeConnection(nodeId);
|
} catch (Exception e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
|
closeConnection(nodeId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncAssetToPeer(String nodeId, DataItemRecord record, Asset asset) {
|
private void syncAssetToPeer(String nodeId, DataItemRecord record, Asset asset) throws IOException {
|
||||||
try {
|
RootMessage announceMessage = new RootMessage.Builder().setAsset(new SetAsset.Builder()
|
||||||
Log.d(TAG, "Sync over to " + nodeId + ": " + asset);
|
.digest(asset.getDigest())
|
||||||
RootMessage announceMessage = new RootMessage.Builder().setAsset(new SetAsset.Builder()
|
.appkeys(new AppKeys(Collections.singletonList(new AppKey(record.packageName, record.signatureDigest))))
|
||||||
.digest(asset.getDigest())
|
.build()).hasAsset(true).build();
|
||||||
.appkeys(new AppKeys(Collections.singletonList(new AppKey(record.packageName, record.signatureDigest))))
|
activeConnections.get(nodeId).writeMessage(announceMessage);
|
||||||
.build()).hasAsset(true).build();
|
File assetFile = createAssetFile(asset.getDigest());
|
||||||
activeConnections.get(nodeId).writeMessage(announceMessage);
|
String fileName = calculateDigest(announceMessage.toByteArray());
|
||||||
File assetFile = createAssetFile(asset.getDigest());
|
FileInputStream fis = new FileInputStream(assetFile);
|
||||||
String fileName = calculateDigest(announceMessage.toByteArray());
|
byte[] arr = new byte[12215];
|
||||||
FileInputStream fis = new FileInputStream(assetFile);
|
ByteString lastPiece = null;
|
||||||
byte[] arr = new byte[12215];
|
int c = 0;
|
||||||
ByteString lastPiece = null;
|
while ((c = fis.read(arr)) > 0) {
|
||||||
int c = 0;
|
if (lastPiece != null) {
|
||||||
while ((c = fis.read(arr)) > 0) {
|
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, false, lastPiece, null)).build());
|
||||||
if (lastPiece != null) {
|
|
||||||
Log.d(TAG, "Sync over to " + nodeId + ": Asset piece for fileName " + fileName + ": " + lastPiece);
|
|
||||||
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, false, lastPiece, null)).build());
|
|
||||||
}
|
|
||||||
lastPiece = ByteString.of(arr, 0, c);
|
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Sync over to " + nodeId + ": Last asset piece for fileName " + fileName + ": " + lastPiece);
|
lastPiece = ByteString.of(arr, 0, c);
|
||||||
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, true, lastPiece, asset.getDigest())).build());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
closeConnection(nodeId);
|
|
||||||
}
|
}
|
||||||
|
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, true, lastPiece, asset.getDigest())).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAssetToDatabase(Asset asset, List<AppKey> appKeys) {
|
public void addAssetToDatabase(Asset asset, List<AppKey> appKeys) {
|
||||||
@ -394,37 +388,59 @@ public class WearableImpl {
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWearableListener getAllListeners() {
|
interface ListenerInvoker {
|
||||||
return MultiListenerProxy.get(IWearableListener.class, new MultiListenerProxy.MultiCollectionListenerPool<IWearableListener>(listeners.values()));
|
void invoke(IWearableListener listener) throws RemoteException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeListeners(@Nullable Intent intent, ListenerInvoker invoker) {
|
||||||
|
for (String packageName : new ArrayList<>(listeners.keySet())) {
|
||||||
|
List<ListenerInfo> listeners = this.listeners.get(packageName);
|
||||||
|
if (listeners == null) continue;
|
||||||
|
for (int i = 0; i < listeners.size(); i++) {
|
||||||
|
boolean filterMatched = false;
|
||||||
|
if (intent != null) {
|
||||||
|
for (IntentFilter filter : listeners.get(i).filters) {
|
||||||
|
filterMatched |= filter.match(context.getContentResolver(), intent, false, TAG) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filterMatched || listeners.get(i).filters.length == 0) {
|
||||||
|
try {
|
||||||
|
invoker.invoke(listeners.get(i).listener);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Registered listener at package " + packageName + " failed, removing.");
|
||||||
|
listeners.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (listeners.isEmpty()) {
|
||||||
|
this.listeners.remove(packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (intent != null) {
|
||||||
|
try {
|
||||||
|
invoker.invoke(RemoteListenerProxy.get(context, intent, IWearableListener.class, "com.google.android.gms.wearable.BIND_LISTENER"));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Failed to deliver message received to " + intent, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPeerConnected(NodeParcelable node) {
|
public void onPeerConnected(NodeParcelable node) {
|
||||||
Log.d(TAG, "onPeerConnected: " + node);
|
Log.d(TAG, "onPeerConnected: " + node);
|
||||||
try {
|
invokeListeners(null, listener -> listener.onPeerConnected(node));
|
||||||
getAllListeners().onPeerConnected(node);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
}
|
|
||||||
addConnectedNode(node);
|
addConnectedNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPeerDisconnected(NodeParcelable node) {
|
public void onPeerDisconnected(NodeParcelable node) {
|
||||||
Log.d(TAG, "onPeerDisconnected: " + node);
|
Log.d(TAG, "onPeerDisconnected: " + node);
|
||||||
try {
|
invokeListeners(null, listener -> listener.onPeerDisconnected(node));
|
||||||
getAllListeners().onPeerDisconnected(node);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
}
|
|
||||||
removeConnectedNode(node.getId());
|
removeConnectedNode(node.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onConnectedNodes(List<NodeParcelable> nodes) {
|
public void onConnectedNodes(List<NodeParcelable> nodes) {
|
||||||
Log.d(TAG, "onConnectedNodes: " + nodes);
|
Log.d(TAG, "onConnectedNodes: " + nodes);
|
||||||
try {
|
invokeListeners(null, listener -> listener.onConnectedNodes(nodes));
|
||||||
getAllListeners().onConnectedNodes(nodes);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataItemRecord putData(PutDataRequest request, String packageName) {
|
public DataItemRecord putData(PutDataRequest request, String packageName) {
|
||||||
@ -444,11 +460,6 @@ public class WearableImpl {
|
|||||||
|
|
||||||
public DataHolder getDataItemsAsHolder(String packageName) {
|
public DataHolder getDataItemsAsHolder(String packageName) {
|
||||||
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolder(packageName, PackageUtils.firstSignatureDigest(context, packageName));
|
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolder(packageName, PackageUtils.firstSignatureDigest(context, packageName));
|
||||||
while (dataHolderItems.moveToNext()) {
|
|
||||||
Log.d(TAG, "getDataItems[]: path=" + Uri.parse(dataHolderItems.getString(1)).getPath());
|
|
||||||
}
|
|
||||||
dataHolderItems.moveToFirst();
|
|
||||||
dataHolderItems.moveToPrevious();
|
|
||||||
return new DataHolder(dataHolderItems, 0, null);
|
return new DataHolder(dataHolderItems, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,40 +478,26 @@ public class WearableImpl {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolderByHostAndPath(packageName, firstSignature, fixHost(uri.getHost(), false), uri.getPath());
|
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolderByHostAndPath(packageName, firstSignature, fixHost(uri.getHost(), false), uri.getPath());
|
||||||
maybeDebugCursor("getDataItems",dataHolderItems);
|
|
||||||
dataHolderItems.moveToFirst();
|
|
||||||
dataHolderItems.moveToPrevious();
|
|
||||||
DataHolder dataHolder = new DataHolder(dataHolderItems, 0, null);
|
DataHolder dataHolder = new DataHolder(dataHolderItems, 0, null);
|
||||||
Log.d(TAG, "Returning data holder of size " + dataHolder.getCount() + " for query " + uri);
|
Log.d(TAG, "Returning data holder of size " + dataHolder.getCount() + " for query " + uri);
|
||||||
return dataHolder;
|
return dataHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(11)
|
public synchronized void addListener(String packageName, IWearableListener listener, IntentFilter[] filters) {
|
||||||
private void maybeDebugCursor(String what, Cursor cursor) {
|
|
||||||
if (SDK_INT >= 11) {
|
|
||||||
int j = 0;
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
|
||||||
if (cursor.getType(i) == Cursor.FIELD_TYPE_STRING) {
|
|
||||||
Log.d(TAG, what+"[" + j + "]: " + cursor.getColumnName(i) + "=" + cursor.getString(i));
|
|
||||||
}
|
|
||||||
if (cursor.getType(i) == Cursor.FIELD_TYPE_INTEGER)
|
|
||||||
Log.d(TAG, what+"[" + j + "]: " + cursor.getColumnName(i) + "=" + cursor.getLong(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void addListener(String packageName, IWearableListener listener) {
|
|
||||||
if (!listeners.containsKey(packageName)) {
|
if (!listeners.containsKey(packageName)) {
|
||||||
listeners.put(packageName, new ArrayList<IWearableListener>());
|
listeners.put(packageName, new ArrayList<ListenerInfo>());
|
||||||
}
|
}
|
||||||
listeners.get(packageName).add(listener);
|
listeners.get(packageName).add(new ListenerInfo(listener, filters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(IWearableListener listener) {
|
public void removeListener(IWearableListener listener) {
|
||||||
for (List<IWearableListener> list : listeners.values()) {
|
for (List<ListenerInfo> list : listeners.values()) {
|
||||||
list.remove(listener);
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
if (list.get(i).listener.equals(listener)) {
|
||||||
|
list.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,12 +543,10 @@ public class WearableImpl {
|
|||||||
|
|
||||||
public void sendMessageReceived(String packageName, MessageEventParcelable messageEvent) {
|
public void sendMessageReceived(String packageName, MessageEventParcelable messageEvent) {
|
||||||
Log.d(TAG, "onMessageReceived: " + messageEvent);
|
Log.d(TAG, "onMessageReceived: " + messageEvent);
|
||||||
try {
|
Intent intent = new Intent("com.google.android.gms.wearable.MESSAGE_RECEIVED");
|
||||||
getListener(packageName, "com.google.android.gms.wearable.MESSAGE_RECEIVED", Uri.parse("wear://" + getLocalNodeId() + "/" + messageEvent.getPath()))
|
intent.setPackage(packageName);
|
||||||
.onMessageReceived(messageEvent);
|
intent.setData(Uri.parse("wear://" + getLocalNodeId() + "/" + messageEvent.getPath()));
|
||||||
} catch (RemoteException e) {
|
invokeListeners(intent, listener -> listener.onMessageReceived(messageEvent));
|
||||||
Log.w(TAG, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataItemRecord getDataItemByUri(Uri uri, String packageName) {
|
public DataItemRecord getDataItemByUri(Uri uri, String packageName) {
|
||||||
@ -568,17 +563,11 @@ public class WearableImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IWearableListener getListener(String packageName, String action, Uri uri) {
|
private IWearableListener getListener(String packageName, String action, Uri uri) {
|
||||||
synchronized (this) {
|
Intent intent = new Intent(action);
|
||||||
List<IWearableListener> l = new ArrayList<IWearableListener>(listeners.containsKey(packageName) ? listeners.get(packageName) : Collections.<IWearableListener>emptyList());
|
intent.setPackage(packageName);
|
||||||
|
intent.setData(uri);
|
||||||
|
|
||||||
Intent intent = new Intent(action);
|
return RemoteListenerProxy.get(context, intent, IWearableListener.class, "com.google.android.gms.wearable.BIND_LISTENER");
|
||||||
intent.setPackage(packageName);
|
|
||||||
intent.setData(uri);
|
|
||||||
|
|
||||||
l.add(RemoteListenerProxy.get(context, intent, IWearableListener.class, "com.google.android.gms.wearable.BIND_LISTENER"));
|
|
||||||
|
|
||||||
return MultiListenerProxy.get(IWearableListener.class, l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeConnection(String nodeId) {
|
private void closeConnection(String nodeId) {
|
||||||
@ -594,7 +583,7 @@ public class WearableImpl {
|
|||||||
}
|
}
|
||||||
activeConnections.remove(nodeId);
|
activeConnections.remove(nodeId);
|
||||||
for (ConnectionConfiguration config : getConfigurations()) {
|
for (ConnectionConfiguration config : getConfigurations()) {
|
||||||
if (config.nodeId.equals(nodeId) || config.peerNodeId.equals(nodeId)) {
|
if (nodeId.equals(config.nodeId) || nodeId.equals(config.peerNodeId)) {
|
||||||
config.connected = false;
|
config.connected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -631,4 +620,14 @@ public class WearableImpl {
|
|||||||
public void stop() {
|
public void stop() {
|
||||||
this.networkHandler.getLooper().quit();
|
this.networkHandler.getLooper().quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ListenerInfo {
|
||||||
|
private IWearableListener listener;
|
||||||
|
private IntentFilter[] filters;
|
||||||
|
|
||||||
|
private ListenerInfo(IWearableListener listener, IntentFilter[] filters) {
|
||||||
|
this.listener = listener;
|
||||||
|
this.filters = filters;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2017 microG Project Team
|
* Copyright (C) 2013-2019 microG Project Team
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -29,8 +29,11 @@ import com.google.android.gms.common.api.Status;
|
|||||||
import com.google.android.gms.wearable.Asset;
|
import com.google.android.gms.wearable.Asset;
|
||||||
import com.google.android.gms.wearable.ConnectionConfiguration;
|
import com.google.android.gms.wearable.ConnectionConfiguration;
|
||||||
import com.google.android.gms.wearable.internal.AddListenerRequest;
|
import com.google.android.gms.wearable.internal.AddListenerRequest;
|
||||||
|
import com.google.android.gms.wearable.internal.AddLocalCapabilityResponse;
|
||||||
import com.google.android.gms.wearable.internal.AncsNotificationParcelable;
|
import com.google.android.gms.wearable.internal.AncsNotificationParcelable;
|
||||||
|
import com.google.android.gms.wearable.internal.CapabilityInfoParcelable;
|
||||||
import com.google.android.gms.wearable.internal.DeleteDataItemsResponse;
|
import com.google.android.gms.wearable.internal.DeleteDataItemsResponse;
|
||||||
|
import com.google.android.gms.wearable.internal.GetCapabilityResponse;
|
||||||
import com.google.android.gms.wearable.internal.GetCloudSyncSettingResponse;
|
import com.google.android.gms.wearable.internal.GetCloudSyncSettingResponse;
|
||||||
import com.google.android.gms.wearable.internal.GetConfigResponse;
|
import com.google.android.gms.wearable.internal.GetConfigResponse;
|
||||||
import com.google.android.gms.wearable.internal.GetConfigsResponse;
|
import com.google.android.gms.wearable.internal.GetConfigsResponse;
|
||||||
@ -45,9 +48,13 @@ import com.google.android.gms.wearable.internal.NodeParcelable;
|
|||||||
import com.google.android.gms.wearable.internal.PutDataRequest;
|
import com.google.android.gms.wearable.internal.PutDataRequest;
|
||||||
import com.google.android.gms.wearable.internal.PutDataResponse;
|
import com.google.android.gms.wearable.internal.PutDataResponse;
|
||||||
import com.google.android.gms.wearable.internal.RemoveListenerRequest;
|
import com.google.android.gms.wearable.internal.RemoveListenerRequest;
|
||||||
|
import com.google.android.gms.wearable.internal.RemoveLocalCapabilityResponse;
|
||||||
import com.google.android.gms.wearable.internal.SendMessageResponse;
|
import com.google.android.gms.wearable.internal.SendMessageResponse;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class WearableServiceImpl extends IWearableService.Stub {
|
public class WearableServiceImpl extends IWearableService.Stub {
|
||||||
private static final String TAG = "GmsWearSvcImpl";
|
private static final String TAG = "GmsWearSvcImpl";
|
||||||
@ -56,11 +63,13 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
|||||||
private final String packageName;
|
private final String packageName;
|
||||||
private final WearableImpl wearable;
|
private final WearableImpl wearable;
|
||||||
private final Handler mainHandler;
|
private final Handler mainHandler;
|
||||||
|
private final CapabilityManager capabilities;
|
||||||
|
|
||||||
public WearableServiceImpl(Context context, WearableImpl wearable, String packageName) {
|
public WearableServiceImpl(Context context, WearableImpl wearable, String packageName) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.wearable = wearable;
|
this.wearable = wearable;
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
|
this.capabilities = new CapabilityManager(context, wearable, packageName);
|
||||||
this.mainHandler = new Handler(context.getMainLooper());
|
this.mainHandler = new Handler(context.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,8 +200,11 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public void deleteDataItemsWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException {
|
public void deleteDataItemsWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException {
|
||||||
Log.d(TAG, "deleteDataItems: " + uri);
|
Log.d(TAG, "deleteDataItems: " + uri);
|
||||||
postMain(callbacks, () -> {
|
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
|
||||||
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
|
@Override
|
||||||
|
public void run(IWearableCallbacks callbacks) throws RemoteException {
|
||||||
|
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,29 +301,49 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getConnectedCapability(IWearableCallbacks callbacks, String s1, int i) throws RemoteException {
|
public void getConnectedCapability(IWearableCallbacks callbacks, String capability, int nodeFilter) throws RemoteException {
|
||||||
Log.d(TAG, "unimplemented Method: getConnectedCapability " + s1 + ", " + i);
|
Log.d(TAG, "unimplemented Method: getConnectedCapability " + capability + ", " + nodeFilter);
|
||||||
|
postMain(callbacks, () -> {
|
||||||
|
List<NodeParcelable> nodes = new ArrayList<>();
|
||||||
|
for (String host : capabilities.getNodesForCapability(capability)) {
|
||||||
|
nodes.add(new NodeParcelable(host, host));
|
||||||
|
}
|
||||||
|
CapabilityInfoParcelable capabilityInfo = new CapabilityInfoParcelable(capability, nodes);
|
||||||
|
callbacks.onGetCapabilityResponse(new GetCapabilityResponse(0, capabilityInfo));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getConnectedCapaibilties(IWearableCallbacks callbacks, int i) throws RemoteException {
|
public void getConnectedCapaibilties(IWearableCallbacks callbacks, int nodeFilter) throws RemoteException {
|
||||||
Log.d(TAG, "unimplemented Method: getConnectedCapaibilties: " + i);
|
Log.d(TAG, "unimplemented Method: getConnectedCapaibilties: " + nodeFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLocalCapability(IWearableCallbacks callbacks, String cap) throws RemoteException {
|
public void addLocalCapability(IWearableCallbacks callbacks, String capability) throws RemoteException {
|
||||||
Log.d(TAG, "unimplemented Method: addLocalCapability: " + cap);
|
Log.d(TAG, "unimplemented Method: addLocalCapability: " + capability);
|
||||||
|
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
|
||||||
|
@Override
|
||||||
|
public void run(IWearableCallbacks callbacks) throws RemoteException {
|
||||||
|
callbacks.onAddLocalCapabilityResponse(new AddLocalCapabilityResponse(capabilities.add(capability)));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLocalCapability(IWearableCallbacks callbacks, String cap) throws RemoteException {
|
public void removeLocalCapability(IWearableCallbacks callbacks, String capability) throws RemoteException {
|
||||||
Log.d(TAG, "unimplemented Method: removeLocalCapability: " + cap);
|
Log.d(TAG, "unimplemented Method: removeLocalCapability: " + capability);
|
||||||
|
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
|
||||||
|
@Override
|
||||||
|
public void run(IWearableCallbacks callbacks) throws RemoteException {
|
||||||
|
callbacks.onRemoveLocalCapabilityResponse(new RemoveLocalCapabilityResponse(capabilities.remove(capability)));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(IWearableCallbacks callbacks, AddListenerRequest request) throws RemoteException {
|
public void addListener(IWearableCallbacks callbacks, AddListenerRequest request) throws RemoteException {
|
||||||
if (request.listener != null) {
|
if (request.listener != null) {
|
||||||
wearable.addListener(packageName, request.listener);
|
wearable.addListener(packageName, request.listener, request.intentFilters);
|
||||||
}
|
}
|
||||||
callbacks.onStatus(Status.SUCCESS);
|
callbacks.onStatus(Status.SUCCESS);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user