Add a dedicated method to check task windowing mode
Trying to get a task information via ActivityManager#getAppTasks() will not report tasks that aren't associated with calling package by the root activity package name. For activities that are from a different package the task wasn't found, so the windowing mode couldn't be checked and WM Extensions didn't report any display features. This CL adds a dedicated method to check the task windowing mode for a given activity token. Bug: 236295340 Test: ActivityEmbeddingIntegrationTests#testDisplayFeaturesWithEmbedding_differentPackage Change-Id: If2dbc337c4b8cb909914cc28ae4db28a82ff9de3
This commit is contained in:
@@ -226,6 +226,18 @@ public class ActivityClient {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
|
||||
* found.
|
||||
*/
|
||||
public int getTaskWindowingMode(IBinder activityToken) {
|
||||
try {
|
||||
return getActivityClientController().getTaskWindowingMode(activityToken);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-finishing activity token below in the same task if it belongs to the same
|
||||
* process.
|
||||
|
||||
@@ -78,6 +78,7 @@ interface IActivityClientController {
|
||||
boolean willActivityBeVisible(in IBinder token);
|
||||
int getDisplayId(in IBinder activityToken);
|
||||
int getTaskForActivity(in IBinder token, in boolean onlyRoot);
|
||||
int getTaskWindowingMode(in IBinder activityToken);
|
||||
IBinder getActivityTokenBelow(IBinder token);
|
||||
ComponentName getCallingActivity(in IBinder token);
|
||||
String getCallingPackage(in IBinder token);
|
||||
|
||||
@@ -25,8 +25,7 @@ import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.AppTask;
|
||||
import android.app.ActivityClient;
|
||||
import android.app.Application;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.Context;
|
||||
@@ -34,7 +33,6 @@ import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.window.common.CommonFoldingFeature;
|
||||
@@ -179,57 +177,49 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
|
||||
private List<DisplayFeature> getDisplayFeatures(
|
||||
@NonNull Activity activity, List<CommonFoldingFeature> storedFeatures) {
|
||||
List<DisplayFeature> features = new ArrayList<>();
|
||||
int displayId = activity.getDisplay().getDisplayId();
|
||||
if (displayId != DEFAULT_DISPLAY) {
|
||||
Log.w(TAG, "This sample doesn't support display features on secondary displays");
|
||||
return features;
|
||||
} else if (isTaskInMultiWindowMode(activity)) {
|
||||
// It is recommended not to report any display features in multi-window mode, since it
|
||||
// won't be possible to synchronize the display feature positions with window movement.
|
||||
return features;
|
||||
} else {
|
||||
for (CommonFoldingFeature baseFeature : storedFeatures) {
|
||||
Integer state = convertToExtensionState(baseFeature.getState());
|
||||
if (state == null) {
|
||||
continue;
|
||||
}
|
||||
Rect featureRect = baseFeature.getRect();
|
||||
rotateRectToDisplayRotation(displayId, featureRect);
|
||||
transformToWindowSpaceRect(activity, featureRect);
|
||||
|
||||
if (!isRectZero(featureRect)) {
|
||||
// TODO(b/228641877) Remove guarding if when fixed.
|
||||
features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
|
||||
}
|
||||
}
|
||||
if (!shouldReportDisplayFeatures(activity)) {
|
||||
return features;
|
||||
}
|
||||
|
||||
int displayId = activity.getDisplay().getDisplayId();
|
||||
for (CommonFoldingFeature baseFeature : storedFeatures) {
|
||||
Integer state = convertToExtensionState(baseFeature.getState());
|
||||
if (state == null) {
|
||||
continue;
|
||||
}
|
||||
Rect featureRect = baseFeature.getRect();
|
||||
rotateRectToDisplayRotation(displayId, featureRect);
|
||||
transformToWindowSpaceRect(activity, featureRect);
|
||||
|
||||
if (!isRectZero(featureRect)) {
|
||||
// TODO(b/228641877): Remove guarding when fixed.
|
||||
features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
|
||||
}
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the task associated with the activity is in multi-window. If task info is not
|
||||
* available it defaults to {@code true}.
|
||||
* Checks whether display features should be reported for the activity.
|
||||
* TODO(b/238948678): Support reporting display features in all windowing modes.
|
||||
*/
|
||||
private boolean isTaskInMultiWindowMode(@NonNull Activity activity) {
|
||||
final ActivityManager am = activity.getSystemService(ActivityManager.class);
|
||||
if (am == null) {
|
||||
return true;
|
||||
private boolean shouldReportDisplayFeatures(@NonNull Activity activity) {
|
||||
int displayId = activity.getDisplay().getDisplayId();
|
||||
if (displayId != DEFAULT_DISPLAY) {
|
||||
// Display features are not supported on secondary displays.
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<AppTask> appTasks = am.getAppTasks();
|
||||
final int taskId = activity.getTaskId();
|
||||
AppTask task = null;
|
||||
for (AppTask t : appTasks) {
|
||||
if (t.getTaskInfo().taskId == taskId) {
|
||||
task = t;
|
||||
break;
|
||||
}
|
||||
final int taskWindowingMode = ActivityClient.getInstance().getTaskWindowingMode(
|
||||
activity.getActivityToken());
|
||||
if (taskWindowingMode == -1) {
|
||||
// If we cannot determine the task windowing mode for any reason, it is likely that we
|
||||
// won't be able to determine its position correctly as well. DisplayFeatures' bounds
|
||||
// in this case can't be computed correctly, so we should skip.
|
||||
return false;
|
||||
}
|
||||
if (task == null) {
|
||||
// The task might be removed on the server already.
|
||||
return true;
|
||||
}
|
||||
return WindowConfiguration.inMultiWindowMode(task.getTaskInfo().getWindowingMode());
|
||||
// It is recommended not to report any display features in multi-window mode, since it
|
||||
// won't be possible to synchronize the display feature positions with window movement.
|
||||
return !WindowConfiguration.inMultiWindowMode(taskWindowingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -577,6 +577,21 @@ class ActivityClientController extends IActivityClientController.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
|
||||
* found.
|
||||
*/
|
||||
@Override
|
||||
public int getTaskWindowingMode(IBinder activityToken) {
|
||||
synchronized (mGlobalLock) {
|
||||
final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken);
|
||||
if (ar == null) {
|
||||
return -1;
|
||||
}
|
||||
return ar.getTask().getWindowingMode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public IBinder getActivityTokenBelow(IBinder activityToken) {
|
||||
|
||||
Reference in New Issue
Block a user