mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2024-12-22 10:37:45 +01:00
Wearable temp state
This commit is contained in:
parent
47a61d6034
commit
435b394e3a
2
extern/GmsApi
vendored
2
extern/GmsApi
vendored
@ -1 +1 @@
|
||||
Subproject commit cf2927f275c53099781dbf965acb7c7f8ed36e97
|
||||
Subproject commit 417ec2585f085c5a599e45aa9ee3b3df6239c628
|
2
extern/Wearable
vendored
2
extern/Wearable
vendored
@ -1 +1 @@
|
||||
Subproject commit 796c8b6b87d564e3bc2e5000c6d4ed348c606083
|
||||
Subproject commit 853f0382b960fcfcad8d7d3655d7963a58095069
|
@ -129,6 +129,14 @@
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name="org.microg.gms.wearable.WearableLocationService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<!-- Services Framework -->
|
||||
|
||||
<provider
|
||||
|
@ -72,6 +72,10 @@ public class ConfigurationDatabaseHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
public void putConfiguration(ConnectionConfiguration config) {
|
||||
putConfiguration(config, null);
|
||||
}
|
||||
|
||||
public void putConfiguration(ConnectionConfiguration config, String oldNodeId) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
if (config.name != null) {
|
||||
contentValues.put("name", config.name);
|
||||
@ -89,7 +93,11 @@ public class ConfigurationDatabaseHelper extends SQLiteOpenHelper {
|
||||
contentValues.put("role", config.role);
|
||||
contentValues.put("connectionEnabled", true);
|
||||
contentValues.put("nodeId", config.nodeId);
|
||||
getWritableDatabase().insert(TABLE_NAME, null, contentValues);
|
||||
if (oldNodeId == null) {
|
||||
getWritableDatabase().insert(TABLE_NAME, null, contentValues);
|
||||
} else {
|
||||
getWritableDatabase().update(TABLE_NAME, contentValues, "nodeId=?", new String[]{oldNodeId});
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectionConfiguration[] getAllConfigurations() {
|
||||
|
@ -51,4 +51,12 @@ public class DataItemInternal {
|
||||
public Map<String, Asset> getAssets() {
|
||||
return Collections.unmodifiableMap(new HashMap<String, Asset>(assets));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("DataItemInternal{");
|
||||
sb.append("uri=").append(uri);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package org.microg.gms.wearable;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.data.DataHolder;
|
||||
import com.google.android.gms.wearable.Asset;
|
||||
|
@ -44,7 +44,7 @@ import java.util.Arrays;
|
||||
public class MessageHandler extends ServerMessageListener {
|
||||
private static final String TAG = "GmsWearMsgHandler";
|
||||
private final WearableImpl wearable;
|
||||
private final String thisNodeId;
|
||||
private final String oldConfigNodeId;
|
||||
private String peerNodeId;
|
||||
|
||||
public MessageHandler(WearableImpl wearable, ConnectionConfiguration config) {
|
||||
@ -54,28 +54,28 @@ public class MessageHandler extends ServerMessageListener {
|
||||
private MessageHandler(WearableImpl wearable, ConnectionConfiguration config, String name, String networkId, long androidId) {
|
||||
super(new Connect.Builder()
|
||||
.name(name)
|
||||
.id(config.nodeId)
|
||||
.id(wearable.getLocalNodeId())
|
||||
.networkId(networkId)
|
||||
.peerAndroidId(androidId)
|
||||
.unknown4(3)
|
||||
.peerVersion(1)
|
||||
.build());
|
||||
this.wearable = wearable;
|
||||
this.thisNodeId = config.nodeId;
|
||||
this.oldConfigNodeId = config.nodeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect(Connect connect) {
|
||||
super.onConnect(connect);
|
||||
peerNodeId = connect.id;
|
||||
wearable.onConnectReceived(getConnection(), thisNodeId, connect);
|
||||
wearable.onConnectReceived(getConnection(), oldConfigNodeId, connect);
|
||||
try {
|
||||
getConnection().writeMessage(new RootMessage.Builder().syncStart(new SyncStart.Builder()
|
||||
.receivedSeqId(-1L)
|
||||
.version(2)
|
||||
.syncTable(Arrays.asList(
|
||||
new SyncTableEntry.Builder().key("cloud").value(1L).build(),
|
||||
new SyncTableEntry.Builder().key(thisNodeId).value(wearable.getCurrentSeqId(thisNodeId)).build(), // TODO
|
||||
new SyncTableEntry.Builder().key(wearable.getLocalNodeId()).value(wearable.getCurrentSeqId(wearable.getLocalNodeId())).build(), // TODO
|
||||
new SyncTableEntry.Builder().key(peerNodeId).value(wearable.getCurrentSeqId(peerNodeId)).build() // TODO
|
||||
)).build()).build());
|
||||
} catch (IOException e) {
|
||||
@ -85,7 +85,10 @@ public class MessageHandler extends ServerMessageListener {
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
wearable.onDisconnectReceived(getConnection(), thisNodeId, getRemoteConnect());
|
||||
Connect connect = getRemoteConnect();
|
||||
if (connect == null)
|
||||
connect = new Connect.Builder().id(oldConfigNodeId).name("Wear device").build();
|
||||
wearable.onDisconnectReceived(getConnection(), connect);
|
||||
super.onDisconnected();
|
||||
}
|
||||
|
||||
@ -120,13 +123,13 @@ public class MessageHandler extends ServerMessageListener {
|
||||
boolean hasLocalNode = false;
|
||||
if (syncStart.syncTable != null) {
|
||||
for (SyncTableEntry entry : syncStart.syncTable) {
|
||||
wearable.syncToPeer(getConnection(), entry.key, entry.value);
|
||||
wearable.syncToPeer(peerNodeId, entry.key, entry.value);
|
||||
if (wearable.getLocalNodeId().equals(entry.key)) hasLocalNode = true;
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "No sync table given.");
|
||||
}
|
||||
if (!hasLocalNode) wearable.syncToPeer(getConnection(), wearable.getLocalNodeId(), 0);
|
||||
if (!hasLocalNode) wearable.syncToPeer(peerNodeId, wearable.getLocalNodeId(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,7 +141,7 @@ public class MessageHandler extends ServerMessageListener {
|
||||
@Override
|
||||
public void onRpcRequest(Request rpcRequest) {
|
||||
Log.d(TAG, "onRpcRequest: " + rpcRequest);
|
||||
if (TextUtils.isEmpty(rpcRequest.targetNodeId) || rpcRequest.targetNodeId.equals(thisNodeId)) {
|
||||
if (TextUtils.isEmpty(rpcRequest.targetNodeId) || rpcRequest.targetNodeId.equals(wearable.getLocalNodeId())) {
|
||||
MessageEventParcelable messageEvent = new MessageEventParcelable();
|
||||
messageEvent.data = rpcRequest.rawData != null ? rpcRequest.rawData.toByteArray() : null;
|
||||
messageEvent.path = rpcRequest.path;
|
||||
|
@ -22,6 +22,7 @@ import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.wearable.Asset;
|
||||
|
||||
@ -73,18 +74,25 @@ public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
String selection;
|
||||
if (path == null) {
|
||||
params = new String[]{packageName, signatureDigest};
|
||||
selection = "packageName =? AND signatureDigest =?";
|
||||
selection = "packageName = ? AND signatureDigest = ?";
|
||||
} else if (host == null) {
|
||||
if (path.endsWith("/")) path = path + "%";
|
||||
params = new String[]{packageName, signatureDigest, path};
|
||||
selection = "packageName =? AND signatureDigest =? AND path =?";
|
||||
selection = "packageName = ? AND signatureDigest = ? AND path LIKE ?";
|
||||
} else {
|
||||
if (path.endsWith("/")) path = path + "%";
|
||||
params = new String[]{packageName, signatureDigest, host, path};
|
||||
selection = "packageName =? AND signatureDigest =? AND host =? AND path =?";
|
||||
selection = "packageName = ? AND signatureDigest = ? AND host = ? AND path LIKE ?";
|
||||
}
|
||||
selection += " AND deleted=0 AND assetsPresent !=0";
|
||||
return getReadableDatabase().rawQuery("SELECT host AS host,path AS path,data AS data,\'\' AS tags,assetname AS asset_key,assets_digest AS asset_id FROM dataItemsAndAssets WHERE " + selection, params);
|
||||
}
|
||||
|
||||
public synchronized Cursor getDataItemsByHostAndPath(String packageName, String signatureDigest, String host, String path) {
|
||||
Log.d(TAG, "getDataItemsByHostAndPath: " + packageName + ", " + signatureDigest + ", " + host + ", " + path);
|
||||
return getDataItemsByHostAndPath(getReadableDatabase(), packageName, signatureDigest, host, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != VERSION) {
|
||||
@ -240,7 +248,7 @@ public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
return res;
|
||||
}
|
||||
|
||||
public void putAsset(Asset asset, boolean dataPresent) {
|
||||
public synchronized void putAsset(Asset asset, boolean dataPresent) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put("digest", asset.getDigest());
|
||||
cv.put("dataPresent", dataPresent ? 1 : 0);
|
||||
@ -248,11 +256,39 @@ public class NodeDatabaseHelper extends SQLiteOpenHelper {
|
||||
getWritableDatabase().insertWithOnConflict("assets", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
|
||||
public void allowAssetAccess(String digest, String packageName, String signatureDigest) {
|
||||
public synchronized void allowAssetAccess(String digest, String packageName, String signatureDigest) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put("assets_digest", digest);
|
||||
cv.put("appkeys_id", getAppKey(db, packageName, signatureDigest));
|
||||
db.insert("assetsacls", null, cv);
|
||||
db.insertWithOnConflict("assetsacls", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
|
||||
public Cursor listMissingAssets() {
|
||||
return getReadableDatabase().query("dataItemsAndAssets", GDIBHAP_FIELDS, "assetsPresent = 0 AND assets_digest NOT NULL", null, null, null, "packageName, signatureDigest, host, path");
|
||||
}
|
||||
|
||||
public boolean hasAsset(Asset asset) {
|
||||
Cursor cursor = getReadableDatabase().query("assets", new String[]{"dataPresent"}, "digest=?", new String[]{asset.getDigest()}, null, null, null);
|
||||
if (cursor == null) return false;
|
||||
try {
|
||||
return (cursor.moveToNext() && cursor.getInt(0) == 1);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void markAssetAsPresent(String digest) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put("dataPresent", 1);
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.update("assets", cv, "digest=?", new String[]{digest});
|
||||
Cursor status = db.query("assetsReadyStatus", null, "nowReady != markedReady", null, null, null, null);
|
||||
while (status.moveToNext()) {
|
||||
cv = new ContentValues();
|
||||
cv.put("assetsPresent", status.getInt(status.getColumnIndex("nowReady")));
|
||||
db.update("dataitems", cv, "_id=?", new String[]{Integer.toString(status.getInt(status.getColumnIndex("dataitems_id")))});
|
||||
}
|
||||
status.close();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RpcHelper {
|
||||
private final Map<String, RpcConnectionState> rpcStateMap = new HashMap<String, RpcConnectionState>();
|
||||
private final SharedPreferences preferences;
|
||||
private final Context context;
|
||||
|
||||
public RpcHelper(Context context) {
|
||||
this.context = context;
|
||||
this.preferences = context.getSharedPreferences("wearable.rpc_service.settings", 0);
|
||||
}
|
||||
|
||||
private String getRpcConnectionId(String packageName, String targetNodeId, String path) {
|
||||
String mode = "lo";
|
||||
if (packageName.equals("com.google.android.wearable.app") && path.startsWith("/s3"))
|
||||
mode = "hi";
|
||||
return targetNodeId + ":" + mode;
|
||||
}
|
||||
|
||||
public RpcHelper.RpcConnectionState useConnectionState(String packageName, String targetNodeId, String path) {
|
||||
String rpcConnectionId = getRpcConnectionId(packageName, targetNodeId, path);
|
||||
synchronized (rpcStateMap) {
|
||||
if (!rpcStateMap.containsKey(rpcConnectionId)) {
|
||||
int g = preferences.getInt(rpcConnectionId, 1)+1;
|
||||
preferences.edit().putInt(rpcConnectionId, g).apply();
|
||||
rpcStateMap.put(rpcConnectionId, new RpcConnectionState(g));
|
||||
}
|
||||
RpcHelper.RpcConnectionState res = rpcStateMap.get(rpcConnectionId);
|
||||
res.lastRequestId++;
|
||||
return res.freeze();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RpcConnectionState {
|
||||
public int generation;
|
||||
public int lastRequestId;
|
||||
|
||||
public RpcConnectionState(int generation) {
|
||||
this.generation = generation;
|
||||
}
|
||||
|
||||
public RpcConnectionState freeze() {
|
||||
RpcConnectionState res = new RpcConnectionState(generation);
|
||||
res.lastRequestId = lastRequestId;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
@ -44,7 +44,9 @@ import org.microg.wearable.proto.AckAsset;
|
||||
import org.microg.wearable.proto.AppKey;
|
||||
import org.microg.wearable.proto.AppKeys;
|
||||
import org.microg.wearable.proto.Connect;
|
||||
import org.microg.wearable.proto.FetchAsset;
|
||||
import org.microg.wearable.proto.FilePiece;
|
||||
import org.microg.wearable.proto.Request;
|
||||
import org.microg.wearable.proto.RootMessage;
|
||||
import org.microg.wearable.proto.SetAsset;
|
||||
|
||||
@ -76,7 +78,8 @@ public class WearableImpl {
|
||||
private final ConfigurationDatabaseHelper configDatabase;
|
||||
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 final Map<String, WearableConnection> activeConnections = new HashMap<String, WearableConnection>();
|
||||
private RpcHelper rpcHelper;
|
||||
private SocketConnectionThread sct;
|
||||
private ConnectionConfiguration[] configurations;
|
||||
private boolean configurationsUpdated = false;
|
||||
@ -87,6 +90,7 @@ public class WearableImpl {
|
||||
this.nodeDatabase = nodeDatabase;
|
||||
this.configDatabase = configDatabase;
|
||||
this.clockworkNodePreferences = new ClockworkNodePreferences(context);
|
||||
this.rpcHelper = new RpcHelper(context);
|
||||
}
|
||||
|
||||
public String getLocalNodeId() {
|
||||
@ -108,6 +112,13 @@ public class WearableImpl {
|
||||
|
||||
public DataItemRecord putDataItem(DataItemRecord record) {
|
||||
nodeDatabase.putRecord(record);
|
||||
if (!record.assetsAreReady) {
|
||||
for (Asset asset : record.dataItem.getAssets().values()) {
|
||||
if (!nodeDatabase.hasAsset(asset)) {
|
||||
Log.d(TAG, "Asset is missing: " + asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
getListener(record.packageName, "com.google.android.gms.wearable.DATA_CHANGED", record.dataItem.uri)
|
||||
.onDataChanged(record.toEventDataHolder());
|
||||
@ -151,7 +162,7 @@ public class WearableImpl {
|
||||
return null;
|
||||
}
|
||||
|
||||
private File createAssetFile(String digest) {
|
||||
public File createAssetFile(String digest) {
|
||||
File dir = new File(new File(context.getFilesDir(), "assets"), digest.substring(digest.length() - 2));
|
||||
dir.mkdirs();
|
||||
return new File(dir, digest + ".asset");
|
||||
@ -183,6 +194,7 @@ public class WearableImpl {
|
||||
if (newConfiguration.name.equals(configuration.name)) {
|
||||
newConfiguration.connected = configuration.connected;
|
||||
newConfiguration.peerNodeId = configuration.peerNodeId;
|
||||
newConfiguration.nodeId = configuration.nodeId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -211,52 +223,50 @@ public class WearableImpl {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void syncToPeer(WearableConnection connection, String nodeId, long seqId) {
|
||||
Log.d(TAG, "-- Start syncing over " + connection + ", nodeId " + nodeId + " starting with seqId " + seqId);
|
||||
public void syncToPeer(String peerNodeId, String nodeId, long seqId) {
|
||||
Log.d(TAG, "-- Start syncing over to " + peerNodeId + ", nodeId " + nodeId + " starting with seqId " + seqId);
|
||||
Cursor cursor = nodeDatabase.getModifiedDataItems(nodeId, seqId, true);
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
if (!syncRecordToPeer(connection, DataItemRecord.fromCursor(cursor))) break;
|
||||
if (!syncRecordToPeer(peerNodeId, DataItemRecord.fromCursor(cursor))) break;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
Log.d(TAG, "-- Done syncing over " + connection + ", nodeId " + nodeId + " starting with seqId " + seqId);
|
||||
Log.d(TAG, "-- Done syncing over to " + peerNodeId + ", nodeId " + nodeId + " starting with seqId " + seqId);
|
||||
}
|
||||
|
||||
|
||||
private void syncRecordToAll(DataItemRecord record) {
|
||||
Log.d(TAG, "Syncing record " + record + " over " + activeConnections.size() + " connections.");
|
||||
for (WearableConnection connection : new ArrayList<WearableConnection>(activeConnections)) {
|
||||
if (!syncRecordToPeer(connection, record)) {
|
||||
Log.d(TAG, "Removing connection as it seems not usable: " + connection);
|
||||
activeConnections.remove(connection);
|
||||
}
|
||||
for (String nodeId : new ArrayList<String>(activeConnections.keySet())) {
|
||||
syncRecordToPeer(nodeId, record);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean syncRecordToPeer(WearableConnection connection, DataItemRecord record) {
|
||||
private boolean syncRecordToPeer(String nodeId, DataItemRecord record) {
|
||||
for (Asset asset : record.dataItem.getAssets().values()) {
|
||||
syncAssetToPeer(connection, record, asset);
|
||||
syncAssetToPeer(nodeId, record, asset);
|
||||
}
|
||||
Log.d(TAG, "Sync over " + connection + ": " + record);
|
||||
Log.d(TAG, "Sync over to " + nodeId + ": " + record);
|
||||
|
||||
try {
|
||||
connection.writeMessage(new RootMessage.Builder().setDataItem(record.toSetDataItem()).build());
|
||||
activeConnections.get(nodeId).writeMessage(new RootMessage.Builder().setDataItem(record.toSetDataItem()).build());
|
||||
} catch (IOException e) {
|
||||
closeConnection(nodeId);
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void syncAssetToPeer(WearableConnection connection, DataItemRecord record, Asset asset) {
|
||||
private void syncAssetToPeer(String nodeId, DataItemRecord record, Asset asset) {
|
||||
try {
|
||||
Log.d(TAG, "Sync over " + connection + ": " + asset);
|
||||
Log.d(TAG, "Sync over to " + nodeId + ": " + asset);
|
||||
RootMessage announceMessage = new RootMessage.Builder().setAsset(new SetAsset.Builder()
|
||||
.digest(asset.getDigest())
|
||||
.appkeys(new AppKeys(Collections.singletonList(new AppKey(record.packageName, record.signatureDigest))))
|
||||
.build()).hasAsset(true).build();
|
||||
connection.writeMessage(announceMessage);
|
||||
activeConnections.get(nodeId).writeMessage(announceMessage);
|
||||
File assetFile = createAssetFile(asset.getDigest());
|
||||
String fileName = calculateDigest(announceMessage.toByteArray());
|
||||
FileInputStream fis = new FileInputStream(assetFile);
|
||||
@ -265,15 +275,16 @@ public class WearableImpl {
|
||||
int c = 0;
|
||||
while ((c = fis.read(arr)) > 0) {
|
||||
if (lastPiece != null) {
|
||||
Log.d(TAG, "Sync over " + connection + ": Asset piece for fileName " + fileName + ": " + lastPiece);
|
||||
connection.writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, false, lastPiece, null)).build());
|
||||
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 " + connection + ": Last asset piece for fileName " + fileName + ": " + lastPiece);
|
||||
connection.writeMessage(new RootMessage.Builder().filePiece(new FilePiece(fileName, true, lastPiece, asset.getDigest())).build());
|
||||
Log.d(TAG, "Sync over to " + nodeId + ": Last asset piece for fileName " + fileName + ": " + lastPiece);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +314,7 @@ public class WearableImpl {
|
||||
String digest = calculateDigest(Utils.readStreamToEnd(new FileInputStream(file)));
|
||||
if (digest.equals(finalPieceDigest)) {
|
||||
if (file.renameTo(createAssetFile(digest))) {
|
||||
// TODO: Mark as stored in db
|
||||
nodeDatabase.markAssetAsPresent(digest);
|
||||
connection.writeMessage(new RootMessage.Builder().ackAsset(new AckAsset(digest)).build());
|
||||
} else {
|
||||
Log.w(TAG, "Could not rename to target file name. delete=" + file.delete());
|
||||
@ -320,23 +331,47 @@ public class WearableImpl {
|
||||
public void onConnectReceived(WearableConnection connection, String nodeId, Connect connect) {
|
||||
for (ConnectionConfiguration config : getConfigurations()) {
|
||||
if (config.nodeId.equals(nodeId)) {
|
||||
if (config.nodeId != nodeId) {
|
||||
config.nodeId = connect.id;
|
||||
configDatabase.putConfiguration(config, nodeId);
|
||||
}
|
||||
config.peerNodeId = connect.id;
|
||||
config.connected = true;
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Adding connection to list of open connections: " + connection);
|
||||
activeConnections.add(connection);
|
||||
Log.d(TAG, "Adding connection to list of open connections: " + connection + " with connect " + connect);
|
||||
activeConnections.put(connect.id, connection);
|
||||
onPeerConnected(new NodeParcelable(connect.id, connect.name));
|
||||
// Fetch missing assets
|
||||
Cursor cursor = nodeDatabase.listMissingAssets();
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
Log.d(TAG, "Fetch for " + cursor.getString(12));
|
||||
connection.writeMessage(new RootMessage.Builder()
|
||||
.fetchAsset(new FetchAsset.Builder()
|
||||
.assetName(cursor.getString(12))
|
||||
.packageName(cursor.getString(1))
|
||||
.signatureDigest(cursor.getString(2))
|
||||
.permission(false)
|
||||
.build()).build());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
closeConnection(connect.id);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisconnectReceived(WearableConnection connection, String nodeId, Connect connect) {
|
||||
public void onDisconnectReceived(WearableConnection connection, Connect connect) {
|
||||
for (ConnectionConfiguration config : getConfigurations()) {
|
||||
if (config.nodeId.equals(nodeId)) {
|
||||
if (config.nodeId.equals(connect.id)) {
|
||||
config.connected = false;
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Removing connection from list of open connections: " + connection);
|
||||
activeConnections.remove(connection);
|
||||
activeConnections.remove(connect.id);
|
||||
onPeerDisconnected(new NodeParcelable(connect.id, connect.name));
|
||||
}
|
||||
|
||||
@ -421,7 +456,7 @@ public class WearableImpl {
|
||||
}
|
||||
dataHolderItems.moveToFirst();
|
||||
dataHolderItems.moveToPrevious();
|
||||
return DataHolder.fromCursor(dataHolderItems, 0, null);
|
||||
return new DataHolder(dataHolderItems, 0, null);
|
||||
}
|
||||
|
||||
public DataHolder getDataItemForRecordAsHolder(DataItemRecord record) {
|
||||
@ -431,7 +466,7 @@ public class WearableImpl {
|
||||
}
|
||||
dataHolderItems.moveToFirst();
|
||||
dataHolderItems.moveToPrevious();
|
||||
return DataHolder.fromCursor(dataHolderItems, 0, null);
|
||||
return new DataHolder(dataHolderItems, 0, null);
|
||||
}
|
||||
|
||||
public synchronized void addListener(String packageName, IWearableListener listener) {
|
||||
@ -451,6 +486,7 @@ public class WearableImpl {
|
||||
configDatabase.setEnabledState(name, true);
|
||||
configurationsUpdated = true;
|
||||
if (name.equals("server") && sct == null) {
|
||||
Log.d(TAG, "Starting server on :" + WEAR_TCP_PORT);
|
||||
(sct = SocketConnectionThread.serverListen(WEAR_TCP_PORT, new MessageHandler(this, configDatabase.getConfiguration(name)))).start();
|
||||
}
|
||||
}
|
||||
@ -497,7 +533,7 @@ public class WearableImpl {
|
||||
}
|
||||
|
||||
public DataItemRecord getDataItemByUri(Uri uri, String packageName) {
|
||||
Cursor cursor = nodeDatabase.getDataItemsForDataHolderByHostAndPath(packageName, PackageUtils.firstSignatureDigest(context, packageName), uri.getHost(), uri.getPath());
|
||||
Cursor cursor = nodeDatabase.getDataItemsByHostAndPath(packageName, PackageUtils.firstSignatureDigest(context, packageName), uri.getHost(), uri.getPath());
|
||||
DataItemRecord record = null;
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToNext()) {
|
||||
@ -505,6 +541,7 @@ public class WearableImpl {
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
Log.d(TAG, "getDataItem: " + record);
|
||||
return record;
|
||||
}
|
||||
|
||||
@ -522,7 +559,49 @@ public class WearableImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(String targetNodeId, String path, byte[] data) {
|
||||
Log.d(TAG, "sendMessage not yet implemented!");
|
||||
private void closeConnection(String nodeId) {
|
||||
WearableConnection connection = activeConnections.get(nodeId);
|
||||
try {
|
||||
connection.close();
|
||||
} catch (IOException e1) {
|
||||
Log.w(TAG, e1);
|
||||
}
|
||||
if (connection == sct.getWearableConnection()) {
|
||||
sct.close();
|
||||
sct = null;
|
||||
}
|
||||
activeConnections.remove(nodeId);
|
||||
for (ConnectionConfiguration config : getConfigurations()) {
|
||||
if (config.nodeId.equals(nodeId) || config.peerNodeId.equals(nodeId)) {
|
||||
config.connected = false;
|
||||
}
|
||||
}
|
||||
onPeerDisconnected(new NodeParcelable(nodeId, "Wear device"));
|
||||
Log.d(TAG, "Closed connection to " + nodeId + " on error");
|
||||
}
|
||||
|
||||
public int sendMessage(String packageName, String targetNodeId, String path, byte[] data) {
|
||||
if (activeConnections.containsKey(targetNodeId)) {
|
||||
WearableConnection connection = activeConnections.get(targetNodeId);
|
||||
RpcHelper.RpcConnectionState state = rpcHelper.useConnectionState(packageName, targetNodeId, path);
|
||||
try {
|
||||
connection.writeMessage(new RootMessage.Builder().rpcRequest(new Request.Builder()
|
||||
.targetNodeId(targetNodeId)
|
||||
.path(path)
|
||||
.rawData(ByteString.of(data))
|
||||
.packageName(packageName)
|
||||
.signatureDigest(PackageUtils.firstSignatureDigest(context, packageName))
|
||||
.sourceNodeId(getLocalNodeId())
|
||||
.generation(state.generation)
|
||||
.requestId(state.lastRequestId)
|
||||
.build()).build());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error while writing, closing link", e);
|
||||
closeConnection(targetNodeId);
|
||||
return -1;
|
||||
}
|
||||
return (state.generation + 527) * 31 + state.lastRequestId;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.pm.PackageManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.data.DataHolder;
|
||||
import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.internal.ClientIdentity;
|
||||
import com.google.android.gms.location.internal.LocationRequestInternal;
|
||||
import com.google.android.gms.wearable.internal.AmsEntityUpdateParcelable;
|
||||
import com.google.android.gms.wearable.internal.AncsNotificationParcelable;
|
||||
import com.google.android.gms.wearable.internal.CapabilityInfoParcelable;
|
||||
import com.google.android.gms.wearable.internal.ChannelEventParcelable;
|
||||
import com.google.android.gms.wearable.internal.IWearableListener;
|
||||
import com.google.android.gms.wearable.internal.MessageEventParcelable;
|
||||
import com.google.android.gms.wearable.internal.NodeParcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class WearableLocationListener extends IWearableListener.Stub {
|
||||
public static final String LOCATION_REQUESTS = "com/google/android/location/fused/wearable/LOCATION_REQUESTS";
|
||||
public static final String CAPABILITY_QUERY = "com/google/android/location/fused/wearable/CAPABILITY_QUERY";
|
||||
|
||||
private static final String TAG = "GmsWearLocListener";
|
||||
|
||||
private WearableLocationService locationService;
|
||||
|
||||
public WearableLocationListener(WearableLocationService locationService) {
|
||||
this.locationService = locationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataChanged(DataHolder data) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(MessageEventParcelable messageEvent) throws RemoteException {
|
||||
if (messageEvent.getPath().equals(LOCATION_REQUESTS)) {
|
||||
//DataMap dataMap = DataMap.fromByteArray(messageEvent.getData());
|
||||
//locationService.onLocationRequests(messageEvent.getSourceNodeId(), parseLocationRequestList(dataMap, locationService), dataMap.getBoolean("TRIGGER_UPDATE", false));
|
||||
} else if (messageEvent.getPath().equals(CAPABILITY_QUERY)) {
|
||||
locationService.onCapabilityQuery(messageEvent.getSourceNodeId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeerConnected(NodeParcelable node) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeerDisconnected(NodeParcelable node) throws RemoteException {
|
||||
locationService.onLocationRequests(node.getId(), Collections.<LocationRequestInternal>emptyList(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedNodes(List<NodeParcelable> nodes) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationReceived(AncsNotificationParcelable notification) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChannelEvent(ChannelEventParcelable channelEvent) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedCapabilityChanged(CapabilityInfoParcelable capabilityInfo) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityUpdate(AmsEntityUpdateParcelable update) throws RemoteException {
|
||||
}
|
||||
|
||||
/*public static Collection<LocationRequestInternal> parseLocationRequestList(DataMap dataMap, Context context) {
|
||||
if (!dataMap.containsKey("REQUEST_LIST")) {
|
||||
Log.w(TAG, "malformed DataMap: missing key REQUEST_LIST");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<DataMap> requestMapList = dataMap.getDataMapArrayList("REQUEST_LIST");
|
||||
List<LocationRequestInternal> locationRequests = new ArrayList<LocationRequestInternal>();
|
||||
for (DataMap map : requestMapList) {
|
||||
locationRequests.add(parseLocationRequest(map, context));
|
||||
}
|
||||
return locationRequests;
|
||||
}
|
||||
|
||||
private static LocationRequestInternal parseLocationRequest(DataMap dataMap, Context context) {
|
||||
LocationRequestInternal request = new LocationRequestInternal();
|
||||
request.triggerUpdate = true;
|
||||
request.request = new LocationRequest();
|
||||
request.clients = Collections.emptyList();
|
||||
|
||||
if (dataMap.containsKey("PRIORITY"))
|
||||
request.request.setPriority(dataMap.getInt("PRIORITY", 0));
|
||||
if (dataMap.containsKey("INTERVAL_MS"))
|
||||
request.request.setInterval(dataMap.getLong("INTERVAL_MS", 0));
|
||||
if (dataMap.containsKey("FASTEST_INTERVAL_MS"))
|
||||
request.request.setFastestInterval(dataMap.getLong("FASTEST_INTERVAL_MS", 0));
|
||||
//if (dataMap.containsKey("MAX_WAIT_TIME_MS"))
|
||||
if (dataMap.containsKey("SMALLEST_DISPLACEMENT_METERS"))
|
||||
request.request.setSmallestDisplacement(dataMap.getFloat("SMALLEST_DISPLACEMENT_METERS", 0));
|
||||
if (dataMap.containsKey("NUM_UPDATES"))
|
||||
request.request.setNumUpdates(dataMap.getInt("NUM_UPDATES", 0));
|
||||
if (dataMap.containsKey("EXPIRATION_DURATION_MS"))
|
||||
request.request.setExpirationDuration(dataMap.getLong("EXPIRATION_DURATION_MS", 0));
|
||||
if (dataMap.containsKey("TAG"))
|
||||
request.tag = dataMap.getString("TAG");
|
||||
if (dataMap.containsKey("CLIENTS_PACKAGE_ARRAY")) {
|
||||
String[] packages = dataMap.getStringArray("CLIENTS_PACKAGE_ARRAY");
|
||||
if (packages != null) {
|
||||
request.clients = new ArrayList<ClientIdentity>();
|
||||
for (String packageName : packages) {
|
||||
request.clients.add(generateClientIdentity(packageName, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private static ClientIdentity generateClientIdentity(String packageName, Context context) {
|
||||
return null;
|
||||
try {
|
||||
return new ClientIdentity(context.getPackageManager().getApplicationInfo(packageName, 0).uid, packageName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Unknown client identity: " + packageName, e);
|
||||
return new ClientIdentity(context.getApplicationInfo().uid, context.getPackageName());
|
||||
}
|
||||
}*/
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.location.internal.LocationRequestInternal;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class WearableLocationService extends Service {
|
||||
// TODO: Implement and use WearableListenerService
|
||||
private static final String TAG = "GmsWearLocSvc";
|
||||
|
||||
private WearableLocationListener listener;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
listener = new WearableLocationListener(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if (intent.getAction().equals("com.google.android.gms.wearable.BIND_LISTENER")) {
|
||||
return listener.asBinder();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onLocationRequests(String nodeId, Collection<LocationRequestInternal> requests, boolean triggerUpdate) {
|
||||
|
||||
}
|
||||
|
||||
public void onCapabilityQuery(String nodeId) {
|
||||
|
||||
}
|
||||
}
|
@ -19,24 +19,33 @@ package org.microg.gms.wearable;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.wearable.Asset;
|
||||
import com.google.android.gms.wearable.ConnectionConfiguration;
|
||||
import com.google.android.gms.wearable.internal.AddListenerRequest;
|
||||
import com.google.android.gms.wearable.internal.AncsNotificationParcelable;
|
||||
import com.google.android.gms.wearable.internal.DeleteDataItemsResponse;
|
||||
import com.google.android.gms.wearable.internal.GetCloudSyncSettingResponse;
|
||||
import com.google.android.gms.wearable.internal.GetConfigResponse;
|
||||
import com.google.android.gms.wearable.internal.GetConfigsResponse;
|
||||
import com.google.android.gms.wearable.internal.GetConnectedNodesResponse;
|
||||
import com.google.android.gms.wearable.internal.GetDataItemResponse;
|
||||
import com.google.android.gms.wearable.internal.GetFdForAssetResponse;
|
||||
import com.google.android.gms.wearable.internal.GetLocalNodeResponse;
|
||||
import com.google.android.gms.wearable.internal.IChannelStreamCallbacks;
|
||||
import com.google.android.gms.wearable.internal.IWearableCallbacks;
|
||||
import com.google.android.gms.wearable.internal.IWearableService;
|
||||
import com.google.android.gms.wearable.internal.NodeParcelable;
|
||||
import com.google.android.gms.wearable.internal.PutDataRequest;
|
||||
import com.google.android.gms.wearable.internal.PutDataResponse;
|
||||
import com.google.android.gms.wearable.internal.RemoveListenerRequest;
|
||||
import com.google.android.gms.wearable.internal.SendMessageResponse;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
public class WearableServiceImpl extends IWearableService.Stub {
|
||||
private static final String TAG = "GmsWearSvcImpl";
|
||||
@ -51,6 +60,50 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Config
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void putConfig(IWearableCallbacks callbacks, ConnectionConfiguration config) throws RemoteException {
|
||||
wearable.createConnection(config);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConfig(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
wearable.deleteConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConfigs(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "getConfigs");
|
||||
try {
|
||||
callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations()));
|
||||
} catch (Exception e) {
|
||||
callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableConfig(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
Log.d(TAG, "enableConfig: " + name);
|
||||
wearable.enableConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableConfig(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
Log.d(TAG, "disableConfig: " + name);
|
||||
wearable.disableConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* DataItems
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void putData(IWearableCallbacks callbacks, PutDataRequest request) throws RemoteException {
|
||||
@ -74,32 +127,88 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
@Override
|
||||
public void getDataItems(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "getDataItems: " + callbacks);
|
||||
callbacks.onDataHolder(wearable.getDataItemsAsHolder(packageName));
|
||||
callbacks.onDataItemChanged(wearable.getDataItemsAsHolder(packageName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(IWearableCallbacks callbacks, String targetNodeId, String path, byte[] data) throws RemoteException {
|
||||
Log.d(TAG, "sendMessage: " + targetNodeId + " / " + path);
|
||||
wearable.sendMessage(targetNodeId, path, data);
|
||||
public void getDataItemsByUri(IWearableCallbacks callbacks, Uri uri) throws RemoteException {
|
||||
getDataItemsByUriWithFilter(callbacks, uri, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataItemsByUri(IWearableCallbacks callbacks, Uri uri, int i) throws RemoteException {
|
||||
public void getDataItemsByUriWithFilter(IWearableCallbacks callbacks, Uri uri, int typeFilter) throws RemoteException {
|
||||
Log.d(TAG, "getDataItemsByUri: " + uri);
|
||||
callbacks.onDataHolder(wearable.getDataItemsByUriAsHolder(uri, packageName));
|
||||
callbacks.onDataItemChanged(wearable.getDataItemsByUriAsHolder(uri, packageName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDataItems(IWearableCallbacks callbacks, Uri uri) throws RemoteException {
|
||||
deleteDataItemsWithFilter(callbacks, uri, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDataItemsWithFilter(IWearableCallbacks callbacks, Uri uri, int typeFilter) throws RemoteException {
|
||||
Log.d(TAG, "deleteDataItems: " + uri);
|
||||
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(IWearableCallbacks callbacks, String targetNodeId, String path, byte[] data) throws RemoteException {
|
||||
Log.d(TAG, "sendMessage: " + targetNodeId + " / " + path);
|
||||
SendMessageResponse sendMessageResponse = new SendMessageResponse();
|
||||
try {
|
||||
sendMessageResponse.resultId = wearable.sendMessage(packageName, targetNodeId, path, data);
|
||||
if (sendMessageResponse.resultId == -1) {
|
||||
sendMessageResponse.statusCode = 4000;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sendMessageResponse.statusCode = 8;
|
||||
}
|
||||
callbacks.onSendMessageResponse(sendMessageResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFdForAsset(IWearableCallbacks callbacks, Asset asset) throws RemoteException {
|
||||
Log.d(TAG, "getFdForAsset " + asset);
|
||||
// TODO: Access control
|
||||
try {
|
||||
callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(0, ParcelFileDescriptor.open(wearable.createAssetFile(asset.getDigest()), ParcelFileDescriptor.MODE_READ_ONLY)));
|
||||
} catch (FileNotFoundException e) {
|
||||
callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(8, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optInCloudSync(IWearableCallbacks callbacks, boolean enable) throws RemoteException {
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void getCloudSyncOptInDone(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getCloudSyncOptInDone");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCloudSyncSetting(IWearableCallbacks callbacks, boolean enable) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: setCloudSyncSetting");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCloudSyncSetting(IWearableCallbacks callbacks) throws RemoteException {
|
||||
callbacks.onGetCloudSyncSettingResponse(new GetCloudSyncSettingResponse(0, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCloudSyncOptInStatus(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getCloudSyncOptInStatus");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRemoteCommand(IWearableCallbacks callbacks, byte b) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: sendRemoteCommand: " + b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLocalNode(IWearableCallbacks callbacks) throws RemoteException {
|
||||
try {
|
||||
@ -111,13 +220,35 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
|
||||
@Override
|
||||
public void getConnectedNodes(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "getConnectedNodes");
|
||||
callbacks.onGetConnectedNodesResponse(new GetConnectedNodesResponse(0, wearable.getConnectedNodesParcelableList()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Capability
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void getConnectedCapability(IWearableCallbacks callbacks, String s1, int i) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getConnectedCapability " + s1 + ", " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConnectedCapaibilties(IWearableCallbacks callbacks, int i) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getConnectedCapaibilties: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLocalCapability(IWearableCallbacks callbacks, String cap) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: addLocalCapability: " + cap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLocalCapability(IWearableCallbacks callbacks, String cap) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: removeLocalCapability: " + cap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IWearableCallbacks callbacks, AddListenerRequest request) throws RemoteException {
|
||||
Log.d(TAG, "addListener[nyp]: " + request);
|
||||
if (request.listener != null) {
|
||||
wearable.addListener(packageName, request.listener);
|
||||
}
|
||||
@ -126,25 +257,112 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
|
||||
@Override
|
||||
public void removeListener(IWearableCallbacks callbacks, RemoveListenerRequest request) throws RemoteException {
|
||||
Log.d(TAG, "removeListener[nyp]: " + request);
|
||||
wearable.removeListener(request.listener);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putConfig(IWearableCallbacks callbacks, ConnectionConfiguration config) throws RemoteException {
|
||||
wearable.createConnection(config);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
public void getStrorageInformation(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getStrorageInformation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConfig(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
wearable.deleteConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
public void clearStorage(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: clearStorage");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConfig(IWearableCallbacks callbacks) throws RemoteException {
|
||||
public void endCall(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: endCall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptRingingCall(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: acceptRingingCall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void silenceRinger(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: silenceRinger");
|
||||
}
|
||||
|
||||
/*
|
||||
* Apple Notification Center Service
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void injectAncsNotificationForTesting(IWearableCallbacks callbacks, AncsNotificationParcelable notification) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: injectAncsNotificationForTesting: " + notification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAncsPositiveAction(IWearableCallbacks callbacks, int i) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: doAncsPositiveAction: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAncsNegativeAction(IWearableCallbacks callbacks, int i) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: doAncsNegativeAction: " + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openChannel(IWearableCallbacks callbacks, String s1, String s2) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: openChannel; " + s1 + ", " + s2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Channels
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void closeChannel(IWearableCallbacks callbacks, String s) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: closeChannel: " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChannelWithError(IWearableCallbacks callbacks, String s, int errorCode) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: closeChannelWithError:" + s + ", " + errorCode);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChannelInputStream(IWearableCallbacks callbacks, IChannelStreamCallbacks channelCallbacks, String s) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getChannelInputStream: " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChannelOutputStream(IWearableCallbacks callbacks, IChannelStreamCallbacks channelCallbacks, String s) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: getChannelOutputStream: " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChannelInputToFd(IWearableCallbacks callbacks, String s, ParcelFileDescriptor fd) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: writeChannelInputToFd: " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readChannelOutputFromFd(IWearableCallbacks callbacks, String s, ParcelFileDescriptor fd, long l1, long l2) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: readChannelOutputFromFd: " + s + ", " + l1 + ", " + l2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncWifiCredentials(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: syncWifiCredentials");
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection deprecated
|
||||
*/
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void putConnection(IWearableCallbacks callbacks, ConnectionConfiguration config) throws RemoteException {
|
||||
Log.d(TAG, "unimplemented Method: putConnection");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void getConnection(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "getConfig");
|
||||
ConnectionConfiguration[] configurations = wearable.getConfigurations();
|
||||
if (configurations == null || configurations.length == 0) {
|
||||
@ -155,28 +373,21 @@ public class WearableServiceImpl extends IWearableService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConfigs(IWearableCallbacks callbacks) throws RemoteException {
|
||||
Log.d(TAG, "getConfigs");
|
||||
try {
|
||||
callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations()));
|
||||
} catch (Exception e) {
|
||||
callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
|
||||
@Deprecated
|
||||
public void enableConnection(IWearableCallbacks callbacks) throws RemoteException {
|
||||
ConnectionConfiguration[] configurations = wearable.getConfigurations();
|
||||
if (configurations.length > 0) {
|
||||
enableConfig(callbacks, configurations[0].name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableConnection(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
Log.d(TAG, "enableConnection: " + name);
|
||||
wearable.enableConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableConnection(IWearableCallbacks callbacks, String name) throws RemoteException {
|
||||
Log.d(TAG, "disableConnection: " + name);
|
||||
wearable.disableConnection(name);
|
||||
callbacks.onStatus(Status.SUCCESS);
|
||||
@Deprecated
|
||||
public void disableConnection(IWearableCallbacks callbacks) throws RemoteException {
|
||||
ConnectionConfiguration[] configurations = wearable.getConfigurations();
|
||||
if (configurations.length > 0) {
|
||||
disableConfig(callbacks, configurations[0].name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user