Fix wearable implementation network usage

This commit is contained in:
Marvin W 2019-07-01 00:31:09 +02:00
parent f8a0c9c4d3
commit bae47feeca
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
3 changed files with 123 additions and 125 deletions

View File

@ -21,6 +21,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
@ -87,6 +89,7 @@ public class WearableImpl {
private ConnectionConfiguration[] configurations; private ConnectionConfiguration[] configurations;
private boolean configurationsUpdated = false; private boolean configurationsUpdated = false;
private ClockworkNodePreferences clockworkNodePreferences; private ClockworkNodePreferences clockworkNodePreferences;
public Handler networkHandler;
public WearableImpl(Context context, NodeDatabaseHelper nodeDatabase, ConfigurationDatabaseHelper configDatabase) { public WearableImpl(Context context, NodeDatabaseHelper nodeDatabase, ConfigurationDatabaseHelper configDatabase) {
this.context = context; this.context = context;
@ -94,6 +97,11 @@ public class WearableImpl {
this.configDatabase = configDatabase; this.configDatabase = configDatabase;
this.clockworkNodePreferences = new ClockworkNodePreferences(context); this.clockworkNodePreferences = new ClockworkNodePreferences(context);
this.rpcHelper = new RpcHelper(context); this.rpcHelper = new RpcHelper(context);
new Thread(() -> {
Looper.prepare();
networkHandler = new Handler(Looper.myLooper());
Looper.loop();
}).start();
} }
public String getLocalNodeId() { public String getLocalNodeId() {
@ -619,4 +627,8 @@ public class WearableImpl {
Log.d(TAG, targetNodeId + " seems not reachable"); Log.d(TAG, targetNodeId + " seems not reachable");
return -1; return -1;
} }
public void stop() {
this.networkHandler.getLooper().quit();
}
} }

View File

@ -16,10 +16,6 @@
package org.microg.gms.wearable; package org.microg.gms.wearable;
import android.content.Context;
import android.os.Binder;
import android.os.Handler;
import android.os.Messenger;
import android.os.RemoteException; import android.os.RemoteException;
import com.google.android.gms.common.internal.GetServiceRequest; import com.google.android.gms.common.internal.GetServiceRequest;
@ -31,24 +27,29 @@ import org.microg.gms.common.PackageUtils;
public class WearableService extends BaseService { public class WearableService extends BaseService {
private static WearableImpl wearable; private WearableImpl wearable;
public WearableService() { public WearableService() {
super("GmsWearSvc", GmsService.WEARABLE); super("GmsWearSvc", GmsService.WEARABLE);
} }
private synchronized static WearableImpl getWearable(Context appCtx) { @Override
if (wearable == null) { public void onCreate() {
ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(appCtx); super.onCreate();
NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(appCtx); ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(getApplicationContext());
wearable = new WearableImpl(appCtx, nodeDatabaseHelper, configurationDatabaseHelper); NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(getApplicationContext());
} wearable = new WearableImpl(getApplicationContext(), nodeDatabaseHelper, configurationDatabaseHelper);
return wearable; }
@Override
public void onDestroy() {
super.onDestroy();
wearable.stop();
} }
@Override @Override
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
PackageUtils.checkPackageUid(this, request.packageName, Binder.getCallingUid()); PackageUtils.getAndCheckCallingPackage(this, request.packageName);
callback.onPostInitComplete(0, new WearableServiceImpl(this, getWearable(getApplicationContext()), request.packageName), null); callback.onPostInitComplete(0, new WearableServiceImpl(this, wearable, request.packageName), null);
} }
} }

View File

