Merge "Return the existing DisplayAreas when registering an organizer"

This commit is contained in:
Chris Li
2020-10-29 17:07:24 +00:00
committed by Android (Google) Code Review
9 changed files with 203 additions and 14 deletions

View File

@@ -2354,6 +2354,15 @@ package android.widget.inline {
package android.window {
public final class DisplayAreaAppearedInfo implements android.os.Parcelable {
ctor public DisplayAreaAppearedInfo(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl);
method public int describeContents();
method @NonNull public android.window.DisplayAreaInfo getDisplayAreaInfo();
method @NonNull public android.view.SurfaceControl getLeash();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.window.DisplayAreaAppearedInfo> CREATOR;
}
public final class DisplayAreaInfo implements android.os.Parcelable {
ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int, int);
method public int describeContents();
@@ -2369,7 +2378,7 @@ package android.window {
ctor public DisplayAreaOrganizer();
method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl);
method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void registerOrganizer(int);
method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.window.DisplayAreaAppearedInfo> registerOrganizer(int);
field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1
field public static final int FEATURE_ONE_HANDED = 3; // 0x3
field public static final int FEATURE_ROOT = 0; // 0x0

View File

@@ -0,0 +1,24 @@
/*
* 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 android.window;
/**
* Data object for the DisplayArea info provided when a DisplayArea is presented to an organizer.
*
* @hide
*/
parcelable DisplayAreaAppearedInfo;

View File

@@ -0,0 +1,88 @@
/*
* 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 android.window;
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.SurfaceControl;
/**
* Data object for the DisplayArea info provided when a DisplayArea is presented to an organizer.
*
* @hide
*/
@TestApi
public final class DisplayAreaAppearedInfo implements Parcelable {
@NonNull
private final DisplayAreaInfo mDisplayAreaInfo;
@NonNull
private final SurfaceControl mLeash;
@NonNull
public static final Creator<DisplayAreaAppearedInfo> CREATOR =
new Creator<DisplayAreaAppearedInfo>() {
@Override
public DisplayAreaAppearedInfo createFromParcel(Parcel source) {
final DisplayAreaInfo displayAreaInfo = source.readTypedObject(DisplayAreaInfo.CREATOR);
final SurfaceControl leash = source.readTypedObject(SurfaceControl.CREATOR);
return new DisplayAreaAppearedInfo(displayAreaInfo, leash);
}
@Override
public DisplayAreaAppearedInfo[] newArray(int size) {
return new DisplayAreaAppearedInfo[size];
}
};
public DisplayAreaAppearedInfo(@NonNull DisplayAreaInfo displayAreaInfo,
@NonNull SurfaceControl leash) {
mDisplayAreaInfo = displayAreaInfo;
mLeash = leash;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeTypedObject(mDisplayAreaInfo, flags);
dest.writeTypedObject(mLeash, flags);
}
@Override
public int describeContents() {
return 0;
}
/**
* @return the DisplayArea info.
*/
@NonNull
public DisplayAreaInfo getDisplayAreaInfo() {
return mDisplayAreaInfo;
}
/**
* @return the leash for the DisplayArea.
*/
@NonNull
public SurfaceControl getLeash() {
return mLeash;
}
}

View File

@@ -16,12 +16,15 @@
package android.window;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.os.RemoteException;
import android.view.SurfaceControl;
import java.util.List;
/**
* Interface for WindowManager to delegate control of display areas.
* @hide
@@ -84,10 +87,17 @@ public class DisplayAreaOrganizer extends WindowOrganizer {
*/
public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
/**
* Registers a DisplayAreaOrganizer to manage display areas for a given feature.
*
* @return a list of display areas that should be managed by the organizer.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
public void registerOrganizer(int displayAreaFeature) {
@CallSuper
@NonNull
public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) {
try {
getController().registerOrganizer(mInterface, displayAreaFeature);
return getController().registerOrganizer(mInterface, displayAreaFeature).getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -97,6 +107,7 @@ public class DisplayAreaOrganizer extends WindowOrganizer {
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
@CallSuper
public void unregisterOrganizer() {
try {
getController().unregisterOrganizer(mInterface);
@@ -105,6 +116,11 @@ public class DisplayAreaOrganizer extends WindowOrganizer {
}
}
/**
* Called when a DisplayArea of the registered window type can be controlled by this organizer.
* It will not be called for the DisplayAreas that exist when {@link #registerOrganizer(int)} is
* called.
*/
public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
@NonNull SurfaceControl leash) {}

View File

@@ -16,13 +16,20 @@
package android.window;
import android.content.pm.ParceledListSlice;
import android.window.DisplayAreaAppearedInfo;
import android.window.IDisplayAreaOrganizer;
/** @hide */
interface IDisplayAreaOrganizerController {
/** Register a DisplayAreaOrganizer to manage display areas for a given feature. */
void registerOrganizer(in IDisplayAreaOrganizer organizer, int displayAreaFeature);
/**
* Registers a DisplayAreaOrganizer to manage display areas for a given feature.
*
* @return a list of display areas that should be managed by the organizer.
*/
ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer(in IDisplayAreaOrganizer organizer,
int displayAreaFeature);
/**
* Unregisters a previously registered display area organizer.

View File

@@ -30,6 +30,7 @@ import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Log;
import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
import android.window.WindowContainerTransaction;
@@ -188,6 +189,17 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
}
}
@Override
public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) {
final List<DisplayAreaAppearedInfo> displayAreaInfos =
super.registerOrganizer(displayAreaFeature);
for (int i = 0; i < displayAreaInfos.size(); i++) {
final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
}
return displayAreaInfos;
}
@Override
public void unregisterOrganizer() {
super.unregisterOrganizer();

View File

@@ -397,6 +397,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
}
void setOrganizer(IDisplayAreaOrganizer organizer) {
setOrganizer(organizer, false /* skipDisplayAreaAppeared */);
}
void setOrganizer(IDisplayAreaOrganizer organizer, boolean skipDisplayAreaAppeared) {
if (mOrganizer == organizer) return;
IDisplayAreaOrganizer lastOrganizer = mOrganizer;
// Update the new display area organizer before calling sendDisplayAreaVanished since it
@@ -404,7 +408,9 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
// about it.
mOrganizer = organizer;
sendDisplayAreaVanished(lastOrganizer);
sendDisplayAreaAppeared();
if (!skipDisplayAreaAppeared) {
sendDisplayAreaAppeared();
}
}
void sendDisplayAreaAppeared() {

View File

@@ -18,16 +18,20 @@ package com.android.server.wm;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo;
import android.window.IDisplayAreaOrganizer;
import android.window.IDisplayAreaOrganizerController;
import com.android.internal.protolog.common.ProtoLog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerController.Stub {
private static final String TAG = "DisplayAreaOrganizerController";
@@ -64,7 +68,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
}
@Override
public void registerOrganizer(IDisplayAreaOrganizer organizer, int feature) {
public ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer(
IDisplayAreaOrganizer organizer, int feature) {
enforceTaskPermission("registerOrganizer()");
final long uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
@@ -83,12 +88,18 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
} catch (RemoteException e) {
// Oh well...
}
final List<DisplayAreaAppearedInfo> displayAreaInfos = new ArrayList<>();
mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
if (da.mFeatureId != feature) return;
da.setOrganizer(organizer);
da.setOrganizer(organizer, true /* skipDisplayAreaAppeared */);
displayAreaInfos.add(new DisplayAreaAppearedInfo(da.getDisplayAreaInfo(),
new SurfaceControl(da.getSurfaceControl(),
"DisplayAreaOrganizerController.registerOrganizer")));
});
mOrganizersByFeatureIds.put(feature, organizer);
return new ParceledListSlice<>(displayAreaInfos);
}
} finally {
Binder.restoreCallingIdentity(origId);

View File

@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@ import android.os.Binder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.IDisplayAreaOrganizer;
@@ -41,6 +43,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
/**
* Build/Install/Run:
* atest WmTests:DisplayAreaOrganizerTest
@@ -88,28 +92,40 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase {
.unregisterOrganizer(organizer);
}
@Test
public void testRegisterOrganizer() throws RemoteException {
IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder());
List<DisplayAreaAppearedInfo> infos = mWm.mAtmService.mWindowOrganizerController
.mDisplayAreaOrganizerController
.registerOrganizer(organizer, FEATURE_VENDOR_FIRST).getList();
// Return a list contains the DA, and no onDisplayAreaAppeared triggered.
assertThat(infos).hasSize(1);
assertThat(infos.get(0).getDisplayAreaInfo().token)
.isEqualTo(mTestDisplayArea.getDisplayAreaInfo().token);
verify(organizer, never()).onDisplayAreaAppeared(any(DisplayAreaInfo.class),
any(SurfaceControl.class));
}
@Test
public void testAppearedVanished() throws RemoteException {
IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
verify(organizer)
.onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class));
unregisterMockOrganizer(organizer);
verify(organizer).onDisplayAreaVanished(any());
}
@Test
public void testChanged() throws RemoteException {
IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
verify(organizer)
.onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class));
mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000));
verify(organizer).onDisplayAreaInfoChanged(any());
Configuration tmpConfiguration = new Configuration();
tmpConfiguration.setTo(mDisplayContent.getRequestedOverrideConfiguration());
mDisplayContent.onRequestedOverrideConfigurationChanged(tmpConfiguration);
// Ensure it was still only called once if the bounds didn't change
verify(organizer).onDisplayAreaInfoChanged(any());
}