Merge "Avoid activity leak via Companion callback" into oc-dev

This commit is contained in:
TreeHugger Robot
2017-05-12 20:14:03 +00:00
committed by Android (Google) Code Review
4 changed files with 94 additions and 26 deletions

View File

@@ -95,7 +95,6 @@ import android.nfc.NfcManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Build;
import android.os.Debug;
import android.os.DropBoxManager;
import android.os.HardwarePropertiesManager;
import android.os.IBatteryPropertiesRegistrar;
@@ -118,8 +117,6 @@ import android.os.health.SystemHealthManager;
import android.os.storage.StorageManager;
import android.print.IPrintManager;
import android.print.PrintManager;
import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.service.oemlock.IOemLockService;
import android.service.oemlock.OemLockManager;
import android.service.persistentdata.IPersistentDataBlockService;
@@ -136,6 +133,8 @@ import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.CaptioningManager;
import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
@@ -660,7 +659,7 @@ final class SystemServiceRegistry {
ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE);
ICompanionDeviceManager service =
ICompanionDeviceManager.Stub.asInterface(iBinder);
return new CompanionDeviceManager(service, ctx);
return new CompanionDeviceManager(service, ctx.getOuterContext());
}});
registerService(Context.CONSUMER_IR_SERVICE, ConsumerIrManager.class,

View File

@@ -21,11 +21,14 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.Application;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.service.notification.NotificationListenerService;
@@ -137,26 +140,11 @@ public final class CompanionDeviceManager {
}
checkNotNull(request, "Request cannot be null");
checkNotNull(callback, "Callback cannot be null");
final Handler finalHandler = Handler.mainIfNull(handler);
try {
mService.associate(
request,
//TODO implicit pointer to outer class -> =null onDestroy
//TODO onStop if isFinishing -> stopScan
new IFindDeviceCallback.Stub() {
@Override
public void onSuccess(PendingIntent launcher) {
finalHandler.post(() -> {
callback.onDeviceFound(launcher.getIntentSender());
});
}
@Override
public void onFailure(CharSequence reason) {
finalHandler.post(() -> callback.onFailure(reason));
}
},
mContext.getPackageName());
new CallbackProxy(request, callback, Handler.mainIfNull(handler)),
getCallingPackage());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -175,7 +163,7 @@ public final class CompanionDeviceManager {
return Collections.emptyList();
}
try {
return mService.getAssociations(mContext.getPackageName(), mContext.getUserId());
return mService.getAssociations(getCallingPackage(), mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -200,7 +188,7 @@ public final class CompanionDeviceManager {
return;
}
try {
mService.disassociate(deviceMacAddress, mContext.getPackageName());
mService.disassociate(deviceMacAddress, getCallingPackage());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -263,4 +251,57 @@ public final class CompanionDeviceManager {
}
return featurePresent;
}
private Activity getActivity() {
return (Activity) mContext;
}
private String getCallingPackage() {
return mContext.getPackageName();
}
private class CallbackProxy extends IFindDeviceCallback.Stub
implements Application.ActivityLifecycleCallbacks {
private Callback mCallback;
private Handler mHandler;
private AssociationRequest mRequest;
private CallbackProxy(AssociationRequest request, Callback callback, Handler handler) {
mCallback = callback;
mHandler = handler;
mRequest = request;
getActivity().getApplication().registerActivityLifecycleCallbacks(this);
}
@Override
public void onSuccess(PendingIntent launcher) {
mHandler.post(() -> mCallback.onDeviceFound(launcher.getIntentSender()));
}
@Override
public void onFailure(CharSequence reason) {
mHandler.post(() -> mCallback.onFailure(reason));
}
@Override
public void onActivityDestroyed(Activity activity) {
try {
mService.stopScan(mRequest, this, getCallingPackage());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
getActivity().getApplication().unregisterActivityLifecycleCallbacks(this);
mCallback = null;
mHandler = null;
mRequest = null;
}
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override public void onActivityStarted(Activity activity) {}
@Override public void onActivityResumed(Activity activity) {}
@Override public void onActivityPaused(Activity activity) {}
@Override public void onActivityStopped(Activity activity) {}
@Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
}
}

View File

@@ -30,6 +30,9 @@ interface ICompanionDeviceManager {
void associate(in AssociationRequest request,
in IFindDeviceCallback callback,
in String callingPackage);
void stopScan(in AssociationRequest request,
in IFindDeviceCallback callback,
in String callingPackage);
List<String> getAssociations(String callingPackage, int userId);
void disassociate(String deviceMacAddress, String callingPackage);

View File

@@ -110,10 +110,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
private final CompanionDeviceManagerImpl mImpl;
private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>();
private IDeviceIdleController mIdleController;
private IFindDeviceCallback mFindDeviceCallback;
private ServiceConnection mServiceConnection;
private IAppOpsService mAppOpsManager;
private IFindDeviceCallback mFindDeviceCallback;
private AssociationRequest mRequest;
private String mCallingPackage;
private final Object mLock = new Object();
public CompanionDeviceManagerService(Context context) {
super(context);
mImpl = new CompanionDeviceManagerImpl();
@@ -156,8 +161,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
private void cleanup() {
mServiceConnection = unbind(mServiceConnection);
mFindDeviceCallback = unlinkToDeath(mFindDeviceCallback, this, 0);
synchronized (mLock) {
mServiceConnection = unbind(mServiceConnection);
mFindDeviceCallback = unlinkToDeath(mFindDeviceCallback, this, 0);
mRequest = null;
mCallingPackage = null;
}
}
/**
@@ -221,6 +230,17 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
}
@Override
public void stopScan(AssociationRequest request,
IFindDeviceCallback callback,
String callingPackage) {
if (Objects.equals(request, mRequest)
&& Objects.equals(callback, mFindDeviceCallback)
&& Objects.equals(callingPackage, mCallingPackage)) {
cleanup();
}
}
@Override
public List<String> getAssociations(String callingPackage, int userId)
throws RemoteException {
@@ -340,7 +360,11 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
"onServiceConnected(name = " + name + ", service = "
+ service + ")");
}
mFindDeviceCallback = findDeviceCallback;
mRequest = request;
mCallingPackage = callingPackage;
try {
mFindDeviceCallback.asBinder().linkToDeath(
CompanionDeviceManagerService.this, 0);
@@ -348,6 +372,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
cleanup();
return;
}
try {
ICompanionDeviceDiscoveryService.Stub
.asInterface(service)