diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background.xml
new file mode 100644
index 0000000000000..723963ff8c9ad
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background_ripple.xml
new file mode 100644
index 0000000000000..0a3a81302a49b
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_background_ripple.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more.xml
new file mode 100644
index 0000000000000..ff5740609b84e
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more_ripple.xml
new file mode 100644
index 0000000000000..16dea484b644e
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_expand_more_ripple.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml
new file mode 100644
index 0000000000000..cbfcfd06e3b70
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml
new file mode 100644
index 0000000000000..469eb1e14849c
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml
new file mode 100644
index 0000000000000..dcb8aed05c9c6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
new file mode 100644
index 0000000000000..cd1d99ae58b04
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
new file mode 100644
index 0000000000000..edf737fcc86ad
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_overlay_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_overlay_layout.xml
new file mode 100644
index 0000000000000..f4c6d65bad055
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_overlay_layout.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_toast_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_toast_layout.xml
new file mode 100644
index 0000000000000..a309d4829f0d5
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_toast_layout.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/values/attrs.xml b/libs/WindowManager/Shell/res/values/attrs.xml
new file mode 100644
index 0000000000000..4aaeef8afcb0e
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values/attrs.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index cf596f7d15dcc..84aec640434b9 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -34,6 +34,9 @@
@android:color/system_neutral1_800
@android:color/system_neutral1_50
+
+ @android:color/system_neutral2_200
+
#E8EAED
#5F6368
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 1c19a10ab2311..ab2c9b1466b84 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -219,6 +219,37 @@
143dp
+
+ 100dp
+
+
+ 28dp
+
+
+ 16dp
+
+
+ 24dp
+
+
+ 48dp
+
+
+ 136dp
+
+
+ 18dp
+
+
+ 444dp
+
+
+ 398dp
+
+
+ 20dp
+
200dp
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index ab0013a2b0b4b..a8a9ed74cd357 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -171,4 +171,28 @@
compatibility control. [CHAR LIMIT=NONE] -->
No camera issues? Tap to dismiss.
+
+ Get the most out of %s
+
+
+ Rotate your device for a full-screen view
+
+
+ Rotate your screen to portrait
+
+
+ Rotate your screen to landscape
+
+
+ Drag in another app to use split screen
+
+
+ Double tap to reposition
+
+
+ Got it
+
+
+ Expand for more information.
+
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java
new file mode 100644
index 0000000000000..762a037d19dfa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 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.wm.shell.compatui.letterboxedu;
+
+import android.annotation.StringRes;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Custom layout for Letterbox Education dialog action.
+ */
+// TODO(b/215316431): Add tests
+class LetterboxEduDialogActionLayout extends FrameLayout {
+ private final ImageView mIcon;
+ private final TextView mText;
+
+ LetterboxEduDialogActionLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ TypedArray styledAttributes =
+ context.getTheme().obtainStyledAttributes(
+ attrs,
+ R.styleable.LetterboxEduDialogActionLayout,
+ /* defStyleAttr= */ 0,
+ /* defStyleRes= */ 0);
+ int iconId = styledAttributes.getResourceId(
+ R.styleable.LetterboxEduDialogActionLayout_icon, 0);
+ String optionalText = styledAttributes.getString(
+ R.styleable.LetterboxEduDialogActionLayout_text);
+ styledAttributes.recycle();
+
+ View rootView = inflate(getContext(), R.layout.letterbox_education_dialog_action_layout,
+ this);
+
+ mIcon = rootView.findViewById(R.id.letterbox_education_dialog_action_icon);
+ mIcon.setImageResource(iconId);
+ mText = rootView.findViewById(R.id.letterbox_education_dialog_action_text);
+ if (optionalText != null) {
+ mText.setText(optionalText);
+ }
+ }
+
+ void setText(@StringRes int id) {
+ mText.setText(getResources().getString(id));
+ }
+
+ void setIconRotation(float rotation) {
+ mIcon.setRotation(rotation);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
new file mode 100644
index 0000000000000..662862afd4613
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 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.wm.shell.compatui.letterboxedu;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Configuration.Orientation;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Container for Letterbox Education Dialog.
+ */
+// TODO(b/215316431): Add tests
+public class LetterboxEduDialogLayout extends FrameLayout {
+
+ public LetterboxEduDialogLayout(Context context) {
+ this(context, null);
+ }
+
+ public LetterboxEduDialogLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LetterboxEduDialogLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public LetterboxEduDialogLayout(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ /**
+ * Register a callback for the dismiss button.
+ * @param callback The callback to register
+ */
+ void setDismissOnClickListener(Runnable callback) {
+ findViewById(R.id.letterbox_education_dialog_dismiss).setOnClickListener(
+ view -> callback.run());
+ }
+
+ /**
+ * Updates the layout with the given app info.
+ * @param appIcon The name of the app
+ * @param appIcon The icon of the app
+ */
+ void updateAppInfo(String appName, Drawable appIcon) {
+ ((ImageView) findViewById(R.id.letterbox_education_icon)).setImageDrawable(appIcon);
+ ((TextView) findViewById(R.id.letterbox_education_dialog_title)).setText(
+ getResources().getString(R.string.letterbox_education_dialog_title, appName));
+ }
+
+ /**
+ * Updates the layout according to the given orientation.
+ * @param orientation The orientation of the display
+ */
+ void updateDisplayOrientation(@Orientation int orientation) {
+ boolean isOrientationPortrait = orientation == Configuration.ORIENTATION_PORTRAIT;
+ ((LetterboxEduDialogActionLayout) findViewById(
+ R.id.letterbox_education_dialog_screen_rotation_action)).setText(
+ isOrientationPortrait
+ ? R.string.letterbox_education_screen_rotation_landscape_text
+ : R.string.letterbox_education_screen_rotation_portrait_text);
+
+ if (isOrientationPortrait) {
+ ((LetterboxEduDialogActionLayout) findViewById(
+ R.id.letterbox_education_dialog_split_screen_action)).setIconRotation(90f);
+ }
+
+ findViewById(R.id.letterbox_education_dialog_reposition_action).setVisibility(
+ isOrientationPortrait ? View.GONE : View.VISIBLE);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduToastLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduToastLayout.java
new file mode 100644
index 0000000000000..e7f592dcb14de
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduToastLayout.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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.wm.shell.compatui.letterboxedu;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Container for the Letterbox Education Toast.
+ */
+// TODO(b/215316431): Add tests
+public class LetterboxEduToastLayout extends FrameLayout {
+
+ public LetterboxEduToastLayout(Context context) {
+ this(context, null);
+ }
+
+ public LetterboxEduToastLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LetterboxEduToastLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public LetterboxEduToastLayout(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ /**
+ * Register a callback for the dismiss button.
+ * @param callback The callback to register
+ */
+ void setExpandOnClickListener(Runnable callback) {
+ findViewById(R.id.letterbox_education_toast_expand).setOnClickListener(
+ view -> callback.run());
+ }
+
+ /**
+ * Updates the layout with the given app info.
+ * @param appName The name of the app
+ * @param appIcon The icon of the app
+ */
+ void updateAppInfo(String appName, Drawable appIcon) {
+ ImageView icon = findViewById(R.id.letterbox_education_icon);
+ icon.setContentDescription(appName);
+ icon.setImageDrawable(appIcon);
+ }
+}