Move the taskviews initiation after root task view
- Moved the creation of background, appgrid and full taskviews after
root task view becomes ready.
- Made some cleanup in terms of the timing of some of the initiation
calls
- Added more logging for easier debuging
- Added a couple of missing fields to the default theme.
- fixed an issue were the background surface would leak from behind the
task views during animation
Bug: 274801802
Fix: 272099148
Test: Manual
Change-Id: I26a8b67a182806baef03099c7c99432f04230783
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
index 9a24390..e6e903f 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/homeactivities/CarUiPortraitHomeScreen.java
@@ -77,6 +77,8 @@
import com.android.car.portraitlauncher.panel.TaskViewPanel;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
/**
@@ -138,7 +140,8 @@
// All the TaskViews & corresponding helper instance variables.
private CarTaskView mBackgroundTaskView;
private CarTaskView mFullScreenTaskView;
- private boolean mIsRootTaskViewReady;
+ private boolean mIsBackgroundTaskViewReady;
+ private boolean mIsFullScreenTaskViewReady;
private int mNavBarHeight;
private boolean mIsSUWInProgress;
private TaskCategoryManager mTaskCategoryManager;
@@ -156,6 +159,9 @@
*/
private final Messenger mMessenger = new Messenger(new IncomingHandler());
+ /** Holds any messages fired before service connection is establish. */
+ private final List<Message> mMessageCache = new ArrayList<>();
+
private CarUiPortraitDriveStateController mCarUiPortraitDriveStateController;
/**
@@ -179,6 +185,10 @@
// so there is no need to do anything here.
Log.w(TAG, "can't connect to CarUiPortraitService: ", e);
}
+ for (Message msg : mMessageCache) {
+ notifySystemUI(msg);
+ }
+ mMessageCache.clear();
}
public void onServiceDisconnected(ComponentName className) {
@@ -193,9 +203,14 @@
public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
throws RemoteException {
logIfDebuggable("On task moved to front, task = " + taskInfo);
- if (!mIsRootTaskViewReady) {
- logIfDebuggable("Root Task View is not ready yet. Caching the task");
- cacheTask(taskInfo);
+ if (!mRootTaskViewPanel.isReady()) {
+ logIfDebuggable("Root Task View is not ready yet.");
+ if (!TaskCategoryManager.isHomeIntent(taskInfo)
+ && !mTaskCategoryManager.isBackgroundApp(taskInfo)
+ && !mTaskCategoryManager.isAppGridActivity(taskInfo)) {
+
+ cacheTask(taskInfo);
+ }
return;
}
@@ -322,6 +337,7 @@
return;
}
+ logIfDebuggable("Control Bar layout changed!");
updateTaskViewInsets();
updateBackgroundTaskViewInsets();
updateObscuredTouchRegion();
@@ -391,24 +407,6 @@
mTaskViewManager = new TaskViewManager(this, getMainThreadHandler());
}
- ViewGroup backgroundAppArea = findViewById(R.id.background_app_area);
- if (backgroundAppArea != null) {
- setUpBackgroundTaskView(backgroundAppArea);
- }
-
- if (mAppGridTaskViewPanel != null) {
- setUpAppGridTaskView();
- }
-
- if (mRootTaskViewPanel != null) {
- setUpRootTaskView();
- }
-
- ViewGroup fullscreenContainer = findViewById(R.id.fullscreen_container);
- if (fullscreenContainer != null) {
- setUpFullScreenTaskView(fullscreenContainer);
- }
-
mCarUiPortraitDriveStateController = new CarUiPortraitDriveStateController(
getApplicationContext());
@@ -416,6 +414,8 @@
initializeCards();
doBindService();
+
+ setUpRootTaskView();
}
@Override
@@ -517,12 +517,7 @@
}
private void cacheTask(ActivityManager.RunningTaskInfo taskInfo) {
- if (TaskCategoryManager.isHomeIntent(taskInfo)
- || mTaskCategoryManager.isBackgroundApp(taskInfo)
- || mTaskCategoryManager.isAppGridActivity(taskInfo)) {
- logIfDebuggable("Skip as task is a home intent or background app " + taskInfo);
- return;
- }
+ logIfDebuggable("Caching the task: " + taskInfo);
if (mTaskInfoCache.cancelTask(taskInfo)) {
boolean cached = mTaskInfoCache.cacheTask(taskInfo);
logIfDebuggable("Task " + taskInfo + " is cached = " + cached);
@@ -617,7 +612,8 @@
}
}
- private void setUpBackgroundTaskView(ViewGroup parent) {
+ private void setUpBackgroundTaskView() {
+ ViewGroup parent = findViewById(R.id.background_app_area);
mTaskViewManager.createControlledCarTaskView(getMainExecutor(),
ControlledCarTaskViewConfig.builder()
.setActivityIntent(CarLauncherUtils.getMapsIntent(getApplicationContext()))
@@ -626,7 +622,7 @@
new ControlledCarTaskViewCallbacks() {
@Override
public void onTaskViewCreated(CarTaskView taskView) {
- taskView.setTag("Background");
+ logIfDebuggable("Background Task View is created");
taskView.setZOrderOnTop(false);
mBackgroundTaskView = taskView;
parent.addView(mBackgroundTaskView);
@@ -634,6 +630,9 @@
@Override
public void onTaskViewReady() {
+ logIfDebuggable("Background Task View is ready");
+ mIsBackgroundTaskViewReady = true;
+ onTaskViewReadinessUpdated();
updateBackgroundTaskViewInsets();
}
}
@@ -651,6 +650,7 @@
}
private void setUpAppGridTaskView() {
+ mAppGridTaskViewPanel.setTag("AppGridPanel");
mTaskViewManager.createControlledCarTaskView(getMainExecutor(),
ControlledCarTaskViewConfig.builder()
.setActivityIntent(CarLauncherUtils.getAppsGridIntent())
@@ -665,7 +665,9 @@
@Override
public void onTaskViewReady() {
- updateBackgroundTaskViewInsets();
+ logIfDebuggable("App grid Task View is ready");
+ mAppGridTaskViewPanel.setReady(true);
+ onTaskViewReadinessUpdated();
}
}
);
@@ -694,35 +696,63 @@
});
}
+ private boolean isAllTaskViewsReady() {
+ return mRootTaskViewPanel.isReady() && mAppGridTaskViewPanel.isReady()
+ && mIsBackgroundTaskViewReady && mIsFullScreenTaskViewReady;
+ }
+
+ private void onTaskViewReadinessUpdated() {
+ if (!isAllTaskViewsReady()) {
+ return;
+ }
+ logIfDebuggable("All task views are ready");
+ updateObscuredTouchRegion();
+ updateBackgroundTaskViewInsets();
+ notifySystemUI(MSG_FG_TASK_VIEW_READY, boolToInt(true));
+ Rect controlBarBounds = new Rect();
+ mControlBarView.getBoundsOnScreen(controlBarBounds);
+ boolean isControlBarVisible = mControlBarView.getVisibility() == View.VISIBLE;
+ logIfDebuggable("Control bar:"
+ + "( visible: " + isControlBarVisible
+ + ", bounds:" + controlBarBounds
+ + ")");
+ }
+
private void setUpRootTaskView() {
+ mRootTaskViewPanel.setTag("RootPanel");
mRootTaskViewPanel.setTaskViewBackgroundColor(Color.BLACK);
mRootTaskViewPanel.setOnStateChangeListener(new TaskViewPanel.OnStateChangeListener() {
@Override
public void onStateChangeStart(TaskViewPanel.State oldState,
TaskViewPanel.State newState, boolean animated) {
- boolean isSystemBarHidden = newState.isFullScreen();
- if (isSystemBarHidden) {
+ boolean isFullScreen = newState.isFullScreen();
+ if (isFullScreen) {
setHomeScreenBottomMargin(mIsSUWInProgress ? 0 : mNavBarHeight);
+ if (!mIsSUWInProgress) {
+ notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(isFullScreen));
+ }
} else {
- setHomeScreenBottomMargin(mNavBarHeight);
setControlBarVisibility(/* isVisible= */ true, animated);
}
-
- if (!mIsSUWInProgress) {
- notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE, boolToInt(isSystemBarHidden));
- }
}
@Override
public void onStateChangeEnd(TaskViewPanel.State oldState,
TaskViewPanel.State newState, boolean animated) {
updateObscuredTouchRegion();
-
updateBackgroundTaskViewInsets();
// Hide the control bar after the animation if in full screen.
if (newState.isFullScreen()) {
setControlBarVisibility(/* isVisible= */ false, animated);
+ } else {
+ // Adjust the bottom margin to count for the nav bar.
+ setHomeScreenBottomMargin(mNavBarHeight);
+ // Show the nav bar if not showing Setup Wizard
+ if (!mIsSUWInProgress) {
+ notifySystemUI(MSG_HIDE_SYSTEM_BAR_FOR_IMMERSIVE,
+ boolToInt(newState.isFullScreen()));
+ }
}
// Hide the app grid task view behind the root task view.
@@ -739,24 +769,27 @@
new LaunchRootCarTaskViewCallbacks() {
@Override
public void onTaskViewCreated(CarTaskView taskView) {
+ logIfDebuggable("Root Task View is created");
taskView.setZOrderMediaOverlay(true);
mRootTaskViewPanel.setTaskView(taskView);
}
@Override
public void onTaskViewReady() {
- mIsRootTaskViewReady = true;
+ logIfDebuggable("Root Task View is ready");
+ mRootTaskViewPanel.setReady(true);
mTaskInfoCache.startCachedTasks();
- logIfDebuggable("Foreground Task View is ready");
- notifySystemUI(MSG_FG_TASK_VIEW_READY, boolToInt(true));
- // Launch the blank activity in the root task view to make sure we do not
- // present a dialog on top of empty space.
- startActivity(BlankActivity.createIntent(getApplicationContext()));
+ onTaskViewReadinessUpdated();
+
+ setUpBackgroundTaskView();
+ setUpAppGridTaskView();
+ setUpFullScreenTaskView();
}
});
}
- private void setUpFullScreenTaskView(ViewGroup parent) {
+ private void setUpFullScreenTaskView() {
+ ViewGroup parent = findViewById(R.id.fullscreen_container);
mTaskViewManager.createSemiControlledTaskView(getMainExecutor(),
new SemiControlledCarTaskViewCallbacks() {
@Override
@@ -769,6 +802,7 @@
@Override
public void onTaskViewCreated(CarTaskView taskView) {
+ logIfDebuggable("FullScreen Task View is created");
mFullScreenTaskView = taskView;
mFullScreenTaskView.setZOrderOnTop(true);
parent.addView(mFullScreenTaskView);
@@ -776,6 +810,9 @@
@Override
public void onTaskViewReady() {
+ logIfDebuggable("FullScreen Task View is ready");
+ mIsFullScreenTaskViewReady = true;
+ onTaskViewReadinessUpdated();
}
});
}
@@ -845,9 +882,16 @@
private void notifySystemUI(int key, int value) {
Message msg = Message.obtain(null, key, value, 0);
+ notifySystemUI(msg);
+ }
+
+ private void notifySystemUI(Message msg) {
try {
if (mService != null) {
mService.send(msg);
+ } else {
+ logIfDebuggable("Service is not connected yet! Caching the message:" + msg);
+ mMessageCache.add(msg);
}
} catch (RemoteException e) {
throw new RuntimeException(e);
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/TaskViewPanel.java b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/TaskViewPanel.java
index c422c2e..84f1b61 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/TaskViewPanel.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/TaskViewPanel.java
@@ -85,6 +85,12 @@
public boolean isFullScreen() {
return mIsFullScreen;
}
+
+ /** The string representation of the state. Used for debugging */
+ public String toString() {
+ return "(visible: " + isVisible() + ", fullscreen: " + isFullScreen() + ", bounds: "
+ + mBounds + ")";
+ }
}
/** Notifies the listener when the panel state changes. */
@@ -160,6 +166,9 @@
/** The surface view showed on the back of the panel. */
private BackgroundSurfaceView mBackgroundSurfaceView;
+ /** The flag indicating if the task view on the panel is ready. */
+ private boolean mIsReady;
+
public TaskViewPanel(Context context) {
this(context, null);
}
@@ -249,7 +258,8 @@
/** Transitions the panel into the close state using the fade-out animation. */
public void fadeOutPanel() {
PanelAnimator animator =
- new FadeOutPanelAnimator(this, mTaskViewOverlay, mTaskView, mOpenState.mBounds);
+ new FadeOutPanelAnimator(this, mBackgroundSurfaceView, mTaskViewOverlay,
+ mTaskView, mOpenState.mBounds);
setActiveState(mCloseState, animator);
}
@@ -288,9 +298,19 @@
/** Updates the {@code TaskView} used in the panel. */
public void setTaskView(CarTaskView taskView) {
- logIfDebuggable("TaskView updated " + taskView);
mTaskView = taskView;
mTaskViewContainer.addView(mTaskView);
+ onParentDimensionChanged();
+ }
+
+ /** Updates the readiness state of the panel. */
+ public void setReady(boolean isReady) {
+ mIsReady = isReady;
+ }
+
+ /** Returns whether the panel is ready. */
+ public boolean isReady() {
+ return mIsReady;
}
/** Refreshes the panel according to the given {@code Theme}. */
@@ -302,7 +322,6 @@
mBackgroundSurfaceView.refresh(theme);
}
-
/**
* Updates the Obscured touch region of the panel.
* This need to be called if there are areas that the task view should not receive a touch
@@ -375,7 +394,11 @@
updateInsets(mActiveState.mInsets);
recalculateBounds();
updateBounds(mActiveState.mBounds);
- post(() -> mTaskView.onLocationChanged());
+ post(() -> {
+ if (mTaskView != null) {
+ mTaskView.onLocationChanged();
+ }
+ });
}
/** Sets a fixed background color for the task view. */
@@ -393,11 +416,15 @@
int parentWidth = ((ViewGroup) getParent()).getWidth();
int parentHeight = ((ViewGroup) getParent()).getHeight();
- Log.w(TAG, "onDimensionChanged: " + parentWidth + " " + parentHeight);
+ logIfDebuggable("onDimensionChanged: " + parentWidth + " " + parentHeight);
recalculateBounds();
- post(() -> mTaskView.onLocationChanged());
+ post(() -> {
+ if (mTaskView != null) {
+ mTaskView.onLocationChanged();
+ }
+ });
updateBounds(mActiveState.mBounds);
}
@@ -414,8 +441,9 @@
}
private void setActiveState(State toState, PanelAnimator animator) {
- Log.w(TAG, "SetActiveState to " + toState.mBounds);
State fromState = mActiveState;
+ logIfDebuggable("Panel( " + getTag() + ") active state changes from " + fromState
+ + " to " + toState);
boolean animated = animator != null;
onStateChangeStart(fromState, toState, animated);
@@ -456,9 +484,12 @@
// to a visible state and only if the window bounds is not changed since the last visible
// state.
Rect taskViewBounds = getTaskViewBounds(mActiveState);
- if (mActiveState.isVisible() && !taskViewBounds.equals(mTaskViewWindowBounds)) {
- mTaskViewWindowBounds = taskViewBounds;
- logIfDebuggable("TaskView bounds: " + mTaskViewWindowBounds);
+ if (!mActiveState.isVisible() || taskViewBounds.equals(mTaskViewWindowBounds)) {
+ return;
+ }
+ mTaskViewWindowBounds = taskViewBounds;
+ logIfDebuggable("TaskView bounds: " + mTaskViewWindowBounds);
+ if (mTaskView != null) {
mTaskView.setWindowBounds(taskViewBounds);
}
}
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FadeOutPanelAnimator.java b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FadeOutPanelAnimator.java
index 21f2f45..2b548d8 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FadeOutPanelAnimator.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FadeOutPanelAnimator.java
@@ -39,6 +39,7 @@
private static final float FADE_OUT_ALPHA = 0;
private static final float FADE_IN_ALPHA = 1;
+ private final View mBackground;
private final View mOverlay;
private final View mTaskView;
private final Rect mBounds;
@@ -47,13 +48,16 @@
* A {@code PanelAnimator} to animate the panel into the open state using the fade-in animation.
*
* @param panel The panel that should animate
- * @param overlay The overlay view that covers the taskView. Used to visually fade out the task
- * view.
+ * @param background The view shown behind the {@code TaskView}.
+ * @param overlay The overlay view that covers the {@code TaskView}. Used to visually fade out
+ * the {@code TaskView}.
* @param taskView The task view of the panel.
* @param toBounds The final bounds of the panel within its parent
*/
- public FadeOutPanelAnimator(ViewGroup panel, View overlay, View taskView, Rect toBounds) {
+ public FadeOutPanelAnimator(ViewGroup panel, View background, View overlay, View taskView,
+ Rect toBounds) {
super(panel);
+ mBackground = background;
mOverlay = overlay;
mTaskView = taskView;
mBounds = toBounds;
@@ -62,6 +66,7 @@
@Override
public void animate(Runnable endAction) {
updateBounds(mBounds);
+ mBackground.setVisibility(GONE);
mOverlay.setVisibility(VISIBLE);
mOverlay.setAlpha(FADE_OUT_ALPHA);
// First fade in the overlay and then fade-out the whole panel.
@@ -70,6 +75,7 @@
.withEndAction(() -> {
mPanel.animate().alpha(FADE_OUT_ALPHA).setDuration(PANEL_FADE_OUT_DURATION)
.withEndAction(() -> {
+ mBackground.setVisibility(VISIBLE);
mOverlay.setVisibility(GONE);
mTaskView.setVisibility(VISIBLE);
mTaskView.setAlpha(FADE_IN_ALPHA);
diff --git a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FullScreenPanelAnimator.java b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FullScreenPanelAnimator.java
index 84c1292..2019a9c 100644
--- a/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FullScreenPanelAnimator.java
+++ b/car_product/car_ui_portrait/apps/CarUiPortraitLauncher/src/com/android/car/portraitlauncher/panel/animation/FullScreenPanelAnimator.java
@@ -59,6 +59,6 @@
Animation animation = new BoundsAnimation(mPanel, mBounds, endAction);
animation.setInterpolator(INTERPOLATOR);
animation.setDuration(DURATION);
- mPanel.startAnimation(animation);
+ mPanel.post(() -> mPanel.startAnimation(animation));
}
}
diff --git a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
index 96fadd6..8b3d839 100644
--- a/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
+++ b/car_product/car_ui_portrait/rro/CarUIPortraitCommon/src/com/android/car/caruiportrait/common/service/CarUiPortraitService.java
@@ -26,6 +26,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import android.util.Log;
import java.util.ArrayList;
@@ -116,6 +117,7 @@
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
+ Log.d(TAG, "Received message: " + msg.what);
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
@@ -173,6 +175,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(REQUEST_FROM_SYSTEM_UI);
registerReceiver(immersiveModeChangeReceiver, filter);
+ Log.d(TAG, "Portrait service is created");
}
@Override
diff --git a/car_product/car_ui_portrait/rro/android/res/values-port/themes_device_defaults.xml b/car_product/car_ui_portrait/rro/android/res/values-port/themes_device_defaults.xml
index e4aef32..9348f1c 100644
--- a/car_product/car_ui_portrait/rro/android/res/values-port/themes_device_defaults.xml
+++ b/car_product/car_ui_portrait/rro/android/res/values-port/themes_device_defaults.xml
@@ -41,6 +41,7 @@
<item name="android:colorBackgroundFloating">@color/floating_background_color</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:colorButtonNormal">@color/btn_device_default</item>
+ <item name="android:colorAccent">@color/car_primary</item>
<item name="android:colorActivatedHighlight">@color/car_control_highlight</item>
<item name="android:colorBackground">@color/car_background</item>
<item name="android:colorControlHighlight">@color/car_control_highlight</item>
@@ -48,6 +49,8 @@
<item name="android:colorFocusedHighlight">@color/car_control_highlight</item>
<item name="android:textColorPrimary">@color/car_on_background</item>
<item name="android:textColorPrimaryInverse">@color/car_background</item>
+ <item name="android:textColorSecondary">@color/car_secondary</item>
+ <item name="android:textColorSecondaryInverse">@color/car_on_secondary</item>
<item name="android:listDivider">@color/list_divider_color</item>
<item name="android:alertDialogTheme">@android:style/Theme.DeviceDefault.Dialog.Alert</item>