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

View File

@ -16,10 +16,6 @@
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 com.google.android.gms.common.internal.GetServiceRequest;
@ -31,24 +27,29 @@ import org.microg.gms.common.PackageUtils;
public class WearableService extends BaseService {
private static WearableImpl wearable;
private WearableImpl wearable;
public WearableService() {
super("GmsWearSvc", GmsService.WEARABLE);
}
private synchronized static WearableImpl getWearable(Context appCtx) {
if (wearable == null) {
ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(appCtx);
NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(appCtx);
wearable = new WearableImpl(appCtx, nodeDatabaseHelper, configurationDatabaseHelper);
}
return wearable;
@Override
public void onCreate() {
super.onCreate();
ConfigurationDatabaseHelper configurationDatabaseHelper = new ConfigurationDatabaseHelper(getApplicationContext());
NodeDatabaseHelper nodeDatabaseHelper = new NodeDatabaseHelper(getApplicationContext());
wearable = new WearableImpl(getApplicationContext(), nodeDatabaseHelper, configurationDatabaseHelper);
}
@Override
public void onDestroy() {
super.onDestroy();
wearable.stop();
}
@Override
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
PackageUtils.checkPackageUid(this, request.packageName, Binder.getCallingUid());
callback.onPostInitComplete(0, new WearableServiceImpl(this, getWearable(getApplicationContext()), request.packageName), null);
PackageUtils.getAndCheckCallingPackage(this, request.packageName);
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 String packageName;
private final WearableImpl wearable;
private final Handler handler;
private final Handler mainHandler;
public WearableServiceImpl(Context context, WearableImpl wearable, String packageName) {
this.context = context;
this.wearable = wearable;
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
public void putConfig(IWearableCallbacks callbacks, final ConnectionConfiguration config) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
wearable.createConnection(config);
callbacks.onStatus(Status.SUCCESS);
}
postMain(callbacks, () -> {
wearable.createConnection(config);
callbacks.onStatus(Status.SUCCESS);
});
}
@Override
public void deleteConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
wearable.deleteConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
postMain(callbacks, () -> {
wearable.deleteConnection(name);
callbacks.onStatus(Status.SUCCESS);
});
}
@Override
public void getConfigs(IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getConfigs");
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
try {
callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations()));
} catch (Exception e) {
callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
}
postMain(callbacks, () -> {
try {
callbacks.onGetConfigsResponse(new GetConfigsResponse(0, wearable.getConfigurations()));
} catch (Exception e) {
callbacks.onGetConfigsResponse(new GetConfigsResponse(8, new ConnectionConfiguration[0]));
}
});
}
@ -109,24 +118,18 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void enableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
Log.d(TAG, "enableConfig: " + name);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
wearable.enableConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
postMain(callbacks, () -> {
wearable.enableConnection(name);
callbacks.onStatus(Status.SUCCESS);
});
}
@Override
public void disableConfig(IWearableCallbacks callbacks, final String name) throws RemoteException {
Log.d(TAG, "disableConfig: " + name);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
wearable.disableConnection(name);
callbacks.onStatus(Status.SUCCESS);
}
postMain(callbacks, () -> {
wearable.disableConnection(name);
callbacks.onStatus(Status.SUCCESS);
});
}
@ -137,7 +140,7 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void putData(IWearableCallbacks callbacks, final PutDataRequest request) throws RemoteException {
Log.d(TAG, "putData: " + request.toString(true));
handler.post(new CallbackRunnable(callbacks) {
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
DataItemRecord record = wearable.putData(request, packageName);
@ -149,15 +152,12 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void getDataItem(IWearableCallbacks callbacks, final Uri uri) throws RemoteException {
Log.d(TAG, "getDataItem: " + uri);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
DataItemRecord record = wearable.getDataItemByUri(uri, packageName);
if (record != null) {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, record.toParcelable()));
} else {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, null));
}
postMain(callbacks, () -> {
DataItemRecord record = wearable.getDataItemByUri(uri, packageName);
if (record != null) {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, record.toParcelable()));
} else {
callbacks.onGetDataItemResponse(new GetDataItemResponse(0, null));
}
});
}
@ -165,11 +165,8 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void getDataItems(final IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getDataItems: " + callbacks);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDataItemChanged(wearable.getDataItemsAsHolder(packageName));
}
postMain(callbacks, () -> {
callbacks.onDataItemChanged(wearable.getDataItemsAsHolder(packageName));
});
}
@ -181,11 +178,8 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void getDataItemsByUriWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException {
Log.d(TAG, "getDataItemsByUri: " + uri);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDataItemChanged(wearable.getDataItemsByUriAsHolder(uri, packageName));
}
postMain(callbacks, () -> {
callbacks.onDataItemChanged(wearable.getDataItemsByUriAsHolder(uri, packageName));
});
}
@ -197,18 +191,15 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void deleteDataItemsWithFilter(IWearableCallbacks callbacks, final Uri uri, int typeFilter) throws RemoteException {
Log.d(TAG, "deleteDataItems: " + uri);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
}
postMain(callbacks, () -> {
callbacks.onDeleteDataItemsResponse(new DeleteDataItemsResponse(0, wearable.deleteDataItems(uri, packageName)));
});
}
@Override
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)));
handler.post(new CallbackRunnable(callbacks) {
this.wearable.networkHandler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
SendMessageResponse sendMessageResponse = new SendMessageResponse();
@ -220,7 +211,13 @@ public class WearableServiceImpl extends IWearableService.Stub {
} catch (Exception e) {
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
public void getFdForAsset(IWearableCallbacks callbacks, final Asset asset) throws RemoteException {
Log.d(TAG, "getFdForAsset " + asset);
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
// 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));
}
postMain(callbacks, () -> {
// 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));
}
});
}
@ -274,25 +268,19 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
public void getLocalNode(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
try {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(0, new NodeParcelable(wearable.getLocalNodeId(), wearable.getLocalNodeId())));
} catch (Exception e) {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(8, null));
}
postMain(callbacks, () -> {
try {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(0, new NodeParcelable(wearable.getLocalNodeId(), wearable.getLocalNodeId())));
} catch (Exception e) {
callbacks.onGetLocalNodeResponse(new GetLocalNodeResponse(8, null));
}
});
}
@Override
public void getConnectedNodes(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
callbacks.onGetConnectedNodesResponse(new GetConnectedNodesResponse(0, wearable.getConnectedNodesParcelableList()));
}
postMain(callbacks, () -> {
callbacks.onGetConnectedNodesResponse(new GetConnectedNodesResponse(0, wearable.getConnectedNodesParcelableList()));
});
}
@ -437,15 +425,12 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Deprecated
public void getConnection(IWearableCallbacks callbacks) throws RemoteException {
Log.d(TAG, "getConfig");
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations == null || configurations.length == 0) {
callbacks.onGetConfigResponse(new GetConfigResponse(1, new ConnectionConfiguration(null, null, 0, 0, false)));
} else {
callbacks.onGetConfigResponse(new GetConfigResponse(0, configurations[0]));
}
postMain(callbacks, () -> {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations == null || configurations.length == 0) {
callbacks.onGetConfigResponse(new GetConfigResponse(1, new ConnectionConfiguration(null, null, 0, 0, false)));
} else {
callbacks.onGetConfigResponse(new GetConfigResponse(0, configurations[0]));
}
});
}
@ -453,13 +438,10 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
@Deprecated
public void enableConnection(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations.length > 0) {
enableConfig(callbacks, configurations[0].name);
}
postMain(callbacks, () -> {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations.length > 0) {
enableConfig(callbacks, configurations[0].name);
}
});
}
@ -467,13 +449,10 @@ public class WearableServiceImpl extends IWearableService.Stub {
@Override
@Deprecated
public void disableConnection(IWearableCallbacks callbacks) throws RemoteException {
handler.post(new CallbackRunnable(callbacks) {
@Override
public void run(IWearableCallbacks callbacks) throws RemoteException {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations.length > 0) {
disableConfig(callbacks, configurations[0].name);
}
postMain(callbacks, () -> {
ConnectionConfiguration[] configurations = wearable.getConfigurations();
if (configurations.length > 0) {
disableConfig(callbacks, configurations[0].name);
}
});
}
@ -497,14 +476,20 @@ public class WearableServiceImpl extends IWearableService.Stub {
try {
run(callbacks);
} catch (RemoteException e) {
try {
callbacks.onStatus(Status.CANCELED);
} catch (RemoteException e1) {
Log.w(TAG, e);
}
mainHandler.post(() -> {
try {
callbacks.onStatus(Status.CANCELED);
} catch (RemoteException e2) {
Log.w(TAG, e);
}
});
}
}
public abstract void run(IWearableCallbacks callbacks) throws RemoteException;
}
public interface RemoteExceptionRunnable {
void run() throws RemoteException;
}
}