Loading Android.bp +1 −25 Original line number Diff line number Diff line Loading @@ -548,33 +548,9 @@ java_library { ], } java_library { name: "framework-annotation-proc", srcs: [ ":framework-all-sources", "core/java/**/*.logtags", ], sdk_version: "core_platform", libs: [ "app-compat-annotations", "ext", "unsupportedappusage", ], installable: false, plugins: [ "compat-changeid-annotation-processor", ], static_libs: [ "framework-internal-utils", "exoplayer2-extractor", "android.hardware.wifi-V1.0-java-constants", ] } platform_compat_config { name: "framework-platform-compat-config", src: ":framework-annotation-proc", src: ":framework-minus-apex", } // A temporary build target that is conditionally included on the bootclasspath if Loading core/java/android/content/pm/PackageInstaller.java +9 −4 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.stream.Collectors; /** * Offers the ability to install, upgrade, and remove applications on the Loading Loading @@ -589,9 +588,15 @@ public class PackageInstaller { * * {@link SessionInfo#isStagedSessionActive()}. */ public @NonNull List<SessionInfo> getActiveStagedSessions() { return getStagedSessions().stream() .filter(s -> s.isStagedSessionActive()) .collect(Collectors.toList()); final List<SessionInfo> activeStagedSessions = new ArrayList<>(); final List<SessionInfo> stagedSessions = getStagedSessions(); for (int i = 0; i < stagedSessions.size(); i++) { final SessionInfo sessionInfo = stagedSessions.get(i); if (sessionInfo.isStagedSessionActive()) { activeStagedSessions.add(sessionInfo); } } return activeStagedSessions; } /** Loading core/java/android/service/contentcapture/ContentCaptureService.java +73 −9 Original line number Diff line number Diff line Loading @@ -60,7 +60,9 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -119,6 +121,9 @@ public abstract class ContentCaptureService extends Service { */ public static final String SERVICE_META_DATA = "android.content_capture"; private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager(); private Handler mHandler; private IContentCaptureServiceCallback mCallback; Loading Loading @@ -546,7 +551,8 @@ public abstract class ContentCaptureService extends Service { Preconditions.checkNotNull(executor); DataShareReadAdapterDelegate delegate = new DataShareReadAdapterDelegate(executor, adapter); new DataShareReadAdapterDelegate(executor, adapter, mDataShareAdapterResourceManager); try { callback.accept(delegate); Loading Loading @@ -653,16 +659,17 @@ public abstract class ContentCaptureService extends Service { private static class DataShareReadAdapterDelegate extends IDataShareReadAdapter.Stub { private final WeakReference<LocalDataShareAdapterResourceManager> mResourceManagerReference; private final Object mLock = new Object(); private final WeakReference<DataShareReadAdapter> mAdapterReference; private final WeakReference<Executor> mExecutorReference; DataShareReadAdapterDelegate(Executor executor, DataShareReadAdapter adapter) { DataShareReadAdapterDelegate(Executor executor, DataShareReadAdapter adapter, LocalDataShareAdapterResourceManager resourceManager) { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(adapter); Preconditions.checkNotNull(resourceManager); mExecutorReference = new WeakReference<>(executor); mAdapterReference = new WeakReference<>(adapter); resourceManager.initializeForDelegate(this, adapter, executor); mResourceManagerReference = new WeakReference<>(resourceManager); } @Override Loading @@ -670,6 +677,10 @@ public abstract class ContentCaptureService extends Service { throws RemoteException { synchronized (mLock) { executeAdapterMethodLocked(adapter -> adapter.onStart(fd), "onStart"); // Client app and Service successfully connected, so this object would be kept alive // until the session has finished. clearHardReferences(); } } Loading @@ -678,16 +689,23 @@ public abstract class ContentCaptureService extends Service { synchronized (mLock) { executeAdapterMethodLocked( adapter -> adapter.onError(errorCode), "onError"); clearHardReferences(); } } private void executeAdapterMethodLocked(Consumer<DataShareReadAdapter> adapterFn, String methodName) { DataShareReadAdapter adapter = mAdapterReference.get(); Executor executor = mExecutorReference.get(); LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't execute " + methodName + "(), resource manager has been GC'ed"); return; } DataShareReadAdapter adapter = resourceManager.getAdapter(this); Executor executor = resourceManager.getExecutor(this); if (adapter == null || executor == null) { Slog.w(TAG, "Can't execute " + methodName + "(), references have been GC'ed"); Slog.w(TAG, "Can't execute " + methodName + "(), references are null"); return; } Loading @@ -698,5 +716,51 @@ public abstract class ContentCaptureService extends Service { Binder.restoreCallingIdentity(identity); } } private void clearHardReferences() { LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't clear references, resource manager has been GC'ed"); return; } resourceManager.clearHardReferences(this); } } /** * Wrapper class making sure dependencies on the current application stay in the application * context. */ private static class LocalDataShareAdapterResourceManager { // Keeping hard references to the remote objects in the current process (static context) // to prevent them to be gc'ed during the lifetime of the application. This is an // artifact of only operating with weak references remotely: there has to be at least 1 // hard reference in order for this to not be killed. private Map<DataShareReadAdapterDelegate, DataShareReadAdapter> mDataShareReadAdapterHardReferences = new HashMap<>(); private Map<DataShareReadAdapterDelegate, Executor> mExecutorHardReferences = new HashMap<>(); void initializeForDelegate(DataShareReadAdapterDelegate delegate, DataShareReadAdapter adapter, Executor executor) { mDataShareReadAdapterHardReferences.put(delegate, adapter); mExecutorHardReferences.remove(delegate, executor); } Executor getExecutor(DataShareReadAdapterDelegate delegate) { return mExecutorHardReferences.get(delegate); } DataShareReadAdapter getAdapter(DataShareReadAdapterDelegate delegate) { return mDataShareReadAdapterHardReferences.get(delegate); } void clearHardReferences(DataShareReadAdapterDelegate delegate) { mDataShareReadAdapterHardReferences.remove(delegate); mExecutorHardReferences.remove(delegate); } } } core/java/android/view/contentcapture/ContentCaptureManager.java +75 −9 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -360,6 +362,9 @@ public final class ContentCaptureManager { @NonNull private final IContentCaptureManager mService; @GuardedBy("mLock") private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager; @NonNull final ContentCaptureOptions mOptions; Loading Loading @@ -399,6 +404,8 @@ public final class ContentCaptureManager { // do, then we should optimize it to run the tests after the Choreographer finishes the most // important steps of the frame. mHandler = Handler.createAsync(Looper.getMainLooper()); mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager(); } /** Loading Loading @@ -681,7 +688,8 @@ public final class ContentCaptureManager { try { mService.shareData(request, new DataShareAdapterDelegate(executor, dataShareWriteAdapter)); new DataShareAdapterDelegate(executor, dataShareWriteAdapter, mDataShareAdapterResourceManager)); } catch (RemoteException e) { e.rethrowFromSystemServer(); } Loading Loading @@ -737,40 +745,53 @@ public final class ContentCaptureManager { private static class DataShareAdapterDelegate extends IDataShareWriteAdapter.Stub { private final WeakReference<DataShareWriteAdapter> mAdapterReference; private final WeakReference<Executor> mExecutorReference; private final WeakReference<LocalDataShareAdapterResourceManager> mResourceManagerReference; private DataShareAdapterDelegate(Executor executor, DataShareWriteAdapter adapter) { private DataShareAdapterDelegate(Executor executor, DataShareWriteAdapter adapter, LocalDataShareAdapterResourceManager resourceManager) { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(adapter); Preconditions.checkNotNull(resourceManager); mExecutorReference = new WeakReference<>(executor); mAdapterReference = new WeakReference<>(adapter); resourceManager.initializeForDelegate(this, adapter, executor); mResourceManagerReference = new WeakReference<>(resourceManager); } @Override public void write(ParcelFileDescriptor destination) throws RemoteException { executeAdapterMethodLocked(adapter -> adapter.onWrite(destination), "onWrite"); // Client app and Service successfully connected, so this object would be kept alive // until the session has finished. clearHardReferences(); } @Override public void error(int errorCode) throws RemoteException { executeAdapterMethodLocked(adapter -> adapter.onError(errorCode), "onError"); clearHardReferences(); } @Override public void rejected() throws RemoteException { executeAdapterMethodLocked(DataShareWriteAdapter::onRejected, "onRejected"); clearHardReferences(); } private void executeAdapterMethodLocked(Consumer<DataShareWriteAdapter> adapterFn, String methodName) { DataShareWriteAdapter adapter = mAdapterReference.get(); Executor executor = mExecutorReference.get(); LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't execute " + methodName + "(), resource manager has been GC'ed"); return; } DataShareWriteAdapter adapter = resourceManager.getAdapter(this); Executor executor = resourceManager.getExecutor(this); if (adapter == null || executor == null) { Slog.w(TAG, "Can't execute " + methodName + "(), references have been GC'ed"); Slog.w(TAG, "Can't execute " + methodName + "(), references are null"); return; } Loading @@ -781,5 +802,50 @@ public final class ContentCaptureManager { Binder.restoreCallingIdentity(identity); } } private void clearHardReferences() { LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't clear references, resource manager has been GC'ed"); return; } resourceManager.clearHardReferences(this); } } /** * Wrapper class making sure dependencies on the current application stay in the application * context. */ private static class LocalDataShareAdapterResourceManager { // Keeping hard references to the remote objects in the current process (static context) // to prevent them to be gc'ed during the lifetime of the application. This is an // artifact of only operating with weak references remotely: there has to be at least 1 // hard reference in order for this to not be killed. private Map<DataShareAdapterDelegate, DataShareWriteAdapter> mWriteAdapterHardReferences = new HashMap<>(); private Map<DataShareAdapterDelegate, Executor> mExecutorHardReferences = new HashMap<>(); void initializeForDelegate(DataShareAdapterDelegate delegate, DataShareWriteAdapter adapter, Executor executor) { mWriteAdapterHardReferences.put(delegate, adapter); mExecutorHardReferences.remove(delegate, executor); } Executor getExecutor(DataShareAdapterDelegate delegate) { return mExecutorHardReferences.get(delegate); } DataShareWriteAdapter getAdapter(DataShareAdapterDelegate delegate) { return mWriteAdapterHardReferences.get(delegate); } void clearHardReferences(DataShareAdapterDelegate delegate) { mWriteAdapterHardReferences.remove(delegate); mExecutorHardReferences.remove(delegate); } } } data/etc/services.core.protolog.json +18 −24 Original line number Diff line number Diff line Loading @@ -193,12 +193,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowState.java" }, "-1741065110": { "message": "No app is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "-1730156332": { "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "level": "VERBOSE", Loading Loading @@ -547,6 +541,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransitionController.java" }, "-993446393": { "message": "App is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "-993378225": { "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", "level": "VERBOSE", Loading Loading @@ -715,12 +715,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, "-650040763": { "message": "rotationForOrientation(orient=%d, last=%d); user=%d %s", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, "-639305784": { "message": "Could not report config changes to the window token client.", "level": "WARN", Loading Loading @@ -1021,12 +1015,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "44438983": { "message": "performLayout: Activity exiting now removed %s", "level": "VERBOSE", "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "45285419": { "message": "startingWindow was set but startingSurface==null, couldn't remove", "level": "VERBOSE", Loading Loading @@ -1087,6 +1075,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, "137835146": { "message": "No app is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "140319294": { "message": "IME target changed within ActivityRecord", "level": "DEBUG", Loading Loading @@ -1531,12 +1525,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, "845234215": { "message": "App is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "853091290": { "message": "Moved stack=%s behind stack=%s", "level": "DEBUG", Loading Loading @@ -1927,6 +1915,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "1685441447": { "message": "performLayout: Activity exiting now removed %s", "level": "VERBOSE", "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "1720229827": { "message": "Creating animation bounds layer", "level": "INFO", Loading Loading
Android.bp +1 −25 Original line number Diff line number Diff line Loading @@ -548,33 +548,9 @@ java_library { ], } java_library { name: "framework-annotation-proc", srcs: [ ":framework-all-sources", "core/java/**/*.logtags", ], sdk_version: "core_platform", libs: [ "app-compat-annotations", "ext", "unsupportedappusage", ], installable: false, plugins: [ "compat-changeid-annotation-processor", ], static_libs: [ "framework-internal-utils", "exoplayer2-extractor", "android.hardware.wifi-V1.0-java-constants", ] } platform_compat_config { name: "framework-platform-compat-config", src: ":framework-annotation-proc", src: ":framework-minus-apex", } // A temporary build target that is conditionally included on the bootclasspath if Loading
core/java/android/content/pm/PackageInstaller.java +9 −4 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.stream.Collectors; /** * Offers the ability to install, upgrade, and remove applications on the Loading Loading @@ -589,9 +588,15 @@ public class PackageInstaller { * * {@link SessionInfo#isStagedSessionActive()}. */ public @NonNull List<SessionInfo> getActiveStagedSessions() { return getStagedSessions().stream() .filter(s -> s.isStagedSessionActive()) .collect(Collectors.toList()); final List<SessionInfo> activeStagedSessions = new ArrayList<>(); final List<SessionInfo> stagedSessions = getStagedSessions(); for (int i = 0; i < stagedSessions.size(); i++) { final SessionInfo sessionInfo = stagedSessions.get(i); if (sessionInfo.isStagedSessionActive()) { activeStagedSessions.add(sessionInfo); } } return activeStagedSessions; } /** Loading
core/java/android/service/contentcapture/ContentCaptureService.java +73 −9 Original line number Diff line number Diff line Loading @@ -60,7 +60,9 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -119,6 +121,9 @@ public abstract class ContentCaptureService extends Service { */ public static final String SERVICE_META_DATA = "android.content_capture"; private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager(); private Handler mHandler; private IContentCaptureServiceCallback mCallback; Loading Loading @@ -546,7 +551,8 @@ public abstract class ContentCaptureService extends Service { Preconditions.checkNotNull(executor); DataShareReadAdapterDelegate delegate = new DataShareReadAdapterDelegate(executor, adapter); new DataShareReadAdapterDelegate(executor, adapter, mDataShareAdapterResourceManager); try { callback.accept(delegate); Loading Loading @@ -653,16 +659,17 @@ public abstract class ContentCaptureService extends Service { private static class DataShareReadAdapterDelegate extends IDataShareReadAdapter.Stub { private final WeakReference<LocalDataShareAdapterResourceManager> mResourceManagerReference; private final Object mLock = new Object(); private final WeakReference<DataShareReadAdapter> mAdapterReference; private final WeakReference<Executor> mExecutorReference; DataShareReadAdapterDelegate(Executor executor, DataShareReadAdapter adapter) { DataShareReadAdapterDelegate(Executor executor, DataShareReadAdapter adapter, LocalDataShareAdapterResourceManager resourceManager) { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(adapter); Preconditions.checkNotNull(resourceManager); mExecutorReference = new WeakReference<>(executor); mAdapterReference = new WeakReference<>(adapter); resourceManager.initializeForDelegate(this, adapter, executor); mResourceManagerReference = new WeakReference<>(resourceManager); } @Override Loading @@ -670,6 +677,10 @@ public abstract class ContentCaptureService extends Service { throws RemoteException { synchronized (mLock) { executeAdapterMethodLocked(adapter -> adapter.onStart(fd), "onStart"); // Client app and Service successfully connected, so this object would be kept alive // until the session has finished. clearHardReferences(); } } Loading @@ -678,16 +689,23 @@ public abstract class ContentCaptureService extends Service { synchronized (mLock) { executeAdapterMethodLocked( adapter -> adapter.onError(errorCode), "onError"); clearHardReferences(); } } private void executeAdapterMethodLocked(Consumer<DataShareReadAdapter> adapterFn, String methodName) { DataShareReadAdapter adapter = mAdapterReference.get(); Executor executor = mExecutorReference.get(); LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't execute " + methodName + "(), resource manager has been GC'ed"); return; } DataShareReadAdapter adapter = resourceManager.getAdapter(this); Executor executor = resourceManager.getExecutor(this); if (adapter == null || executor == null) { Slog.w(TAG, "Can't execute " + methodName + "(), references have been GC'ed"); Slog.w(TAG, "Can't execute " + methodName + "(), references are null"); return; } Loading @@ -698,5 +716,51 @@ public abstract class ContentCaptureService extends Service { Binder.restoreCallingIdentity(identity); } } private void clearHardReferences() { LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't clear references, resource manager has been GC'ed"); return; } resourceManager.clearHardReferences(this); } } /** * Wrapper class making sure dependencies on the current application stay in the application * context. */ private static class LocalDataShareAdapterResourceManager { // Keeping hard references to the remote objects in the current process (static context) // to prevent them to be gc'ed during the lifetime of the application. This is an // artifact of only operating with weak references remotely: there has to be at least 1 // hard reference in order for this to not be killed. private Map<DataShareReadAdapterDelegate, DataShareReadAdapter> mDataShareReadAdapterHardReferences = new HashMap<>(); private Map<DataShareReadAdapterDelegate, Executor> mExecutorHardReferences = new HashMap<>(); void initializeForDelegate(DataShareReadAdapterDelegate delegate, DataShareReadAdapter adapter, Executor executor) { mDataShareReadAdapterHardReferences.put(delegate, adapter); mExecutorHardReferences.remove(delegate, executor); } Executor getExecutor(DataShareReadAdapterDelegate delegate) { return mExecutorHardReferences.get(delegate); } DataShareReadAdapter getAdapter(DataShareReadAdapterDelegate delegate) { return mDataShareReadAdapterHardReferences.get(delegate); } void clearHardReferences(DataShareReadAdapterDelegate delegate) { mDataShareReadAdapterHardReferences.remove(delegate); mExecutorHardReferences.remove(delegate); } } }
core/java/android/view/contentcapture/ContentCaptureManager.java +75 −9 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; Loading Loading @@ -360,6 +362,9 @@ public final class ContentCaptureManager { @NonNull private final IContentCaptureManager mService; @GuardedBy("mLock") private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager; @NonNull final ContentCaptureOptions mOptions; Loading Loading @@ -399,6 +404,8 @@ public final class ContentCaptureManager { // do, then we should optimize it to run the tests after the Choreographer finishes the most // important steps of the frame. mHandler = Handler.createAsync(Looper.getMainLooper()); mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager(); } /** Loading Loading @@ -681,7 +688,8 @@ public final class ContentCaptureManager { try { mService.shareData(request, new DataShareAdapterDelegate(executor, dataShareWriteAdapter)); new DataShareAdapterDelegate(executor, dataShareWriteAdapter, mDataShareAdapterResourceManager)); } catch (RemoteException e) { e.rethrowFromSystemServer(); } Loading Loading @@ -737,40 +745,53 @@ public final class ContentCaptureManager { private static class DataShareAdapterDelegate extends IDataShareWriteAdapter.Stub { private final WeakReference<DataShareWriteAdapter> mAdapterReference; private final WeakReference<Executor> mExecutorReference; private final WeakReference<LocalDataShareAdapterResourceManager> mResourceManagerReference; private DataShareAdapterDelegate(Executor executor, DataShareWriteAdapter adapter) { private DataShareAdapterDelegate(Executor executor, DataShareWriteAdapter adapter, LocalDataShareAdapterResourceManager resourceManager) { Preconditions.checkNotNull(executor); Preconditions.checkNotNull(adapter); Preconditions.checkNotNull(resourceManager); mExecutorReference = new WeakReference<>(executor); mAdapterReference = new WeakReference<>(adapter); resourceManager.initializeForDelegate(this, adapter, executor); mResourceManagerReference = new WeakReference<>(resourceManager); } @Override public void write(ParcelFileDescriptor destination) throws RemoteException { executeAdapterMethodLocked(adapter -> adapter.onWrite(destination), "onWrite"); // Client app and Service successfully connected, so this object would be kept alive // until the session has finished. clearHardReferences(); } @Override public void error(int errorCode) throws RemoteException { executeAdapterMethodLocked(adapter -> adapter.onError(errorCode), "onError"); clearHardReferences(); } @Override public void rejected() throws RemoteException { executeAdapterMethodLocked(DataShareWriteAdapter::onRejected, "onRejected"); clearHardReferences(); } private void executeAdapterMethodLocked(Consumer<DataShareWriteAdapter> adapterFn, String methodName) { DataShareWriteAdapter adapter = mAdapterReference.get(); Executor executor = mExecutorReference.get(); LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't execute " + methodName + "(), resource manager has been GC'ed"); return; } DataShareWriteAdapter adapter = resourceManager.getAdapter(this); Executor executor = resourceManager.getExecutor(this); if (adapter == null || executor == null) { Slog.w(TAG, "Can't execute " + methodName + "(), references have been GC'ed"); Slog.w(TAG, "Can't execute " + methodName + "(), references are null"); return; } Loading @@ -781,5 +802,50 @@ public final class ContentCaptureManager { Binder.restoreCallingIdentity(identity); } } private void clearHardReferences() { LocalDataShareAdapterResourceManager resourceManager = mResourceManagerReference.get(); if (resourceManager == null) { Slog.w(TAG, "Can't clear references, resource manager has been GC'ed"); return; } resourceManager.clearHardReferences(this); } } /** * Wrapper class making sure dependencies on the current application stay in the application * context. */ private static class LocalDataShareAdapterResourceManager { // Keeping hard references to the remote objects in the current process (static context) // to prevent them to be gc'ed during the lifetime of the application. This is an // artifact of only operating with weak references remotely: there has to be at least 1 // hard reference in order for this to not be killed. private Map<DataShareAdapterDelegate, DataShareWriteAdapter> mWriteAdapterHardReferences = new HashMap<>(); private Map<DataShareAdapterDelegate, Executor> mExecutorHardReferences = new HashMap<>(); void initializeForDelegate(DataShareAdapterDelegate delegate, DataShareWriteAdapter adapter, Executor executor) { mWriteAdapterHardReferences.put(delegate, adapter); mExecutorHardReferences.remove(delegate, executor); } Executor getExecutor(DataShareAdapterDelegate delegate) { return mExecutorHardReferences.get(delegate); } DataShareWriteAdapter getAdapter(DataShareAdapterDelegate delegate) { return mWriteAdapterHardReferences.get(delegate); } void clearHardReferences(DataShareAdapterDelegate delegate) { mWriteAdapterHardReferences.remove(delegate); mExecutorHardReferences.remove(delegate); } } }
data/etc/services.core.protolog.json +18 −24 Original line number Diff line number Diff line Loading @@ -193,12 +193,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowState.java" }, "-1741065110": { "message": "No app is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "-1730156332": { "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "level": "VERBOSE", Loading Loading @@ -547,6 +541,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransitionController.java" }, "-993446393": { "message": "App is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "-993378225": { "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", "level": "VERBOSE", Loading Loading @@ -715,12 +715,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, "-650040763": { "message": "rotationForOrientation(orient=%d, last=%d); user=%d %s", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, "-639305784": { "message": "Could not report config changes to the window token client.", "level": "WARN", Loading Loading @@ -1021,12 +1015,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "44438983": { "message": "performLayout: Activity exiting now removed %s", "level": "VERBOSE", "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "45285419": { "message": "startingWindow was set but startingSurface==null, couldn't remove", "level": "VERBOSE", Loading Loading @@ -1087,6 +1075,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, "137835146": { "message": "No app is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "140319294": { "message": "IME target changed within ActivityRecord", "level": "DEBUG", Loading Loading @@ -1531,12 +1525,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, "845234215": { "message": "App is requesting an orientation, return %d for display id=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, "853091290": { "message": "Moved stack=%s behind stack=%s", "level": "DEBUG", Loading Loading @@ -1927,6 +1915,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "1685441447": { "message": "performLayout: Activity exiting now removed %s", "level": "VERBOSE", "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/TaskContainers.java" }, "1720229827": { "message": "Creating animation bounds layer", "level": "INFO", Loading