Skip to content

Commit

Permalink
Update Wearable
Browse files Browse the repository at this point in the history
- Add support for deleting dataitems
- Refactoring
- Update wearable-lib
  • Loading branch information
mar-v-in committed May 18, 2016
1 parent 4ea10d9 commit db01360
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 129 deletions.
2 changes: 1 addition & 1 deletion extern/Wearable
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,17 +26,22 @@
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 final ListenerPool<T> listeners;

private MultiListenerProxy(Collection<T> listeners) {
private MultiListenerProxy(ListenerPool<T> listeners) {
this.listeners = listeners;
}

Expand All @@ -44,14 +50,175 @@ public Object invoke(Object proxy, Method method, Object[] args) {
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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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++;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private MessageHandler(WearableImpl wearable, ConnectionConfiguration config, St
.networkId(networkId)
.peerAndroidId(androidId)
.unknown4(3)
.unknown5(1)
.peerVersion(1)
.build());
this.wearable = wearable;
this.thisNodeId = config.nodeId;
Expand All @@ -83,6 +83,12 @@ public void onConnect(Connect connect) {
}
}

@Override
public void onDisconnected() {
wearable.onDisconnectReceived(getConnection(), thisNodeId, getRemoteConnect());
super.onDisconnected();
}

@Override
public void onSetAsset(SetAsset setAsset) {
Log.d(TAG, "onSetAsset: " + setAsset);
Expand Down Expand Up @@ -132,8 +138,7 @@ public void onSetDataItem(SetDataItem setDataItem) {
@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;
Expand Down

This file was deleted.

Loading

0 comments on commit db01360

Please sign in to comment.