Snap for 6345044 from d6503d5cfd3b65e3ee7925c94f111480d321aec3 to rvc-d1-release
Change-Id: I8d6652bff70b310c0fd3e1b56325f21358d93f1a
diff --git a/Android.bp b/Android.bp
index be1aefc..30d4409 100644
--- a/Android.bp
+++ b/Android.bp
@@ -548,33 +548,9 @@
],
}
-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
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 61744e42..ef55f06 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -60,7 +60,9 @@
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;
@@ -119,6 +121,9 @@
*/
public static final String SERVICE_META_DATA = "android.content_capture";
+ private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager =
+ new LocalDataShareAdapterResourceManager();
+
private Handler mHandler;
private IContentCaptureServiceCallback mCallback;
@@ -546,7 +551,8 @@
Preconditions.checkNotNull(executor);
DataShareReadAdapterDelegate delegate =
- new DataShareReadAdapterDelegate(executor, adapter);
+ new DataShareReadAdapterDelegate(executor, adapter,
+ mDataShareAdapterResourceManager);
try {
callback.accept(delegate);
@@ -653,16 +659,17 @@
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
@@ -670,6 +677,10 @@
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();
}
}
@@ -678,16 +689,23 @@
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;
}
@@ -698,5 +716,51 @@
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);
+ }
}
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 954b83b..edc6b12 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -54,6 +54,8 @@
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;
@@ -360,6 +362,9 @@
@NonNull
private final IContentCaptureManager mService;
+ @GuardedBy("mLock")
+ private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager;
+
@NonNull
final ContentCaptureOptions mOptions;
@@ -399,6 +404,8 @@
// 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();
}
/**
@@ -681,7 +688,8 @@
try {
mService.shareData(request,
- new DataShareAdapterDelegate(executor, dataShareWriteAdapter));
+ new DataShareAdapterDelegate(executor, dataShareWriteAdapter,
+ mDataShareAdapterResourceManager));
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -737,40 +745,53 @@
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;
}
@@ -781,5 +802,50 @@
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);
+ }
}
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 99605ad..a871047 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -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",
@@ -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",
@@ -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",
@@ -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",
@@ -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",
@@ -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",
@@ -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",
diff --git a/services/Android.bp b/services/Android.bp
index 1ce7dcf..730b9a5 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -81,10 +81,6 @@
"framework-tethering-stubs-module_libs_api",
],
- plugins: [
- "compat-changeid-annotation-processor",
- ],
-
// Uncomment to enable output of certain warnings (deprecated, unchecked)
//javacflags: ["-Xlint"],
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 5d2b9f3..ce539da 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -89,7 +89,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -919,35 +918,24 @@
private static class DataShareCallbackDelegate extends IDataShareCallback.Stub {
@NonNull private final DataShareRequest mDataShareRequest;
- @NonNull private final WeakReference<IDataShareWriteAdapter> mClientAdapterReference;
- @NonNull private final WeakReference<ContentCaptureManagerService> mParentServiceReference;
+ @NonNull private final IDataShareWriteAdapter mClientAdapter;
+ @NonNull private final ContentCaptureManagerService mParentService;
DataShareCallbackDelegate(@NonNull DataShareRequest dataShareRequest,
@NonNull IDataShareWriteAdapter clientAdapter,
ContentCaptureManagerService parentService) {
mDataShareRequest = dataShareRequest;
- mClientAdapterReference = new WeakReference<>(clientAdapter);
- mParentServiceReference = new WeakReference<>(parentService);
+ mClientAdapter = clientAdapter;
+ mParentService = parentService;
}
@Override
public void accept(IDataShareReadAdapter serviceAdapter) throws RemoteException {
Slog.i(TAG, "Data share request accepted by Content Capture service");
- final ContentCaptureManagerService parentService = mParentServiceReference.get();
- final IDataShareWriteAdapter clientAdapter = mClientAdapterReference.get();
- if (parentService == null || clientAdapter == null) {
- Slog.w(TAG, "Can't fulfill accept() request, because remote objects have been "
- + "GC'ed");
- return;
- }
-
- final WeakReference<IDataShareReadAdapter> serviceAdapterReference =
- new WeakReference<>(serviceAdapter);
-
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
if (clientPipe == null) {
- clientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ mClientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
@@ -959,7 +947,7 @@
if (servicePipe == null) {
bestEffortCloseFileDescriptors(sourceIn, sinkIn);
- clientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ mClientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
@@ -967,9 +955,9 @@
ParcelFileDescriptor sourceOut = servicePipe.second;
ParcelFileDescriptor sinkOut = servicePipe.first;
- parentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
+ mParentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
- clientAdapter.write(sourceIn);
+ mClientAdapter.write(sourceIn);
serviceAdapter.start(sinkOut);
// File descriptor received by the client app will be a copy of the current one. Close
@@ -977,7 +965,7 @@
// current pipe.
bestEffortCloseFileDescriptor(sourceIn);
- parentService.mDataShareExecutor.execute(() -> {
+ mParentService.mDataShareExecutor.execute(() -> {
try (InputStream fis =
new ParcelFileDescriptor.AutoCloseInputStream(sinkIn);
OutputStream fos =
@@ -996,23 +984,23 @@
} catch (IOException e) {
Slog.e(TAG, "Failed to pipe client and service streams", e);
- sendErrorSignal(mClientAdapterReference, serviceAdapterReference,
+ sendErrorSignal(mClientAdapter, serviceAdapter,
ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
} finally {
- synchronized (parentService.mLock) {
- parentService.mPackagesWithShareRequests
+ synchronized (mParentService.mLock) {
+ mParentService.mPackagesWithShareRequests
.remove(mDataShareRequest.getPackageName());
}
}
});
- parentService.mHandler.postDelayed(() ->
+ mParentService.mHandler.postDelayed(() ->
enforceDataSharingTtl(
sourceIn,
sinkIn,
sourceOut,
sinkOut,
- serviceAdapterReference),
+ serviceAdapter),
MAX_DATA_SHARE_FILE_DESCRIPTORS_TTL_MS);
}
@@ -1020,31 +1008,17 @@
public void reject() throws RemoteException {
Slog.i(TAG, "Data share request rejected by Content Capture service");
- IDataShareWriteAdapter clientAdapter = mClientAdapterReference.get();
- if (clientAdapter == null) {
- Slog.w(TAG, "Can't fulfill reject() request, because remote objects have been "
- + "GC'ed");
- return;
- }
-
- clientAdapter.rejected();
+ mClientAdapter.rejected();
}
private void enforceDataSharingTtl(ParcelFileDescriptor sourceIn,
ParcelFileDescriptor sinkIn,
ParcelFileDescriptor sourceOut,
ParcelFileDescriptor sinkOut,
- WeakReference<IDataShareReadAdapter> serviceAdapterReference) {
+ IDataShareReadAdapter serviceAdapter) {
- final ContentCaptureManagerService parentService = mParentServiceReference.get();
- if (parentService == null) {
- Slog.w(TAG, "Can't enforce data sharing TTL, because remote objects have been "
- + "GC'ed");
- return;
- }
-
- synchronized (parentService.mLock) {
- parentService.mPackagesWithShareRequests
+ synchronized (mParentService.mLock) {
+ mParentService.mPackagesWithShareRequests
.remove(mDataShareRequest.getPackageName());
// Interaction finished successfully <=> all data has been written to Content
@@ -1069,7 +1043,7 @@
bestEffortCloseFileDescriptors(sourceIn, sinkIn, sourceOut, sinkOut);
if (!finishedSuccessfully) {
- sendErrorSignal(mClientAdapterReference, serviceAdapterReference,
+ sendErrorSignal(mClientAdapter, serviceAdapter,
ContentCaptureManager.DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED);
}
}
@@ -1115,19 +1089,9 @@
}
private static void sendErrorSignal(
- WeakReference<IDataShareWriteAdapter> clientAdapterReference,
- WeakReference<IDataShareReadAdapter> serviceAdapterReference,
+ IDataShareWriteAdapter clientAdapter,
+ IDataShareReadAdapter serviceAdapter,
int errorCode) {
-
- final IDataShareWriteAdapter clientAdapter = clientAdapterReference.get();
- final IDataShareReadAdapter serviceAdapter = serviceAdapterReference.get();
-
- if (clientAdapter == null || serviceAdapter == null) {
- Slog.w(TAG, "Can't propagate error() to read/write data share adapters, because "
- + "remote objects have been GC'ed");
- return;
- }
-
try {
clientAdapter.error(errorCode);
} catch (RemoteException e) {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 7a26b21..dcf7615 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -130,10 +130,6 @@
"netd_event_listener_interface-java",
"overlayable_policy_aidl-java",
],
-
- plugins: [
- "compat-changeid-annotation-processor",
- ],
}
java_genrule {
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index 0ec0c7b..3c083e1 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -19,8 +19,6 @@
import android.content.res.Resources;
import android.text.TextUtils;
-import com.android.server.wm.DisplayContent.TaskContainers;
-
/**
* Policy that manages DisplayAreas.
*/
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 9fc90da..5900ae8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -32,9 +32,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -79,7 +77,6 @@
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
-import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
@@ -108,7 +105,6 @@
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
-import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
@@ -289,7 +285,7 @@
/** The containers below are the only child containers {@link #mWindowContainers} can have. */
// Contains all window containers that are related to apps (Activities)
- private final TaskContainers mTaskContainers = new TaskContainers(mWmService);
+ private final TaskContainers mTaskContainers = new TaskContainers(this, mWmService);
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
@@ -579,10 +575,6 @@
// Last systemUiVisibility we dispatched to windows.
private int mLastDispatchedSystemUiVisibility = 0;
- private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
- private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
- private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
-
/** Corner radius that windows should have in order to match the display. */
private final float mWindowCornerRadius;
@@ -4260,531 +4252,6 @@
}
}
- /**
- * Window container class that contains all containers on this display relating to Apps.
- * I.e Activities.
- */
- final class TaskContainers extends DisplayArea<ActivityStack> {
- /**
- * A control placed at the appropriate level for transitions to occur.
- */
- SurfaceControl mAppAnimationLayer = null;
- SurfaceControl mBoostedAppAnimationLayer = null;
- SurfaceControl mHomeAppAnimationLayer = null;
-
- /**
- * Given that the split-screen divider does not have an AppWindowToken, it
- * will have to live inside of a "NonAppWindowContainer". However, in visual Z order
- * it will need to be interleaved with some of our children, appearing on top of
- * both docked stacks but underneath any assistant stacks.
- *
- * To solve this problem we have this anchor control, which will always exist so
- * we can always assign it the correct value in our {@link #assignChildLayers}.
- * Likewise since it always exists, we can always
- * assign the divider a layer relative to it. This way we prevent linking lifecycle
- * events between tasks and the divider window.
- */
- SurfaceControl mSplitScreenDividerAnchor = null;
-
- // Cached reference to some special tasks we tend to get a lot so we don't need to loop
- // through the list to find them.
- private ActivityStack mRootHomeTask = null;
- private ActivityStack mRootPinnedTask = null;
- private ActivityStack mRootSplitScreenPrimaryTask = null;
-
- TaskContainers(WindowManagerService service) {
- super(service, Type.ANY, "TaskContainers", FEATURE_TASK_CONTAINER);
- }
-
- /**
- * Returns the topmost stack on the display that is compatible with the input windowing mode
- * and activity type. Null is no compatible stack on the display.
- */
- ActivityStack getStack(int windowingMode, int activityType) {
- if (activityType == ACTIVITY_TYPE_HOME) {
- return mRootHomeTask;
- }
- if (windowingMode == WINDOWING_MODE_PINNED) {
- return mRootPinnedTask;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- return mRootSplitScreenPrimaryTask;
- }
- for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = mTaskContainers.getChildAt(i);
- if (activityType == ACTIVITY_TYPE_UNDEFINED
- && windowingMode == stack.getWindowingMode()) {
- // Passing in undefined type means we want to match the topmost stack with the
- // windowing mode.
- return stack;
- }
- if (stack.isCompatible(windowingMode, activityType)) {
- return stack;
- }
- }
- return null;
- }
-
- @VisibleForTesting
- ActivityStack getTopStack() {
- final int count = mTaskContainers.getChildCount();
- return count > 0 ? mTaskContainers.getChildAt(count - 1) : null;
- }
-
- int getIndexOf(ActivityStack stack) {
- return mTaskContainers.mChildren.indexOf(stack);
- }
-
- ActivityStack getRootHomeTask() {
- return mRootHomeTask;
- }
-
- ActivityStack getRootPinnedTask() {
- return mRootPinnedTask;
- }
-
- ActivityStack getRootSplitScreenPrimaryTask() {
- return mRootSplitScreenPrimaryTask;
- }
-
- ArrayList<Task> getVisibleTasks() {
- final ArrayList<Task> visibleTasks = new ArrayList<>();
- forAllTasks(task -> {
- if (task.isLeafTask() && task.isVisible()) {
- visibleTasks.add(task);
- }
- });
- return visibleTasks;
- }
-
- void onStackWindowingModeChanged(ActivityStack stack) {
- removeStackReferenceIfNeeded(stack);
- addStackReferenceIfNeeded(stack);
- if (stack == mRootPinnedTask && getTopStack() != stack) {
- // Looks like this stack changed windowing mode to pinned. Move it to the top.
- positionChildAt(POSITION_TOP, stack, false /* includingParents */);
- }
- }
-
- private void addStackReferenceIfNeeded(ActivityStack stack) {
- if (stack.isActivityTypeHome()) {
- if (mRootHomeTask != null) {
- if (!stack.isDescendantOf(mRootHomeTask)) {
- throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
- + mRootHomeTask + " already exist on display=" + this
- + " stack=" + stack);
- }
- } else {
- mRootHomeTask = stack;
- }
- }
-
- if (!stack.isRootTask()) {
- return;
- }
- final int windowingMode = stack.getWindowingMode();
- if (windowingMode == WINDOWING_MODE_PINNED) {
- if (mRootPinnedTask != null) {
- throw new IllegalArgumentException(
- "addStackReferenceIfNeeded: pinned stack=" + mRootPinnedTask
- + " already exist on display=" + this + " stack=" + stack);
- }
- mRootPinnedTask = stack;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- if (mRootSplitScreenPrimaryTask != null) {
- throw new IllegalArgumentException(
- "addStackReferenceIfNeeded: split screen primary stack="
- + mRootSplitScreenPrimaryTask
- + " already exist on display=" + this + " stack=" + stack);
- }
- mRootSplitScreenPrimaryTask = stack;
- }
- }
-
- void removeStackReferenceIfNeeded(ActivityStack stack) {
- if (stack == mRootHomeTask) {
- mRootHomeTask = null;
- } else if (stack == mRootPinnedTask) {
- mRootPinnedTask = null;
- } else if (stack == mRootSplitScreenPrimaryTask) {
- mRootSplitScreenPrimaryTask = null;
- }
- }
-
- @Override
- void addChild(ActivityStack stack, int position) {
- addStackReferenceIfNeeded(stack);
- position = findPositionForStack(position, stack, true /* adding */);
-
- super.addChild(stack, position);
- mAtmService.updateSleepIfNeededLocked();
-
- // The reparenting case is handled in WindowContainer.
- if (!stack.mReparenting) {
- setLayoutNeeded();
- }
- }
-
- @Override
- protected void removeChild(ActivityStack stack) {
- super.removeChild(stack);
- mDisplayContent.onStackRemoved(stack);
- mAtmService.updateSleepIfNeededLocked();
- removeStackReferenceIfNeeded(stack);
- }
-
- @Override
- boolean isOnTop() {
- // Considered always on top
- return true;
- }
-
- @Override
- void positionChildAt(int position, ActivityStack child, boolean includingParents) {
- final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
- final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
- if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
- // This stack is always-on-top, override the default behavior.
- Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
-
- // Moving to its current position, as we must call super but we don't want to
- // perform any meaningful action.
- final int currentPosition = mChildren.indexOf(child);
- super.positionChildAt(currentPosition, child, false /* includingParents */);
- return;
- }
- // We don't allow untrusted display to top when task stack moves to top,
- // until user tapping this display to change display position as top intentionally.
- if (isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
- includingParents = false;
- }
- final int targetPosition = findPositionForStack(position, child, false /* adding */);
- super.positionChildAt(targetPosition, child, false /* includingParents */);
-
- if (includingParents && (moveToTop || moveToBottom)) {
- // The DisplayContent children do not re-order, but we still want to move the
- // display of this stack container because the intention of positioning is to have
- // higher z-order to gain focus.
- positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
- true /* includingParents */);
- }
-
- child.updateTaskMovement(moveToTop);
-
- setLayoutNeeded();
- }
-
- /**
- * When stack is added or repositioned, find a proper position for it.
- * This will make sure that pinned stack always stays on top.
- * @param requestedPosition Position requested by caller.
- * @param stack Stack to be added or positioned.
- * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
- * @return The proper position for the stack.
- */
- private int findPositionForStack(int requestedPosition, ActivityStack stack,
- boolean adding) {
- if (stack.isActivityTypeDream()) {
- return POSITION_TOP;
- }
-
- if (stack.inPinnedWindowingMode()) {
- return POSITION_TOP;
- }
-
- final int topChildPosition = mChildren.size() - 1;
- int belowAlwaysOnTopPosition = POSITION_BOTTOM;
- for (int i = topChildPosition; i >= 0; --i) {
- // Since a stack could be repositioned while being one of the child, return
- // current index if that's the same stack we are positioning and it is always on
- // top.
- final boolean sameStack = getStacks().get(i) == stack;
- if ((sameStack && stack.isAlwaysOnTop())
- || (!sameStack && !getStacks().get(i).isAlwaysOnTop())) {
- belowAlwaysOnTopPosition = i;
- break;
- }
- }
-
- // The max possible position we can insert the stack at.
- int maxPosition = POSITION_TOP;
- // The min possible position we can insert the stack at.
- int minPosition = POSITION_BOTTOM;
-
- if (stack.isAlwaysOnTop()) {
- if (hasPinnedTask()) {
- // Always-on-top stacks go below the pinned stack.
- maxPosition = getStacks().indexOf(mRootPinnedTask) - 1;
- }
- // Always-on-top stacks need to be above all other stacks.
- minPosition = belowAlwaysOnTopPosition !=
- POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
- } else {
- // Other stacks need to be below the always-on-top stacks.
- maxPosition = belowAlwaysOnTopPosition !=
- POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
- }
-
- // Cap the requested position to something reasonable for the previous position check
- // below.
- if (requestedPosition == POSITION_TOP) {
- requestedPosition = mChildren.size();
- } else if (requestedPosition == POSITION_BOTTOM) {
- requestedPosition = 0;
- }
-
- int targetPosition = requestedPosition;
- targetPosition = Math.min(targetPosition, maxPosition);
- targetPosition = Math.max(targetPosition, minPosition);
-
- int prevPosition = getStacks().indexOf(stack);
- // The positions we calculated above (maxPosition, minPosition) do not take into
- // consideration the following edge cases.
- // 1) We need to adjust the position depending on the value "adding".
- // 2) When we are moving a stack to another position, we also need to adjust the
- // position depending on whether the stack is moving to a higher or lower position.
- if ((targetPosition != requestedPosition) &&
- (adding || targetPosition < prevPosition)) {
- targetPosition++;
- }
-
- return targetPosition;
- }
-
- @Override
- boolean forAllWindows(ToBooleanFunction<WindowState> callback,
- boolean traverseTopToBottom) {
- if (traverseTopToBottom) {
- if (super.forAllWindows(callback, traverseTopToBottom)) {
- return true;
- }
- if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
- return true;
- }
- } else {
- if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
- return true;
- }
- if (super.forAllWindows(callback, traverseTopToBottom)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean forAllExitingAppTokenWindows(ToBooleanFunction<WindowState> callback,
- boolean traverseTopToBottom) {
- // For legacy reasons we process the TaskStack.mExitingActivities first here before the
- // app tokens.
- // TODO: Investigate if we need to continue to do this or if we can just process them
- // in-order.
- if (traverseTopToBottom) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- for (int j = activities.size() - 1; j >= 0; --j) {
- if (activities.get(j).forAllWindowsUnchecked(callback,
- traverseTopToBottom)) {
- return true;
- }
- }
- }
- } else {
- final int count = mChildren.size();
- for (int i = 0; i < count; ++i) {
- final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- final int appTokensCount = activities.size();
- for (int j = 0; j < appTokensCount; j++) {
- if (activities.get(j).forAllWindowsUnchecked(callback,
- traverseTopToBottom)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- void setExitingTokensHasVisible(boolean hasVisible) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- for (int j = activities.size() - 1; j >= 0; --j) {
- activities.get(j).hasVisible = hasVisible;
- }
- }
- }
-
- void removeExistingAppTokensIfPossible() {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- for (int j = activities.size() - 1; j >= 0; --j) {
- final ActivityRecord activity = activities.get(j);
- if (!activity.hasVisible && !mClosingApps.contains(activity)
- && (!activity.mIsExiting || activity.isEmpty())) {
- // Make sure there is no animation running on this activity, so any windows
- // associated with it will be removed as soon as their animations are
- // complete.
- cancelAnimation();
- ProtoLog.v(WM_DEBUG_ADD_REMOVE,
- "performLayout: Activity exiting now removed %s", activity);
- activity.removeIfPossible();
- }
- }
- }
- }
-
- @Override
- int getOrientation(int candidate) {
- if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
- // Apps and their containers are not allowed to specify an orientation while using
- // root tasks...except for the home stack if it is not resizable and currently
- // visible (top of) its root task.
- if (mRootHomeTask != null && mRootHomeTask.isVisible()) {
- final Task topMost = mRootHomeTask.getTopMostTask();
- final boolean resizable = topMost != null && topMost.isResizeable();
- if (!(resizable && mRootHomeTask.matchParentBounds())) {
- final int orientation = mRootHomeTask.getOrientation();
- if (orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
- }
- }
- }
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
-
- final int orientation = super.getOrientation(candidate);
- if (orientation != SCREEN_ORIENTATION_UNSET
- && orientation != SCREEN_ORIENTATION_BEHIND) {
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "App is requesting an orientation, return %d for display id=%d",
- orientation, mDisplayId);
- return orientation;
- }
-
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "No app is requesting an orientation, return %d for display id=%d",
- getLastOrientation(), mDisplayId);
- // The next app has not been requested to be visible, so we keep the current orientation
- // to prevent freezing/unfreezing the display too early.
- return getLastOrientation();
- }
-
- @Override
- void assignChildLayers(SurfaceControl.Transaction t) {
- assignStackOrdering(t);
-
- for (int i = 0; i < mChildren.size(); i++) {
- final ActivityStack s = mChildren.get(i);
- s.assignChildLayers(t);
- }
- }
-
- void assignStackOrdering(SurfaceControl.Transaction t) {
- if (getParent() == null) {
- return;
- }
- mTmpAlwaysOnTopStacks.clear();
- mTmpHomeStacks.clear();
- mTmpNormalStacks.clear();
- for (int i = 0; i < mChildren.size(); ++i) {
- final ActivityStack s = mChildren.get(i);
- if (s.isAlwaysOnTop()) {
- mTmpAlwaysOnTopStacks.add(s);
- } else if (s.isActivityTypeHome()) {
- mTmpHomeStacks.add(s);
- } else {
- mTmpNormalStacks.add(s);
- }
- }
-
- int layer = 0;
- // Place home stacks to the bottom.
- for (int i = 0; i < mTmpHomeStacks.size(); i++) {
- mTmpHomeStacks.get(i).assignLayer(t, layer++);
- }
- // The home animation layer is between the home stacks and the normal stacks.
- final int layerForHomeAnimationLayer = layer++;
- int layerForSplitScreenDividerAnchor = layer++;
- int layerForAnimationLayer = layer++;
- for (int i = 0; i < mTmpNormalStacks.size(); i++) {
- final ActivityStack s = mTmpNormalStacks.get(i);
- s.assignLayer(t, layer++);
- if (s.inSplitScreenWindowingMode()) {
- // The split screen divider anchor is located above the split screen window.
- layerForSplitScreenDividerAnchor = layer++;
- }
- if (s.isTaskAnimating() || s.isAppTransitioning()) {
- // The animation layer is located above the highest animating stack and no
- // higher.
- layerForAnimationLayer = layer++;
- }
- }
- // The boosted animation layer is between the normal stacks and the always on top
- // stacks.
- final int layerForBoostedAnimationLayer = layer++;
- for (int i = 0; i < mTmpAlwaysOnTopStacks.size(); i++) {
- mTmpAlwaysOnTopStacks.get(i).assignLayer(t, layer++);
- }
-
- t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
- t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
- t.setLayer(mSplitScreenDividerAnchor, layerForSplitScreenDividerAnchor);
- t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
- }
-
- @Override
- SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
- switch (animationLayer) {
- case ANIMATION_LAYER_BOOSTED:
- return mBoostedAppAnimationLayer;
- case ANIMATION_LAYER_HOME:
- return mHomeAppAnimationLayer;
- case ANIMATION_LAYER_STANDARD:
- default:
- return mAppAnimationLayer;
- }
- }
-
- SurfaceControl getSplitScreenDividerAnchor() {
- return mSplitScreenDividerAnchor;
- }
-
- @Override
- void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
- if (getParent() != null) {
- super.onParentChanged(newParent, oldParent, () -> {
- mAppAnimationLayer = makeChildSurface(null)
- .setName("animationLayer")
- .build();
- mBoostedAppAnimationLayer = makeChildSurface(null)
- .setName("boostedAnimationLayer")
- .build();
- mHomeAppAnimationLayer = makeChildSurface(null)
- .setName("homeAnimationLayer")
- .build();
- mSplitScreenDividerAnchor = makeChildSurface(null)
- .setName("splitScreenDividerAnchor")
- .build();
- getPendingTransaction()
- .show(mAppAnimationLayer)
- .show(mBoostedAppAnimationLayer)
- .show(mHomeAppAnimationLayer)
- .show(mSplitScreenDividerAnchor);
- });
- } else {
- super.onParentChanged(newParent, oldParent);
- mWmService.mTransactionFactory.get()
- .remove(mAppAnimationLayer)
- .remove(mBoostedAppAnimationLayer)
- .remove(mHomeAppAnimationLayer)
- .remove(mSplitScreenDividerAnchor)
- .apply();
- mAppAnimationLayer = null;
- mBoostedAppAnimationLayer = null;
- mHomeAppAnimationLayer = null;
- mSplitScreenDividerAnchor = null;
- }
- }
- }
-
private class WindowContainers extends DisplayChildWindowContainer<WindowContainer> {
private final String mName;
diff --git a/services/core/java/com/android/server/wm/TaskContainers.java b/services/core/java/com/android/server/wm/TaskContainers.java
new file mode 100644
index 0000000..a959942
--- /dev/null
+++ b/services/core/java/com/android/server/wm/TaskContainers.java
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER;
+
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.util.Slog;
+import android.view.SurfaceControl;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ToBooleanFunction;
+import com.android.server.protolog.common.ProtoLog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Window container class that contains all containers on this display relating to Apps.
+ * I.e Activities.
+ */
+final class TaskContainers extends DisplayArea<ActivityStack> {
+ private DisplayContent mDisplayContent;
+ /**
+ * A control placed at the appropriate level for transitions to occur.
+ */
+ private SurfaceControl mAppAnimationLayer;
+ private SurfaceControl mBoostedAppAnimationLayer;
+ private SurfaceControl mHomeAppAnimationLayer;
+
+ /**
+ * Given that the split-screen divider does not have an AppWindowToken, it
+ * will have to live inside of a "NonAppWindowContainer". However, in visual Z order
+ * it will need to be interleaved with some of our children, appearing on top of
+ * both docked stacks but underneath any assistant stacks.
+ *
+ * To solve this problem we have this anchor control, which will always exist so
+ * we can always assign it the correct value in our {@link #assignChildLayers}.
+ * Likewise since it always exists, we can always
+ * assign the divider a layer relative to it. This way we prevent linking lifecycle
+ * events between tasks and the divider window.
+ */
+ private SurfaceControl mSplitScreenDividerAnchor;
+
+ // Cached reference to some special tasks we tend to get a lot so we don't need to loop
+ // through the list to find them.
+ private ActivityStack mRootHomeTask;
+ private ActivityStack mRootPinnedTask;
+ private ActivityStack mRootSplitScreenPrimaryTask;
+
+ private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
+ private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
+ private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
+
+ TaskContainers(DisplayContent displayContent, WindowManagerService service) {
+ super(service, Type.ANY, "TaskContainers", FEATURE_TASK_CONTAINER);
+ mDisplayContent = displayContent;
+ }
+
+ /**
+ * Returns the topmost stack on the display that is compatible with the input windowing mode
+ * and activity type. Null is no compatible stack on the display.
+ */
+ ActivityStack getStack(int windowingMode, int activityType) {
+ if (activityType == ACTIVITY_TYPE_HOME) {
+ return mRootHomeTask;
+ }
+ if (windowingMode == WINDOWING_MODE_PINNED) {
+ return mRootPinnedTask;
+ } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ return mRootSplitScreenPrimaryTask;
+ }
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getChildAt(i);
+ if (activityType == ACTIVITY_TYPE_UNDEFINED
+ && windowingMode == stack.getWindowingMode()) {
+ // Passing in undefined type means we want to match the topmost stack with the
+ // windowing mode.
+ return stack;
+ }
+ if (stack.isCompatible(windowingMode, activityType)) {
+ return stack;
+ }
+ }
+ return null;
+ }
+
+ @VisibleForTesting
+ ActivityStack getTopStack() {
+ final int count = getChildCount();
+ return count > 0 ? getChildAt(count - 1) : null;
+ }
+
+ int getIndexOf(ActivityStack stack) {
+ return mChildren.indexOf(stack);
+ }
+
+ ActivityStack getRootHomeTask() {
+ return mRootHomeTask;
+ }
+
+ ActivityStack getRootPinnedTask() {
+ return mRootPinnedTask;
+ }
+
+ ActivityStack getRootSplitScreenPrimaryTask() {
+ return mRootSplitScreenPrimaryTask;
+ }
+
+ ArrayList<Task> getVisibleTasks() {
+ final ArrayList<Task> visibleTasks = new ArrayList<>();
+ forAllTasks(task -> {
+ if (task.isLeafTask() && task.isVisible()) {
+ visibleTasks.add(task);
+ }
+ });
+ return visibleTasks;
+ }
+
+ void onStackWindowingModeChanged(ActivityStack stack) {
+ removeStackReferenceIfNeeded(stack);
+ addStackReferenceIfNeeded(stack);
+ if (stack == mRootPinnedTask && getTopStack() != stack) {
+ // Looks like this stack changed windowing mode to pinned. Move it to the top.
+ positionChildAt(POSITION_TOP, stack, false /* includingParents */);
+ }
+ }
+
+ void addStackReferenceIfNeeded(ActivityStack stack) {
+ if (stack.isActivityTypeHome()) {
+ if (mRootHomeTask != null) {
+ if (!stack.isDescendantOf(mRootHomeTask)) {
+ throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
+ + mRootHomeTask + " already exist on display=" + this
+ + " stack=" + stack);
+ }
+ } else {
+ mRootHomeTask = stack;
+ }
+ }
+
+ if (!stack.isRootTask()) {
+ return;
+ }
+ final int windowingMode = stack.getWindowingMode();
+ if (windowingMode == WINDOWING_MODE_PINNED) {
+ if (mRootPinnedTask != null) {
+ throw new IllegalArgumentException(
+ "addStackReferenceIfNeeded: pinned stack=" + mRootPinnedTask
+ + " already exist on display=" + this + " stack=" + stack);
+ }
+ mRootPinnedTask = stack;
+ } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ if (mRootSplitScreenPrimaryTask != null) {
+ throw new IllegalArgumentException(
+ "addStackReferenceIfNeeded: split screen primary stack="
+ + mRootSplitScreenPrimaryTask
+ + " already exist on display=" + this + " stack=" + stack);
+ }
+ mRootSplitScreenPrimaryTask = stack;
+ }
+ }
+
+ void removeStackReferenceIfNeeded(ActivityStack stack) {
+ if (stack == mRootHomeTask) {
+ mRootHomeTask = null;
+ } else if (stack == mRootPinnedTask) {
+ mRootPinnedTask = null;
+ } else if (stack == mRootSplitScreenPrimaryTask) {
+ mRootSplitScreenPrimaryTask = null;
+ }
+ }
+
+ @Override
+ void addChild(ActivityStack stack, int position) {
+ addStackReferenceIfNeeded(stack);
+ position = findPositionForStack(position, stack, true /* adding */);
+
+ super.addChild(stack, position);
+ mDisplayContent.mAtmService.updateSleepIfNeededLocked();
+
+ // The reparenting case is handled in WindowContainer.
+ if (!stack.mReparenting) {
+ mDisplayContent.setLayoutNeeded();
+ }
+ }
+
+ @Override
+ protected void removeChild(ActivityStack stack) {
+ super.removeChild(stack);
+ mDisplayContent.onStackRemoved(stack);
+ mDisplayContent.mAtmService.updateSleepIfNeededLocked();
+ removeStackReferenceIfNeeded(stack);
+ }
+
+ @Override
+ boolean isOnTop() {
+ // Considered always on top
+ return true;
+ }
+
+ @Override
+ void positionChildAt(int position, ActivityStack child, boolean includingParents) {
+ final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
+ final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
+ if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
+ // This stack is always-on-top, override the default behavior.
+ Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
+
+ // Moving to its current position, as we must call super but we don't want to
+ // perform any meaningful action.
+ final int currentPosition = mChildren.indexOf(child);
+ super.positionChildAt(currentPosition, child, false /* includingParents */);
+ return;
+ }
+ // We don't allow untrusted display to top when task stack moves to top,
+ // until user tapping this display to change display position as top intentionally.
+ if (mDisplayContent.isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
+ includingParents = false;
+ }
+ final int targetPosition = findPositionForStack(position, child, false /* adding */);
+ super.positionChildAt(targetPosition, child, false /* includingParents */);
+
+ if (includingParents && (moveToTop || moveToBottom)) {
+ // The DisplayContent children do not re-order, but we still want to move the
+ // display of this stack container because the intention of positioning is to have
+ // higher z-order to gain focus.
+ mDisplayContent.positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
+ true /* includingParents */);
+ }
+
+ child.updateTaskMovement(moveToTop);
+
+ mDisplayContent.setLayoutNeeded();
+ }
+
+ /**
+ * When stack is added or repositioned, find a proper position for it.
+ * This will make sure that pinned stack always stays on top.
+ * @param requestedPosition Position requested by caller.
+ * @param stack Stack to be added or positioned.
+ * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
+ * @return The proper position for the stack.
+ */
+ private int findPositionForStack(int requestedPosition, ActivityStack stack,
+ boolean adding) {
+ if (stack.isActivityTypeDream()) {
+ return POSITION_TOP;
+ }
+
+ if (stack.inPinnedWindowingMode()) {
+ return POSITION_TOP;
+ }
+
+ final int topChildPosition = mChildren.size() - 1;
+ int belowAlwaysOnTopPosition = POSITION_BOTTOM;
+ for (int i = topChildPosition; i >= 0; --i) {
+ // Since a stack could be repositioned while being one of the child, return
+ // current index if that's the same stack we are positioning and it is always on
+ // top.
+ final boolean sameStack = mDisplayContent.getStacks().get(i) == stack;
+ if ((sameStack && stack.isAlwaysOnTop())
+ || (!sameStack && !mDisplayContent.getStacks().get(i).isAlwaysOnTop())) {
+ belowAlwaysOnTopPosition = i;
+ break;
+ }
+ }
+
+ // The max possible position we can insert the stack at.
+ int maxPosition = POSITION_TOP;
+ // The min possible position we can insert the stack at.
+ int minPosition = POSITION_BOTTOM;
+
+ if (stack.isAlwaysOnTop()) {
+ if (mDisplayContent.hasPinnedTask()) {
+ // Always-on-top stacks go below the pinned stack.
+ maxPosition = mDisplayContent.getStacks().indexOf(mRootPinnedTask) - 1;
+ }
+ // Always-on-top stacks need to be above all other stacks.
+ minPosition = belowAlwaysOnTopPosition
+ != POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
+ } else {
+ // Other stacks need to be below the always-on-top stacks.
+ maxPosition = belowAlwaysOnTopPosition
+ != POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
+ }
+
+ // Cap the requested position to something reasonable for the previous position check
+ // below.
+ if (requestedPosition == POSITION_TOP) {
+ requestedPosition = mChildren.size();
+ } else if (requestedPosition == POSITION_BOTTOM) {
+ requestedPosition = 0;
+ }
+
+ int targetPosition = requestedPosition;
+ targetPosition = Math.min(targetPosition, maxPosition);
+ targetPosition = Math.max(targetPosition, minPosition);
+
+ int prevPosition = mDisplayContent.getStacks().indexOf(stack);
+ // The positions we calculated above (maxPosition, minPosition) do not take into
+ // consideration the following edge cases.
+ // 1) We need to adjust the position depending on the value "adding".
+ // 2) When we are moving a stack to another position, we also need to adjust the
+ // position depending on whether the stack is moving to a higher or lower position.
+ if ((targetPosition != requestedPosition) && (adding || targetPosition < prevPosition)) {
+ targetPosition++;
+ }
+
+ return targetPosition;
+ }
+
+ @Override
+ boolean forAllWindows(ToBooleanFunction<WindowState> callback,
+ boolean traverseTopToBottom) {
+ if (traverseTopToBottom) {
+ if (super.forAllWindows(callback, traverseTopToBottom)) {
+ return true;
+ }
+ if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
+ return true;
+ }
+ } else {
+ if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
+ return true;
+ }
+ if (super.forAllWindows(callback, traverseTopToBottom)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean forAllExitingAppTokenWindows(ToBooleanFunction<WindowState> callback,
+ boolean traverseTopToBottom) {
+ // For legacy reasons we process the TaskStack.mExitingActivities first here before the
+ // app tokens.
+ // TODO: Investigate if we need to continue to do this or if we can just process them
+ // in-order.
+ if (traverseTopToBottom) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
+ for (int j = activities.size() - 1; j >= 0; --j) {
+ if (activities.get(j).forAllWindowsUnchecked(callback,
+ traverseTopToBottom)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ final int count = mChildren.size();
+ for (int i = 0; i < count; ++i) {
+ final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
+ final int appTokensCount = activities.size();
+ for (int j = 0; j < appTokensCount; j++) {
+ if (activities.get(j).forAllWindowsUnchecked(callback,
+ traverseTopToBottom)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ void setExitingTokensHasVisible(boolean hasVisible) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
+ for (int j = activities.size() - 1; j >= 0; --j) {
+ activities.get(j).hasVisible = hasVisible;
+ }
+ }
+ }
+
+ void removeExistingAppTokensIfPossible() {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
+ for (int j = activities.size() - 1; j >= 0; --j) {
+ final ActivityRecord activity = activities.get(j);
+ if (!activity.hasVisible && !mDisplayContent.mClosingApps.contains(activity)
+ && (!activity.mIsExiting || activity.isEmpty())) {
+ // Make sure there is no animation running on this activity, so any windows
+ // associated with it will be removed as soon as their animations are
+ // complete.
+ cancelAnimation();
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "performLayout: Activity exiting now removed %s", activity);
+ activity.removeIfPossible();
+ }
+ }
+ }
+ }
+
+ @Override
+ int getOrientation(int candidate) {
+ if (mDisplayContent.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
+ // Apps and their containers are not allowed to specify an orientation while using
+ // root tasks...except for the home stack if it is not resizable and currently
+ // visible (top of) its root task.
+ if (mRootHomeTask != null && mRootHomeTask.isVisible()) {
+ final Task topMost = mRootHomeTask.getTopMostTask();
+ final boolean resizable = topMost != null && topMost.isResizeable();
+ if (!(resizable && mRootHomeTask.matchParentBounds())) {
+ final int orientation = mRootHomeTask.getOrientation();
+ if (orientation != SCREEN_ORIENTATION_UNSET) {
+ return orientation;
+ }
+ }
+ }
+ return SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+
+ final int orientation = super.getOrientation(candidate);
+ if (orientation != SCREEN_ORIENTATION_UNSET
+ && orientation != SCREEN_ORIENTATION_BEHIND) {
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "App is requesting an orientation, return %d for display id=%d",
+ orientation, mDisplayContent.mDisplayId);
+ return orientation;
+ }
+
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "No app is requesting an orientation, return %d for display id=%d",
+ mDisplayContent.getLastOrientation(), mDisplayContent.mDisplayId);
+ // The next app has not been requested to be visible, so we keep the current orientation
+ // to prevent freezing/unfreezing the display too early.
+ return mDisplayContent.getLastOrientation();
+ }
+
+ @Override
+ void assignChildLayers(SurfaceControl.Transaction t) {
+ assignStackOrdering(t);
+
+ for (int i = 0; i < mChildren.size(); i++) {
+ final ActivityStack s = mChildren.get(i);
+ s.assignChildLayers(t);
+ }
+ }
+
+ void assignStackOrdering(SurfaceControl.Transaction t) {
+ if (getParent() == null) {
+ return;
+ }
+ mTmpAlwaysOnTopStacks.clear();
+ mTmpHomeStacks.clear();
+ mTmpNormalStacks.clear();
+ for (int i = 0; i < mChildren.size(); ++i) {
+ final ActivityStack s = mChildren.get(i);
+ if (s.isAlwaysOnTop()) {
+ mTmpAlwaysOnTopStacks.add(s);
+ } else if (s.isActivityTypeHome()) {
+ mTmpHomeStacks.add(s);
+ } else {
+ mTmpNormalStacks.add(s);
+ }
+ }
+
+ int layer = 0;
+ // Place home stacks to the bottom.
+ for (int i = 0; i < mTmpHomeStacks.size(); i++) {
+ mTmpHomeStacks.get(i).assignLayer(t, layer++);
+ }
+ // The home animation layer is between the home stacks and the normal stacks.
+ final int layerForHomeAnimationLayer = layer++;
+ int layerForSplitScreenDividerAnchor = layer++;
+ int layerForAnimationLayer = layer++;
+ for (int i = 0; i < mTmpNormalStacks.size(); i++) {
+ final ActivityStack s = mTmpNormalStacks.get(i);
+ s.assignLayer(t, layer++);
+ if (s.inSplitScreenWindowingMode()) {
+ // The split screen divider anchor is located above the split screen window.
+ layerForSplitScreenDividerAnchor = layer++;
+ }
+ if (s.isTaskAnimating() || s.isAppTransitioning()) {
+ // The animation layer is located above the highest animating stack and no
+ // higher.
+ layerForAnimationLayer = layer++;
+ }
+ }
+ // The boosted animation layer is between the normal stacks and the always on top
+ // stacks.
+ final int layerForBoostedAnimationLayer = layer++;
+ for (int i = 0; i < mTmpAlwaysOnTopStacks.size(); i++) {
+ mTmpAlwaysOnTopStacks.get(i).assignLayer(t, layer++);
+ }
+
+ t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
+ t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
+ t.setLayer(mSplitScreenDividerAnchor, layerForSplitScreenDividerAnchor);
+ t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
+ }
+
+ @Override
+ SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
+ switch (animationLayer) {
+ case ANIMATION_LAYER_BOOSTED:
+ return mBoostedAppAnimationLayer;
+ case ANIMATION_LAYER_HOME:
+ return mHomeAppAnimationLayer;
+ case ANIMATION_LAYER_STANDARD:
+ default:
+ return mAppAnimationLayer;
+ }
+ }
+
+ SurfaceControl getSplitScreenDividerAnchor() {
+ return mSplitScreenDividerAnchor;
+ }
+
+ @Override
+ void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
+ if (getParent() != null) {
+ super.onParentChanged(newParent, oldParent, () -> {
+ mAppAnimationLayer = makeChildSurface(null)
+ .setName("animationLayer")
+ .build();
+ mBoostedAppAnimationLayer = makeChildSurface(null)
+ .setName("boostedAnimationLayer")
+ .build();
+ mHomeAppAnimationLayer = makeChildSurface(null)
+ .setName("homeAnimationLayer")
+ .build();
+ mSplitScreenDividerAnchor = makeChildSurface(null)
+ .setName("splitScreenDividerAnchor")
+ .build();
+ getPendingTransaction()
+ .show(mAppAnimationLayer)
+ .show(mBoostedAppAnimationLayer)
+ .show(mHomeAppAnimationLayer)
+ .show(mSplitScreenDividerAnchor);
+ });
+ } else {
+ super.onParentChanged(newParent, oldParent);
+ mWmService.mTransactionFactory.get()
+ .remove(mAppAnimationLayer)
+ .remove(mBoostedAppAnimationLayer)
+ .remove(mHomeAppAnimationLayer)
+ .remove(mSplitScreenDividerAnchor)
+ .apply();
+ mAppAnimationLayer = null;
+ mBoostedAppAnimationLayer = null;
+ mHomeAppAnimationLayer = null;
+ mSplitScreenDividerAnchor = null;
+ }
+ }
+}
diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp
index cdbe77a..2f6592b 100644
--- a/services/devicepolicy/Android.bp
+++ b/services/devicepolicy/Android.bp
@@ -13,8 +13,4 @@
"services.core",
"app-compat-annotations",
],
-
- plugins: [
- "compat-changeid-annotation-processor",
- ],
}
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index ae27c7a..25da8fe 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -157,7 +157,6 @@
IncrementalService::IncFsMount::~IncFsMount() {
incrementalService.mDataLoaderManager->destroyDataLoader(mountId);
- control.reset();
LOG(INFO) << "Unmounting and cleaning up mount " << mountId << " with root '" << root << '\'';
for (auto&& [target, _] : bindPoints) {
LOG(INFO) << "\tbind: " << target;
@@ -424,9 +423,10 @@
LOG(ERROR) << "Vold::mountIncFs() returned invalid control parcel.";
return kInvalidStorageId;
}
- control.cmd = controlParcel.cmd.release().release();
- control.pendingReads = controlParcel.pendingReads.release().release();
- control.logs = controlParcel.log.release().release();
+ int cmd = controlParcel.cmd.release().release();
+ int pendingReads = controlParcel.pendingReads.release().release();
+ int logs = controlParcel.log.release().release();
+ control = mIncFs->createControl(cmd, pendingReads, logs);
}
std::unique_lock l(mLock);
@@ -965,16 +965,17 @@
auto mountTarget = path::join(root, constants().mount);
const auto backing = path::join(root, constants().backing);
- IncFsMount::Control control;
IncrementalFileSystemControlParcel controlParcel;
auto status = mVold->mountIncFs(backing, mountTarget, 0, &controlParcel);
if (!status.isOk()) {
LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
return false;
}
- control.cmd = controlParcel.cmd.release().release();
- control.pendingReads = controlParcel.pendingReads.release().release();
- control.logs = controlParcel.log.release().release();
+
+ int cmd = controlParcel.cmd.release().release();
+ int pendingReads = controlParcel.pendingReads.release().release();
+ int logs = controlParcel.log.release().release();
+ IncFsMount::Control control = mIncFs->createControl(cmd, pendingReads, logs);
auto ifs = std::make_shared<IncFsMount>(std::string(root), -1, std::move(control), *this);
@@ -1084,10 +1085,10 @@
}
FileSystemControlParcel fsControlParcel;
fsControlParcel.incremental = aidl::make_nullable<IncrementalFileSystemControlParcel>();
- fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd)));
+ fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd())));
fsControlParcel.incremental->pendingReads.reset(
- base::unique_fd(::dup(ifs.control.pendingReads)));
- fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs)));
+ base::unique_fd(::dup(ifs.control.pendingReads())));
+ fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs())));
sp<IncrementalDataLoaderListener> listener =
new IncrementalDataLoaderListener(*this,
externalListener ? *externalListener
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 5349ebf..c70a47d 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -66,15 +66,17 @@
class IncFsWrapper {
public:
virtual ~IncFsWrapper() = default;
- virtual ErrorCode makeFile(Control control, std::string_view path, int mode, FileId id,
+ virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const = 0;
+ virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
NewFileParams params) const = 0;
- virtual ErrorCode makeDir(Control control, std::string_view path, int mode) const = 0;
- virtual RawMetadata getMetadata(Control control, FileId fileid) const = 0;
- virtual RawMetadata getMetadata(Control control, std::string_view path) const = 0;
- virtual FileId getFileId(Control control, std::string_view path) const = 0;
- virtual ErrorCode link(Control control, std::string_view from, std::string_view to) const = 0;
- virtual ErrorCode unlink(Control control, std::string_view path) const = 0;
- virtual base::unique_fd openWrite(Control control, FileId id) const = 0;
+ virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0;
+ virtual RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
+ virtual RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
+ virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
+ virtual ErrorCode link(const Control& control, std::string_view from,
+ std::string_view to) const = 0;
+ virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
+ virtual base::unique_fd openWrite(const Control& control, FileId id) const = 0;
virtual ErrorCode writeBlocks(Span<const DataBlock> blocks) const = 0;
};
@@ -149,29 +151,33 @@
public:
RealIncFs() = default;
~RealIncFs() = default;
- ErrorCode makeFile(Control control, std::string_view path, int mode, FileId id,
+ Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const override {
+ return incfs::createControl(cmd, pendingReads, logs);
+ }
+ ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
NewFileParams params) const override {
return incfs::makeFile(control, path, mode, id, params);
}
- ErrorCode makeDir(Control control, std::string_view path, int mode) const override {
+ ErrorCode makeDir(const Control& control, std::string_view path, int mode) const override {
return incfs::makeDir(control, path, mode);
}
- RawMetadata getMetadata(Control control, FileId fileid) const override {
+ RawMetadata getMetadata(const Control& control, FileId fileid) const override {
return incfs::getMetadata(control, fileid);
}
- RawMetadata getMetadata(Control control, std::string_view path) const override {
+ RawMetadata getMetadata(const Control& control, std::string_view path) const override {
return incfs::getMetadata(control, path);
}
- FileId getFileId(Control control, std::string_view path) const override {
+ FileId getFileId(const Control& control, std::string_view path) const override {
return incfs::getFileId(control, path);
}
- ErrorCode link(Control control, std::string_view from, std::string_view to) const override {
+ ErrorCode link(const Control& control, std::string_view from,
+ std::string_view to) const override {
return incfs::link(control, from, to);
}
- ErrorCode unlink(Control control, std::string_view path) const override {
+ ErrorCode unlink(const Control& control, std::string_view path) const override {
return incfs::unlink(control, path);
}
- base::unique_fd openWrite(Control control, FileId id) const override {
+ base::unique_fd openWrite(const Control& control, FileId id) const override {
return base::unique_fd{incfs::openWrite(control, id)};
}
ErrorCode writeBlocks(Span<const DataBlock> blocks) const override {
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index f5b88d9..c4b4d17 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -164,22 +164,23 @@
class MockIncFs : public IncFsWrapper {
public:
+ MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
MOCK_CONST_METHOD5(makeFile,
- ErrorCode(Control control, std::string_view path, int mode, FileId id,
+ ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
NewFileParams params));
- MOCK_CONST_METHOD3(makeDir, ErrorCode(Control control, std::string_view path, int mode));
- MOCK_CONST_METHOD2(getMetadata, RawMetadata(Control control, FileId fileid));
- MOCK_CONST_METHOD2(getMetadata, RawMetadata(Control control, std::string_view path));
- MOCK_CONST_METHOD2(getFileId, FileId(Control control, std::string_view path));
+ MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
+ MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
+ MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
+ MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
MOCK_CONST_METHOD3(link,
- ErrorCode(Control control, std::string_view from, std::string_view to));
- MOCK_CONST_METHOD2(unlink, ErrorCode(Control control, std::string_view path));
- MOCK_CONST_METHOD2(openWrite, base::unique_fd(Control control, FileId id));
+ ErrorCode(const Control& control, std::string_view from, std::string_view to));
+ MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
+ MOCK_CONST_METHOD2(openWrite, base::unique_fd(const Control& control, FileId id));
MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
- RawMetadata getMountInfoMetadata(Control control, std::string_view path) {
+ RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
metadata::Mount m;
m.mutable_storage()->set_id(100);
m.mutable_loader()->set_package_name("com.test");
@@ -189,13 +190,13 @@
m.mutable_loader()->release_package_name();
return {metadata.begin(), metadata.end()};
}
- RawMetadata getStorageMetadata(Control control, std::string_view path) {
+ RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
metadata::Storage st;
st.set_id(100);
auto metadata = st.SerializeAsString();
return {metadata.begin(), metadata.end()};
}
- RawMetadata getBindPointMetadata(Control control, std::string_view path) {
+ RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
metadata::BindPoint bp;
std::string destPath = "dest";
std::string srcPath = "src";
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaProviderTest.java
index 3120631..32d7a077 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaProviderTest.java
@@ -78,7 +78,7 @@
@Override
public DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer,
- DisplayContent.TaskContainers taskContainers) {
+ TaskContainers taskContainers) {
throw new RuntimeException("test stub");
}
}