@ -55,13 +55,31 @@ public class WearableServiceImpl extends IWearableService.Stub {
private final Context context; private final Context context;
private final String packageName; private final String packageName;
private final WearableImpl wearable; private final WearableImpl wearable;
private final Handler handler; private final Handler mainHandler;
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.handler = new Handler(context.getMainLooper()); this.mainHandler = new Handler(context.getMainLooper());
}
private void postMain(IWearableCallbacks callbacks, RemoteExceptionRunnable runnable) {
mainHandler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
runnable.run();
}
});
}
private void postNetwork(IWearableCallbacks callbacks, RemoteExceptionRunnable runnable) {
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
runnable.run();
}
});
} }
/* /*
@ -70,37 +88,28 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void putConfig(IWearableCallbacks callbacks, final ConnectionConfiguration config) throws RemoteException { public void putConfig(IWearableCallbacks callbacks, final ConnectionConfiguration config) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override wearable.createConnection(config);
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onStatus(Status.SUCCESS);
wearable.createConnection(config);
callbacks.onStatus(Status.SUCCESS);
}
}); });
} }
@Override @Override
public void deleteConfig(IWearableCallbacks callbacks, final String name) throws RemoteException { public void deleteConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override wearable.deleteConnection(name);
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onStatus(Status.SUCCESS);
wearable.deleteConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
}); });
} }
@Override @Override
public void getConfigs(IWearableCallbacks callbacks) throws RemoteException { public void getConfigs(IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getConfigs"); Log.d(TAG, "getConfigs");
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override try {
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations()));
try { } catch (Exception e) {
callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations())); callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
} catch (Exception e) {
callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
}
} }
}); });
} }
@ -109,24 +118,18 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void enableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException { public void enableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
Log.d(TAG, "enableConfig: " + name); Log.d(TAG, "enableConfig: " + name);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override wearable.enableConnection(name);
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onStatus(Status.SUCCESS);
wearable.enableConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
}); });
} }
@Override @Override
public void disableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException { public void disableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
Log.d(TAG, "disableConfig: " + name); Log.d(TAG, "disableConfig: " + name);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override wearable.disableConnection(name);
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onStatus(Status.SUCCESS);
wearable.disableConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
}); });
} }
@ -137,7 +140,7 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void putData(IWearableCallbacks callbacks, final PutDataRequest request) throws RemoteException { public void putData(IWearableCallbacks callbacks, final PutDataRequest request) throws RemoteException {
Log.d(TAG, "putData: " + request.toString(true)); Log.d(TAG, "putData: " + request.toString(true));
handler.post(new CallbackRunnable(callbacks) { this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
@Override @Override
public void run(IWearableCallbacks callbacks) throws RemoteException { public void run(IWearableCallbacks callbacks) throws RemoteException {
DataItemRecord record = wearable.putData(request, packageName); DataItemRecord record = wearable.putData(request, packageName);
@ -149,15 +152,12 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void getDataItem(IWearableCallbacks callbacks, final Uri uri) throws RemoteException { public void getDataItem(IWearableCallbacks callbacks, final Uri uri) throws RemoteException {
Log.d(TAG, "getDataItem: " + uri); Log.d(TAG, "getDataItem: " + uri);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override DataItemRecord record = wearable.getDataItemByUri(uri, packageName);
public void run(IWearableCallbacks callbacks) throws RemoteException { if (record != null) {
DataItemRecord record = wearable.getDataItemByUri(uri, packageName); callbacks.onGetDataItemResponse(new GetDataItemResponse(0, record.toParcelable()));
if (record != null) { } else {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, record.toParcelable())); callbacks.onGetDataItemResponse(new GetDataItemResponse(0, null));
} else {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, null));
}
} }
}); });
} }
@ -165,11 +165,8 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void getDataItems(final IWearableCallbacks callbacks) throws RemoteException { public void getDataItems(final IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getDataItems: " + callbacks); Log.d(TAG, "getDataItems: " + callbacks);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override callbacks.onDataItemChanged(wearable.getDataItemsAsHolder(packageName));
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDataItemChanged(wearable.getDataItemsAsHolder(packageName));
}
}); });
} }
@ -181,11 +178,8 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void getDataItemsByUriWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException { public void getDataItemsByUriWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException {
Log.d(TAG, "getDataItemsByUri: " + uri); Log.d(TAG, "getDataItemsByUri: " + uri);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override callbacks.onDataItemChanged(wearable.getDataItemsByUriAsHolder(uri, packageName));
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDataItemChanged(wearable.getDataItemsByUriAsHolder(uri, packageName));
}
}); });
} }
@ -197,18 +191,15 @@ 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);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
}
}); });
} }
@Override @Override
public void sendMessage(IWearableCallbacks callbacks, final String targetNodeId, final String path, final byte[] data) throws RemoteException { public void sendMessage(IWearableCallbacks callbacks, final String targetNodeId, final String path, final byte[] data) throws RemoteException {
Log.d(TAG, "sendMessage: " + targetNodeId + " / " + path + ": " + (data == null ? null : Base64.encodeToString(data, Base64.NO_WRAP))); Log.d(TAG, "sendMessage: " + targetNodeId + " / " + path + ": " + (data == null ? null : Base64.encodeToString(data, Base64.NO_WRAP)));
handler.post(new CallbackRunnable(callbacks) { this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
@Override @Override
public void run(IWearableCallbacks callbacks) throws RemoteException { public void run(IWearableCallbacks callbacks) throws RemoteException {
SendMessageResponse sendMessageResponse = new SendMessageResponse(); SendMessageResponse sendMessageResponse = new SendMessageResponse();
@ -220,7 +211,13 @@ public class WearableServiceImpl extends IWearableService.Stub {
} catch (Exception e) { } catch (Exception e) {
sendMessageResponse.statusCode = 8; sendMessageResponse.statusCode = 8;
} }
callbacks.onSendMessageResponse(sendMessageResponse); mainHandler.post(() -> {
try {
callbacks.onSendMessageResponse(sendMessageResponse);
} catch (RemoteException e) {
e.printStackTrace();
}
});
} }
}); });
} }
@ -228,15 +225,12 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void getFdForAsset(IWearableCallbacks callbacks, final Asset asset) throws RemoteException { public void getFdForAsset(IWearableCallbacks callbacks, final Asset asset) throws RemoteException {
Log.d(TAG, "getFdForAsset " + asset); Log.d(TAG, "getFdForAsset " + asset);
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override // TODO: Access control
public void run(IWearableCallbacks callbacks) throws RemoteException { try {
// TODO: Access control callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(0, ParcelFileDescriptor.open(wearable.createAssetFile(asset.getDigest()), ParcelFileDescriptor.MODE_READ_ONLY)));
try { } catch (FileNotFoundException e) {
callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(0, ParcelFileDescriptor.open(wearable.createAssetFile(asset.getDigest()), ParcelFileDescriptor.MODE_READ_ONLY))); callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(8, null));
} catch (FileNotFoundException e) {
callbacks.onGetFdForAssetResponse(new GetFdForAssetResponse(8, null));
}
} }
}); });
} }
@ -274,25 +268,19 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
public void getLocalNode(IWearableCallbacks callbacks) throws RemoteException { public void getLocalNode(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override try {
public void run(IWearableCallbacks callbacks) throws RemoteException { callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(0, new NodeParcelable(wearable.getLocalNodeId(), wearable.getLocalNodeId())));
try { } catch (Exception e) {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(0, new NodeParcelable(wearable.getLocalNodeId(), wearable.getLocalNodeId()))); callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(8, null));
} catch (Exception e) {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(8, null));
}
} }
}); });
} }
@Override @Override
public void getConnectedNodes(IWearableCallbacks callbacks) throws RemoteException { public void getConnectedNodes(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override callbacks.onGetConnectedNodesResponse(new GetConnectedNodesResponse(0, wearable.getConnectedNodesParcelableList()));
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onGetConnectedNodesResponse(new GetConnectedNodesResponse(0, wearable.getConnectedNodesParcelableList()));
}
}); });
} }
@ -437,15 +425,12 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Deprecated @Deprecated
public void getConnection(IWearableCallbacks callbacks) throws RemoteException { public void getConnection(IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getConfig"); Log.d(TAG, "getConfig");
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override ConnectionConfiguration[] configurations = wearable.getConfigurations();
public void run(IWearableCallbacks callbacks) throws RemoteException { if (configurations == null || configurations.length == 0) {
ConnectionConfiguration[] configurations = wearable.getConfigurations(); callbacks.onGetConfigResponse(new GetConfigResponse(1, new ConnectionConfiguration(null, null, 0, 0, false)));
if (configurations == null || configurations.length == 0) { } else {
callbacks.onGetConfigResponse(new GetConfigResponse(1, new ConnectionConfiguration(null, null, 0, 0, false))); callbacks.onGetConfigResponse(new GetConfigResponse(0, configurations[0]));
} else {
callbacks.onGetConfigResponse(new GetConfigResponse(0, configurations[0]));
}
} }
}); });
} }
@ -453,13 +438,10 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
@Deprecated @Deprecated
public void enableConnection(IWearableCallbacks callbacks) throws RemoteException { public void enableConnection(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override ConnectionConfiguration[] configurations = wearable.getConfigurations();
public void run(IWearableCallbacks callbacks) throws RemoteException { if (configurations.length > 0) {
ConnectionConfiguration[] configurations = wearable.getConfigurations(); enableConfig(callbacks, configurations[0].name);
if (configurations.length > 0) {
enableConfig(callbacks, configurations[0].name);
}
} }
}); });
} }
@ -467,13 +449,10 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override @Override
@Deprecated @Deprecated
public void disableConnection(IWearableCallbacks callbacks) throws RemoteException { public void disableConnection(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) { postMain(callbacks, () -> {
@Override ConnectionConfiguration[] configurations = wearable.getConfigurations();
public void run(IWearableCallbacks callbacks) throws RemoteException { if (configurations.length > 0) {
ConnectionConfiguration[] configurations = wearable.getConfigurations(); disableConfig(callbacks, configurations[0].name);
if (configurations.length > 0) {
disableConfig(callbacks, configurations[0].name);
}
} }
}); });
} }
@ -497,14 +476,20 @@ public class WearableServiceImpl extends IWearableService.Stub {
try { try {
run(callbacks); run(callbacks);
} catch (RemoteException e) { } catch (RemoteException e) {
try { mainHandler.post(() -> {
callbacks.onStatus(Status.CANCELED); try {
} catch (RemoteException e1) { callbacks.onStatus(Status.CANCELED);
Log.w(TAG, e); } catch (RemoteException e2) {
} Log.w(TAG, e);
}
});
} }
} }
public abstract void run(IWearableCallbacks callbacks) throws RemoteException; public abstract void run(IWearableCallbacks callbacks) throws RemoteException;
} }
public interface RemoteExceptionRunnable {
void run() throws RemoteException;
}
} }