From bae47feecafb516f49ec2d517f73449bf635cfe6 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Mon, 1 Jul 2019 00:31:09 +0200 Subject: [PATCH] Fix wearable implementation network usage --- .../org/microg/gms/wearable/WearableImpl.java | 12 + .../microg/gms/wearable/WearableService.java | 29 +-- .../gms/wearable/WearableServiceImpl.java | 207 ++++++++---------- 3 files changed, 123 insertions(+), 125 deletions(-) diff --git a/play-services-core/src/main/java/org/microg/gms/wearable/WearableImpl.java b/play-services-core/src/main/java/org/microg/gms/wearable/WearableImpl.java index 76faffe7..85243892 100644 --- a/play-services-core/src/main/java/org/microg/gms/wearable/WearableImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/wearable/WearableImpl.java @@ -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(); + } } diff --git a/play-services-core/src/main/java/org/microg/gms/wearable/WearableService.java b/play-services-core/src/main/java/org/microg/gms/wearable/WearableService.java index 9afb8b83..737b045d 100644 --- a/play-services-core/src/main/java/org/microg/gms/wearable/WearableService.java +++ b/play-services-core/src/main/java/org/microg/gms/wearable/WearableService.java @@ -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); } } diff --git a/play-services-core/src/main/java/org/microg/gms/wearable/WearableServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/wearable/WearableServiceImpl.java index c087f39e..ef830d3b 100644 --- a/play-services-core/src/main/java/org/microg/gms/wearable/WearableServiceImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/wearable/WearableServiceImpl.java @@ -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; + } }