4/ Update HideDisplayCutout and AppPairs to use shell main thread
Bug: 161979899 Test: atest WMShellUnitTests Change-Id: I369e83cbc85fea80b0db4d58ba8d05d12fbd09e3
This commit is contained in:
@@ -19,41 +19,58 @@ package com.android.wm.shell.apppairs;
|
||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Class manages app-pairs multitasking mode and implements the main interface {@link AppPairs}.
|
||||
*/
|
||||
public class AppPairsController implements AppPairs {
|
||||
public class AppPairsController {
|
||||
private static final String TAG = AppPairsController.class.getSimpleName();
|
||||
|
||||
private final ShellTaskOrganizer mTaskOrganizer;
|
||||
private final SyncTransactionQueue mSyncQueue;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final AppPairsImpl mImpl = new AppPairsImpl();
|
||||
|
||||
private AppPairsPool mPairsPool;
|
||||
// Active app-pairs mapped by root task id key.
|
||||
private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
|
||||
private final DisplayController mDisplayController;
|
||||
|
||||
public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
||||
DisplayController displayController) {
|
||||
/**
|
||||
* Creates {@link AppPairs}, returns {@code null} if the feature is not supported.
|
||||
*/
|
||||
@Nullable
|
||||
public static AppPairs create(ShellTaskOrganizer organizer,
|
||||
SyncTransactionQueue syncQueue, DisplayController displayController,
|
||||
ShellExecutor mainExecutor) {
|
||||
return new AppPairsController(organizer, syncQueue, displayController,
|
||||
mainExecutor).mImpl;
|
||||
}
|
||||
|
||||
AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
||||
DisplayController displayController, ShellExecutor mainExecutor) {
|
||||
mTaskOrganizer = organizer;
|
||||
mSyncQueue = syncQueue;
|
||||
mDisplayController = displayController;
|
||||
mMainExecutor = mainExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOrganizerRegistered() {
|
||||
void onOrganizerRegistered() {
|
||||
if (mPairsPool == null) {
|
||||
setPairsPool(new AppPairsPool(this));
|
||||
}
|
||||
@@ -64,8 +81,7 @@ public class AppPairsController implements AppPairs {
|
||||
mPairsPool = pool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pair(int taskId1, int taskId2) {
|
||||
boolean pair(int taskId1, int taskId2) {
|
||||
final ActivityManager.RunningTaskInfo task1 = mTaskOrganizer.getRunningTaskInfo(taskId1);
|
||||
final ActivityManager.RunningTaskInfo task2 = mTaskOrganizer.getRunningTaskInfo(taskId2);
|
||||
if (task1 == null || task2 == null) {
|
||||
@@ -74,8 +90,7 @@ public class AppPairsController implements AppPairs {
|
||||
return pair(task1, task2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pair(ActivityManager.RunningTaskInfo task1,
|
||||
boolean pair(ActivityManager.RunningTaskInfo task1,
|
||||
ActivityManager.RunningTaskInfo task2) {
|
||||
return pairInner(task1, task2) != null;
|
||||
}
|
||||
@@ -94,8 +109,7 @@ public class AppPairsController implements AppPairs {
|
||||
return pair;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpair(int taskId) {
|
||||
void unpair(int taskId) {
|
||||
unpair(taskId, true /* releaseToPool */);
|
||||
}
|
||||
|
||||
@@ -135,8 +149,7 @@ public class AppPairsController implements AppPairs {
|
||||
return mDisplayController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
private void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = prefix + " ";
|
||||
final String childPrefix = innerPrefix + " ";
|
||||
pw.println(prefix + this);
|
||||
@@ -155,4 +168,55 @@ public class AppPairsController implements AppPairs {
|
||||
return TAG + "#" + mActiveAppPairs.size();
|
||||
}
|
||||
|
||||
private class AppPairsImpl implements AppPairs {
|
||||
@Override
|
||||
public boolean pair(int task1, int task2) {
|
||||
boolean[] result = new boolean[1];
|
||||
try {
|
||||
mMainExecutor.executeBlocking(() -> {
|
||||
result[0] = AppPairsController.this.pair(task1, task2);
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
Slog.e(TAG, "Failed to pair tasks: " + task1 + ", " + task2);
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pair(ActivityManager.RunningTaskInfo task1,
|
||||
ActivityManager.RunningTaskInfo task2) {
|
||||
boolean[] result = new boolean[1];
|
||||
try {
|
||||
mMainExecutor.executeBlocking(() -> {
|
||||
result[0] = AppPairsController.this.pair(task1, task2);
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
Slog.e(TAG, "Failed to pair tasks: " + task1 + ", " + task2);
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpair(int taskId) {
|
||||
mMainExecutor.execute(() -> {
|
||||
AppPairsController.this.unpair(taskId);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOrganizerRegistered() {
|
||||
mMainExecutor.execute(() -> {
|
||||
AppPairsController.this.onOrganizerRegistered();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
try {
|
||||
mMainExecutor.executeBlocking(() -> AppPairsController.this.dump(pw, prefix));
|
||||
} catch (InterruptedException e) {
|
||||
Slog.e(TAG, "Failed to dump AppPairsController in 2s");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.wm.shell.hidedisplaycutout;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Slog;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -28,17 +29,18 @@ import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Manages the hide display cutout status.
|
||||
*/
|
||||
public class HideDisplayCutoutController implements HideDisplayCutout {
|
||||
public class HideDisplayCutoutController {
|
||||
private static final String TAG = "HideDisplayCutoutController";
|
||||
|
||||
private final Context mContext;
|
||||
private final HideDisplayCutoutOrganizer mOrganizer;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final HideDisplayCutoutImpl mImpl = new HideDisplayCutoutImpl();
|
||||
@VisibleForTesting
|
||||
boolean mEnabled;
|
||||
|
||||
@@ -55,7 +57,7 @@ public class HideDisplayCutoutController implements HideDisplayCutout {
|
||||
* supported.
|
||||
*/
|
||||
@Nullable
|
||||
public static HideDisplayCutoutController create(
|
||||
public static HideDisplayCutout create(
|
||||
Context context, DisplayController displayController, ShellExecutor mainExecutor) {
|
||||
// The SystemProperty is set for devices that support this feature and is used to control
|
||||
// whether to create the HideDisplayCutout instance.
|
||||
@@ -66,7 +68,7 @@ public class HideDisplayCutoutController implements HideDisplayCutout {
|
||||
|
||||
HideDisplayCutoutOrganizer organizer =
|
||||
new HideDisplayCutoutOrganizer(context, displayController, mainExecutor);
|
||||
return new HideDisplayCutoutController(context, organizer, mainExecutor);
|
||||
return new HideDisplayCutoutController(context, organizer, mainExecutor).mImpl;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -88,13 +90,11 @@ public class HideDisplayCutoutController implements HideDisplayCutout {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
private void onConfigurationChanged(Configuration newConfig) {
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull PrintWriter pw) {
|
||||
private void dump(@NonNull PrintWriter pw) {
|
||||
final String prefix = " ";
|
||||
pw.print(TAG);
|
||||
pw.println(" states: ");
|
||||
@@ -103,4 +103,22 @@ public class HideDisplayCutoutController implements HideDisplayCutout {
|
||||
pw.println(mEnabled);
|
||||
mOrganizer.dump(pw);
|
||||
}
|
||||
|
||||
private class HideDisplayCutoutImpl implements HideDisplayCutout {
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
mMainExecutor.execute(() -> {
|
||||
HideDisplayCutoutController.this.onConfigurationChanged(newConfig);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull PrintWriter pw) {
|
||||
try {
|
||||
mMainExecutor.executeBlocking(() -> HideDisplayCutoutController.this.dump(pw));
|
||||
} catch (InterruptedException e) {
|
||||
Slog.e(TAG, "Failed to dump HideDisplayCutoutController in 2s");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,21 @@
|
||||
|
||||
package com.android.wm.shell.apppairs;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
public class TestAppPairsController extends AppPairsController {
|
||||
TestAppPairsPool mPool;
|
||||
private TestAppPairsPool mPool;
|
||||
|
||||
public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
||||
DisplayController displayController) {
|
||||
super(organizer, syncQueue, displayController);
|
||||
super(organizer, syncQueue, displayController, mock(ShellExecutor.class));
|
||||
mPool = new TestAppPairsPool(this);
|
||||
setPairsPool(mPool);
|
||||
}
|
||||
|
||||
@@ -84,8 +84,10 @@ public class WMShellModule {
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static AppPairs provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
|
||||
SyncTransactionQueue syncQueue, DisplayController displayController) {
|
||||
return new AppPairsController(shellTaskOrganizer, syncQueue, displayController);
|
||||
SyncTransactionQueue syncQueue, DisplayController displayController,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return AppPairsController.create(shellTaskOrganizer, syncQueue, displayController,
|
||||
mainExecutor);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
|
||||
Reference in New Issue
Block a user