diff options
author | Jonathan Scott <scottjonathan@google.com> | 2021-09-22 10:57:50 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-09-22 10:57:50 +0000 |
commit | bd1ae8781806626032e47ad5275fa963f6c51f45 (patch) | |
tree | 0bb6d94ce4a1e4dc54aad2bf353e9b7aa41935bf | |
parent | 195192cb287b2ec42b1bb4fc85f1fa9d298e941a (diff) | |
parent | 7799a3a2c8b03417fe474b9ec41e0c36dec82a55 (diff) | |
download | connectedappssdk-bd1ae8781806626032e47ad5275fa963f6c51f45.tar.gz |
Make Connected Apps SDK use only a single broadcast receiver. am: 1ea704c05a am: 7799a3a2c8
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/connectedappssdk/+/15880768
Change-Id: I43d514617c1e28b8794039b0854f16cd8281e1d2
2 files changed, 37 insertions, 6 deletions
diff --git a/sdk/src/main/java/com/google/android/enterprise/connectedapps/AbstractProfileConnector.java b/sdk/src/main/java/com/google/android/enterprise/connectedapps/AbstractProfileConnector.java index ae24257..cc71c7b 100644 --- a/sdk/src/main/java/com/google/android/enterprise/connectedapps/AbstractProfileConnector.java +++ b/sdk/src/main/java/com/google/android/enterprise/connectedapps/AbstractProfileConnector.java @@ -110,7 +110,6 @@ public abstract class AbstractProfileConnector /* availabilityListener= */ this, scheduledExecutorService, availabilityRestrictions); - crossProfileSender.beginMonitoringAvailabilityChanges(); } return crossProfileSender; } diff --git a/sdk/src/main/java/com/google/android/enterprise/connectedapps/CrossProfileSender.java b/sdk/src/main/java/com/google/android/enterprise/connectedapps/CrossProfileSender.java index fe34d09..9cc287b 100644 --- a/sdk/src/main/java/com/google/android/enterprise/connectedapps/CrossProfileSender.java +++ b/sdk/src/main/java/com/google/android/enterprise/connectedapps/CrossProfileSender.java @@ -18,6 +18,9 @@ package com.google.android.enterprise.connectedapps; import static com.google.android.enterprise.connectedapps.CrossProfileSDKUtilities.filterUsersByAvailabilityRestrictions; import static com.google.android.enterprise.connectedapps.CrossProfileSDKUtilities.selectUserHandleToBind; +import static java.util.Collections.newSetFromMap; +import static java.util.Collections.synchronizedSet; + import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -27,6 +30,7 @@ import android.content.ServiceConnection; import android.content.pm.CrossProfileApps; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.Parcel; @@ -41,8 +45,13 @@ import com.google.android.enterprise.connectedapps.internal.CrossProfileParcelCa import com.google.android.enterprise.connectedapps.internal.ParcelCallReceiver; import com.google.android.enterprise.connectedapps.internal.ParcelUtilities; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledExecutorService; @@ -238,6 +247,11 @@ public class CrossProfileSender { @Nullable private volatile ScheduledFuture<Void> automaticDisconnectionFuture; private final AvailabilityRestrictions availabilityRestrictions; + // This is synchronized which isn't massively performant but it only gets accessed once straight + // after creating a Sender, and once each time availability changes + private static final Set<CrossProfileSender> senders = + synchronizedSet(newSetFromMap(new WeakHashMap<>())); + private boolean isManuallyManagingConnection = false; private ConcurrentLinkedDeque<OngoingCrossProfileCall> ongoingCrossProfileCalls = new ConcurrentLinkedDeque<>(); @@ -277,13 +291,18 @@ public class CrossProfileSender { canUseReflectedApis = ReflectionUtilities.canUseReflectedApis(); this.scheduledExecutorService = scheduledExecutorService; this.availabilityRestrictions = availabilityRestrictions; + + senders.add(this); + beginMonitoringAvailabilityChanges(); } - private final BroadcastReceiver profileAvailabilityReceiver = + private static final BroadcastReceiver profileAvailabilityReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - checkAvailability(); + for (CrossProfileSender sender : senders) { + sender.scheduledExecutorService.execute(sender::checkAvailability); + } } }; @@ -370,7 +389,13 @@ public class CrossProfileSender { return null; } - void beginMonitoringAvailabilityChanges() { + private static final AtomicBoolean isMonitoringAvailabilityChanges = new AtomicBoolean(false); + + private void beginMonitoringAvailabilityChanges() { + if (isMonitoringAvailabilityChanges.getAndSet(true)) { + return; + } + IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); @@ -593,10 +618,17 @@ public class CrossProfileSender { * @throws UnavailableProfileException if a connection is not already established */ public Parcel call(long crossProfileTypeIdentifier, int methodIdentifier, Parcel params) - throws UnavailableProfileException { + throws UnavailableProfileException { try { return callWithExceptions(crossProfileTypeIdentifier, methodIdentifier, params); - } catch (UnavailableProfileException | RuntimeException e) { + } catch (UnavailableProfileException | RuntimeException | Error e) { + StackTraceElement[] remoteStack = e.getStackTrace(); + StackTraceElement[] localStack = Thread.currentThread().getStackTrace(); + StackTraceElement[] totalStack = + Arrays.copyOf(remoteStack, remoteStack.length + localStack.length - 1); + // We cut off the first element of localStack as it is just getting the stack trace + System.arraycopy(localStack, 1, totalStack, remoteStack.length, localStack.length - 1); + e.setStackTrace(totalStack); throw e; } catch (Throwable e) { throw new UnavailableProfileException("Unexpected checked exception", e); |