mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2024-12-22 18:47:46 +01:00
Update Wearable
- Add support for deleting dataitems - Refactoring - Update wearable-lib
This commit is contained in:
parent
4ea10d9049
commit
db013606e0
2
extern/Wearable
vendored
2
extern/Wearable
vendored
@ -1 +1 @@
|
||||
Subproject commit 5c24adaa3928de68167ce31c0fa5b9b1a3256677
|
||||
Subproject commit 666ef2a8628b1c76701a2d5f138d4fd90751b5e9
|
@ -17,6 +17,7 @@
|
||||
package org.microg.gms.common;
|
||||
|
||||
import android.os.IInterface;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
@ -25,17 +26,22 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class MultiListenerProxy<T extends IInterface> implements InvocationHandler {
|
||||
private static final String TAG = "GmsMultiListener";
|
||||
|
||||
public static <T extends IInterface> T get(Class<T> tClass, final Collection<T> listeners) {
|
||||
return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class[]{tClass}, new MultiListenerProxy<T>(listeners));
|
||||
return get(tClass, new CollectionListenerPool<T>(listeners));
|
||||
}
|
||||
|
||||
private final Collection<T> listeners;
|
||||
public static <T extends IInterface> T get(Class<T> tClass, final ListenerPool<T> listenerPool) {
|
||||
return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class[]{tClass}, new MultiListenerProxy<T>(listenerPool));
|
||||
}
|
||||
|
||||
private MultiListenerProxy(Collection<T> listeners) {
|
||||
private final ListenerPool<T> listeners;
|
||||
|
||||
private MultiListenerProxy(ListenerPool<T> listeners) {
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
@ -44,14 +50,175 @@ public class MultiListenerProxy<T extends IInterface> implements InvocationHandl
|
||||
for (T listener : new HashSet<T>(listeners)) {
|
||||
try {
|
||||
method.invoke(listener, args);
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, e);
|
||||
listeners.remove(listener);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.w(TAG, e.getTargetException());
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static abstract class ListenerPool<T> implements Collection<T> {
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T object) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> collection) {
|
||||
for (Object o : collection) {
|
||||
if (!contains(o)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> collection) {
|
||||
boolean x = true;
|
||||
for (Object o : collection) {
|
||||
if (!remove(o)) x = false;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <T1> T1[] toArray(T1[] array) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class CollectionListenerPool<T> extends ListenerPool<T> {
|
||||
|
||||
private Collection<T> listeners;
|
||||
|
||||
public CollectionListenerPool(Collection<T> listeners) {
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return listeners.contains(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return listeners.isEmpty();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return listeners.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object object) {
|
||||
return listeners.remove(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return listeners.size();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiCollectionListenerPool<T> extends ListenerPool<T> {
|
||||
private Collection<? extends Collection<T>> multiCol;
|
||||
|
||||
public MultiCollectionListenerPool(Collection<? extends Collection<T>> multiCol) {
|
||||
this.multiCol = multiCol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for (Collection<T> ts : multiCol) {
|
||||
ts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
for (Collection<T> ts : multiCol) {
|
||||
if (ts.contains(object)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (Collection<T> ts : multiCol) {
|
||||
if (!ts.isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
final Iterator<? extends Collection<T>> interMed = multiCol.iterator();
|
||||
return new Iterator<T>() {
|
||||
private Iterator<T> med;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while ((med == null || !med.hasNext()) && interMed.hasNext()) {
|
||||
med = interMed.next().iterator();
|
||||
}
|
||||
return med != null && med.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
while (med == null || !med.hasNext()) {
|
||||
med = interMed.next().iterator();
|
||||
}
|
||||
return med.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
med.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object object) {
|
||||
for (Collection<T> ts : multiCol) {
|
||||
if (ts.remove(object)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int sum = 0;
|
||||
for (Collection<T> ts : multiCol) {
|
||||
sum += ts.size();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2016 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.wearable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClockworkNodePreferences {
|
||||
|
||||
private static final String CLOCKWORK_NODE_PREFERENCES = "cw_node";
|
||||
private static final String CLOCKWORK_NODE_PREFERENCE_NODE_ID = "node_id";
|
||||
private static final String CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK = "nextSeqIdBlock";
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private static long seqIdBlock;
|
||||
private static long seqIdInBlock = -1;
|
||||
|
||||
private Context context;
|
||||
|
||||
public ClockworkNodePreferences(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public String getLocalNodeId() {
|
||||
SharedPreferences preferences = context.getSharedPreferences(CLOCKWORK_NODE_PREFERENCES, Context.MODE_PRIVATE);
|
||||
String nodeId = preferences.getString(CLOCKWORK_NODE_PREFERENCE_NODE_ID, null);
|
||||
if (nodeId == null) {
|
||||
nodeId = UUID.randomUUID().toString();
|
||||
preferences.edit().putString(CLOCKWORK_NODE_PREFERENCE_NODE_ID, nodeId).apply();
|
||||
}
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public long getNextSeqId() {
|
||||
synchronized (lock) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(CLOCKWORK_NODE_PREFERENCES, Context.MODE_PRIVATE);
|
||||
if (seqIdInBlock < 0) seqIdInBlock = 1000;
|
||||
if (seqIdInBlock >= 1000) {
|
||||
seqIdBlock = preferences.getLong(CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK, 100);
|
||||
preferences.edit().putLong(CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK, seqIdBlock + seqIdInBlock).apply();
|
||||
seqIdInBlock = 0;
|
||||
}
|
||||
return seqIdBlock + seqIdInBlock++;
|
||||
}
|
||||
}
|
||||
}
|
@ -58,7 +58,7 @@ public class MessageHandler extends ServerMessageListener {
|
||||
.networkId(networkId)
|
||||
.peerAndroidId(androidId)
|
||||
.unknown4(3)
|
||||
.unknown5(1)
|
||||
.peerVersion(1)
|
||||
.build());
|
||||
this.wearable = wearable;
|
||||
this.thisNodeId = config.nodeId;
|
||||
@ -83,6 +83,12 @@ public class MessageHandler extends ServerMessageListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
wearable.onDisconnectReceived(getConnection(), thisNodeId, getRemoteConnect());
|
||||
super.onDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetAsset(SetAsset setAsset) {
|
||||
Log.d(TAG, "onSetAsset: " + setAsset);
|
||||
@ -132,8 +138,7 @@ public class MessageHandler extends ServerMessageListener {
|
||||
@Override
|
||||
public void onRpcRequest(Request rpcRequest) {
|
||||
Log.d(TAG, "onRpcRequest: " + rpcRequest);
|
||||
if (TextUtils.isEmpty(rpcRequest.targetNodeId)) {
|
||||
// TODO: That's probably not how it should go!
|
||||
if (TextUtils.isEmpty(rpcRequest.targetNodeId) || rpcRequest.targetNodeId.equals(thisNodeId)) {
|
||||
MessageEventParcelable messageEvent = new MessageEventParcelable();
|
||||
messageEvent.data = rpcRequest.rawData != null ? rpcRequest.rawData.toByteArray() : null;
|
||||
messageEvent.path = rpcRequest.path;
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.wearable;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.wearable.ConnectionConfiguration;
|
||||
|
||||
import org.microg.wearable.SocketWearableConnection;
|
||||
import org.microg.wearable.WearableConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
class NetworkConnectionThread extends Thread {
|
||||
private static final String TAG = "GmsWearNetConnThr";
|
||||
private static final int WEAR_TCP_PORT = 5601;
|
||||
|
||||
private ConnectionConfiguration config;
|
||||
private ServerSocket socket;
|
||||
private MessageHandler handler;
|
||||
private WearableConnection wearableConnection;
|
||||
|
||||
public NetworkConnectionThread(WearableImpl wearable, ConnectionConfiguration config) {
|
||||
this.config = config;
|
||||
this.handler = new MessageHandler(wearable, config);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
public WearableConnection getWearableConnection() {
|
||||
return wearableConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
socket = new ServerSocket(WEAR_TCP_PORT);
|
||||
Log.d(TAG, "Listening for connections on TCP :" + WEAR_TCP_PORT);
|
||||
Socket accepted = socket.accept();
|
||||
(wearableConnection = new SocketWearableConnection(accepted, handler)).run();
|
||||
Log.d(TAG, "Connection terminated, me too");
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@ import android.text.TextUtils;
|
||||
|
||||
import com.google.android.gms.wearable.Asset;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
@ -34,8 +36,11 @@ public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String[] GDIBHAP_FIELDS = new String[]{"dataitems_id", "packageName", "signatureDigest", "host", "path", "seqId", "deleted", "sourceNode", "data", "timestampMs", "assetsPresent", "assetname", "assets_digest", "v1SourceNode", "v1SeqId"};
|
||||
private static final int VERSION = 9;
|
||||
|
||||
private ClockworkNodePreferences clockworkNodePreferences;
|
||||
|
||||
public NodeDatabaseHelper(Context context) {
|
||||
super(context, DB_NAME, null, VERSION);
|
||||
clockworkNodePreferences = new ClockworkNodePreferences(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -198,27 +203,32 @@ public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
return getReadableDatabase().query("dataItemsAndAssets", GDIBHAP_FIELDS, selection, new String[]{nodeId, Long.toString(seqId)}, null, null, "seqId", null);
|
||||
}
|
||||
|
||||
public synchronized int deleteDataItems(String packageName, String signatureDigest, String host, String path) {
|
||||
public synchronized List<DataItemRecord> deleteDataItems(String packageName, String signatureDigest, String host, String path) {
|
||||
List<DataItemRecord> updated = new ArrayList<DataItemRecord>();
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
Cursor cursor = getDataItemsByHostAndPath(db, packageName, signatureDigest, host, path);
|
||||
int n = 0;
|
||||
while (cursor.moveToNext()) {
|
||||
DataItemRecord record = DataItemRecord.fromCursor(cursor);
|
||||
record.deleted = true;
|
||||
record.assetsAreReady = true;
|
||||
record.dataItem.data = null;
|
||||
record.seqId = clockworkNodePreferences.getNextSeqId();
|
||||
record.v1SeqId = record.seqId;
|
||||
updateRecord(db, cursor.getString(0), record);
|
||||
n++;
|
||||
updated.add(record);
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
return n;
|
||||
return updated;
|
||||
}
|
||||
|
||||
public long getCurrentSeqId(String sourceNode) {
|
||||
if (TextUtils.isEmpty(sourceNode)) return 1;
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
return getCurrentSeqId(getReadableDatabase(), sourceNode);
|
||||
}
|
||||
|
||||
private long getCurrentSeqId(SQLiteDatabase db, String sourceNode) {
|
||||
Cursor cursor = db.query("dataItemsAndAssets", new String[]{"seqId"}, "sourceNode=?", new String[]{sourceNode}, null, null, "seqId DESC", "1");
|
||||
long res = 1;
|
||||
if (cursor != null) {
|
||||
|
@ -17,10 +17,10 @@
|
||||
package org.microg.gms.wearable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
@ -37,6 +37,7 @@ 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.Utils;
|
||||
import org.microg.wearable.SocketConnectionThread;
|
||||
import org.microg.wearable.WearableConnection;
|
||||
import org.microg.wearable.proto.AckAsset;
|
||||
import org.microg.wearable.proto.AppKey;
|
||||
@ -54,12 +55,14 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import okio.ByteString;
|
||||
|
||||
@ -67,48 +70,28 @@ public class WearableImpl {
|
||||
|
||||
private static final String TAG = "GmsWear";
|
||||
|
||||
private static final String CLOCKWORK_NODE_PREFERENCES = "cw_node";
|
||||
private static final String CLOCKWORK_NODE_PREFERENCE_NODE_ID = "node_id";
|
||||
private static final String CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK = "nextSeqIdBlock";
|
||||
private static final int WEAR_TCP_PORT = 5601;
|
||||
|
||||
private final Context context;
|
||||
private final NodeDatabaseHelper nodeDatabase;
|
||||
private final ConfigurationDatabaseHelper configDatabase;
|
||||
private final Set<IWearableListener> listeners = new HashSet<IWearableListener>();
|
||||
private final Map<String, List<IWearableListener>> listeners = new HashMap<String, List<IWearableListener>>();
|
||||
private final Set<Node> connectedNodes = new HashSet<Node>();
|
||||
private final Set<WearableConnection> activeConnections = new HashSet<WearableConnection>();
|
||||
private NetworkConnectionThread nct;
|
||||
private SocketConnectionThread sct;
|
||||
private ConnectionConfiguration[] configurations;
|
||||
private boolean configurationsUpdated = false;
|
||||
|
||||
private long seqIdBlock;
|
||||
private long seqIdInBlock = -1;
|
||||
private ClockworkNodePreferences clockworkNodePreferences;
|
||||
|
||||
public WearableImpl(Context context, NodeDatabaseHelper nodeDatabase, ConfigurationDatabaseHelper configDatabase) {
|
||||
this.context = context;
|
||||
this.nodeDatabase = nodeDatabase;
|
||||
this.configDatabase = configDatabase;
|
||||
this.clockworkNodePreferences = new ClockworkNodePreferences(context);
|
||||
}
|
||||
|
||||
public String getLocalNodeId() {
|
||||
SharedPreferences preferences = context.getSharedPreferences(CLOCKWORK_NODE_PREFERENCES, Context.MODE_PRIVATE);
|
||||
String nodeId = preferences.getString(CLOCKWORK_NODE_PREFERENCE_NODE_ID, null);
|
||||
if (nodeId == null) {
|
||||
nodeId = UUID.randomUUID().toString();
|
||||
preferences.edit().putString(CLOCKWORK_NODE_PREFERENCE_NODE_ID, nodeId).apply();
|
||||
}
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
private synchronized long getNextSeqId() {
|
||||
SharedPreferences preferences = context.getSharedPreferences(CLOCKWORK_NODE_PREFERENCES, Context.MODE_PRIVATE);
|
||||
if (seqIdInBlock < 0) seqIdInBlock = 1000;
|
||||
if (seqIdInBlock >= 1000) {
|
||||
seqIdBlock = preferences.getLong(CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK, 100);
|
||||
preferences.edit().putLong(CLOCKWORK_NODE_PREFERENCE_NEXT_SEQ_ID_BLOCK, seqIdBlock + seqIdInBlock).apply();
|
||||
seqIdInBlock = 0;
|
||||
}
|
||||
return seqIdBlock + seqIdInBlock++;
|
||||
return clockworkNodePreferences.getLocalNodeId();
|
||||
}
|
||||
|
||||
public DataItemRecord putDataItem(String packageName, String signatureDigest, String source, DataItemInternal dataItem) {
|
||||
@ -118,7 +101,7 @@ public class WearableImpl {
|
||||
record.deleted = false;
|
||||
record.source = source;
|
||||
record.dataItem = dataItem;
|
||||
record.v1SeqId = getNextSeqId();
|
||||
record.v1SeqId = clockworkNodePreferences.getNextSeqId();
|
||||
if (record.source.equals(getLocalNodeId())) record.seqId = record.v1SeqId;
|
||||
nodeDatabase.putRecord(record);
|
||||
return record;
|
||||
@ -127,7 +110,11 @@ public class WearableImpl {
|
||||
public DataItemRecord putDataItem(DataItemRecord record) {
|
||||
nodeDatabase.putRecord(record);
|
||||
try {
|
||||
getAllListeners().onDataChanged(getDataItemsByUri(record.dataItem.uri, record.packageName));
|
||||
if (listeners.containsKey(record.packageName)) {
|
||||
MultiListenerProxy.get(IWearableListener.class, listeners.get(record.packageName)).onDataChanged(getDataItemForRecord(record));
|
||||
} else {
|
||||
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
@ -272,7 +259,7 @@ public class WearableImpl {
|
||||
RootMessage announceMessage = new RootMessage.Builder().setAsset(new SetAsset.Builder()
|
||||
.digest(asset.getDigest())
|
||||
.appkeys(new AppKeys(Collections.singletonList(new AppKey(record.packageName, record.signatureDigest))))
|
||||
.build()).unknown13(true).build();
|
||||
.build()).hasAsset(true).build();
|
||||
connection.writeMessage(announceMessage);
|
||||
File assetFile = createAssetFile(asset.getDigest());
|
||||
String fileName = calculateDigest(announceMessage.toByteArray());
|
||||
@ -346,6 +333,16 @@ public class WearableImpl {
|
||||
onPeerConnected(new NodeParcelable(connect.id, connect.name));
|
||||
}
|
||||
|
||||
public void onDisconnectReceived(WearableConnection connection, String nodeId, Connect connect) {
|
||||
for (ConnectionConfiguration config : getConfigurations()) {
|
||||
if (config.nodeId.equals(nodeId)) {
|
||||
config.connected = false;
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Removing connection from list of open connections: " + connection);
|
||||
activeConnections.remove(connection);
|
||||
onPeerDisconnected(new NodeParcelable(connect.id, connect.name));
|
||||
}
|
||||
|
||||
public List<NodeParcelable> getConnectedNodesParcelableList() {
|
||||
List<NodeParcelable> nodes = new ArrayList<NodeParcelable>();
|
||||
@ -356,7 +353,7 @@ public class WearableImpl {
|
||||
}
|
||||
|
||||
public IWearableListener getAllListeners() {
|
||||
return MultiListenerProxy.get(IWearableListener.class, listeners);
|
||||
return MultiListenerProxy.get(IWearableListener.class, new MultiListenerProxy.MultiCollectionListenerPool<IWearableListener>(listeners.values()));
|
||||
}
|
||||
|
||||
public void onPeerConnected(NodeParcelable node) {
|
||||
@ -369,6 +366,16 @@ public class WearableImpl {
|
||||
addConnectedNode(node);
|
||||
}
|
||||
|
||||
public void onPeerDisconnected(NodeParcelable node) {
|
||||
Log.d(TAG, "onPeerDisconnected: " + node);
|
||||
try {
|
||||
getAllListeners().onPeerDisconnected(node);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
removeConnectedNode(node.getId());
|
||||
}
|
||||
|
||||
public void onConnectedNodes(List<NodeParcelable> nodes) {
|
||||
Log.d(TAG, "onConnectedNodes: " + nodes);
|
||||
try {
|
||||
@ -406,7 +413,13 @@ public class WearableImpl {
|
||||
}
|
||||
|
||||
public DataHolder getDataItemsByUri(Uri uri, String packageName) {
|
||||
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolderByHostAndPath(packageName, PackageUtils.firstSignatureDigest(context, packageName), uri.getHost(), uri.getPath());
|
||||
String firstSignature;
|
||||
try {
|
||||
firstSignature = PackageUtils.firstSignatureDigest(context, packageName);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolderByHostAndPath(packageName, firstSignature, uri.getHost(), uri.getPath());
|
||||
while (dataHolderItems.moveToNext()) {
|
||||
Log.d(TAG, "getDataItems[]: path=" + Uri.parse(dataHolderItems.getString(1)).getPath());
|
||||
}
|
||||
@ -415,30 +428,45 @@ public class WearableImpl {
|
||||
return DataHolder.fromCursor(dataHolderItems, 0, null);
|
||||
}
|
||||
|
||||
public void addListener(IWearableListener listener) {
|
||||
listeners.add(listener);
|
||||
public DataHolder getDataItemForRecord(DataItemRecord record) {
|
||||
Cursor dataHolderItems = nodeDatabase.getDataItemsForDataHolderByHostAndPath(record.packageName, record.signatureDigest, record.dataItem.uri.getHost(), record.dataItem.uri.getPath());
|
||||
while (dataHolderItems.moveToNext()) {
|
||||
Log.d(TAG, "getDataItems[]: path=" + Uri.parse(dataHolderItems.getString(1)).getPath());
|
||||
}
|
||||
dataHolderItems.moveToFirst();
|
||||
dataHolderItems.moveToPrevious();
|
||||
return DataHolder.fromCursor(dataHolderItems, 0, null);
|
||||
}
|
||||
|
||||
public synchronized void addListener(String packageName, IWearableListener listener) {
|
||||
if (!listeners.containsKey(packageName)) {
|
||||
listeners.put(packageName, new ArrayList<IWearableListener>());
|
||||
}
|
||||
listeners.get(packageName).add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(IWearableListener listener) {
|
||||
listeners.add(listener);
|
||||
for (List<IWearableListener> list : listeners.values()) {
|
||||
list.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableConnection(String name) {
|
||||
configDatabase.setEnabledState(name, true);
|
||||
configurationsUpdated = true;
|
||||
if (name.equals("server") && nct == null) {
|
||||
(nct = new NetworkConnectionThread(this, configDatabase.getConfiguration(name))).start();
|
||||
if (name.equals("server") && sct == null) {
|
||||
(sct = SocketConnectionThread.serverListen(WEAR_TCP_PORT, new MessageHandler(this, configDatabase.getConfiguration(name)))).start();
|
||||
}
|
||||
}
|
||||
|
||||
public void disableConnection(String name) {
|
||||
configDatabase.setEnabledState(name, false);
|
||||
configurationsUpdated = true;
|
||||
if (name.equals("server") && nct != null) {
|
||||
activeConnections.remove(nct.getWearableConnection());
|
||||
nct.close();
|
||||
nct.interrupt();
|
||||
nct = null;
|
||||
if (name.equals("server") && sct != null) {
|
||||
activeConnections.remove(sct.getWearableConnection());
|
||||
sct.close();
|
||||
sct.interrupt();
|
||||
sct = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +483,11 @@ public class WearableImpl {
|
||||
}
|
||||
|
||||
public int deleteDataItems(Uri uri, String packageName) {
|
||||
return nodeDatabase.deleteDataItems(packageName, PackageUtils.firstSignatureDigest(context, packageName), uri.getHost(), uri.getPath());
|
||||
List<DataItemRecord> records = nodeDatabase.deleteDataItems(packageName, PackageUtils.firstSignatureDigest(context, packageName), uri.getHost(), uri.getPath());
|
||||
for (DataItemRecord record : records) {
|
||||
syncRecordToAll(record);
|
||||
}
|
||||
return records.size();
|
||||
}
|
||||
|
||||
public void sendMessageReceived(MessageEventParcelable messageEvent) {
|
||||
|
@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
@ -113,7 +114,7 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
public void addListener(IWearableCallbacks callbacks, AddListenerRequest request) throws RemoteException {
|
||||
Log.d(TAG, "addListener[nyp]: " + request);
|
||||
if (request.listener != null) {
|
||||
wearable.addListener(request.listener);
|
||||
wearable.addListener(packageName, request.listener);
|
||||
}
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user