blob: 96be5dfe1121871ce321262def7ddbdd4d1159b6 [file] [log] [blame]
Samuel Fufaaed008d2019-12-19 10:57:40 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.launcher3.hybridhotseat;
17
Samuel Fufa6fd62fd2020-06-09 18:10:31 -070018import static com.android.launcher3.logging.StatsLogManager.LauncherEvent
19 .LAUNCHER_HOTSEAT_EDU_ACCEPT;
20import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_EDU_DENY;
21import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_EDU_SEEN;
Samuel Fufab641ac22020-02-10 17:58:11 -080022
Samuel Fufaaed008d2019-12-19 10:57:40 -080023import android.animation.PropertyValuesHolder;
24import android.content.Context;
25import android.content.res.Configuration;
26import android.graphics.Rect;
27import android.util.AttributeSet;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.widget.Button;
Samuel Fufaa4211432020-02-25 18:47:54 -080031import android.widget.TextView;
Samuel Fufaaed008d2019-12-19 10:57:40 -080032
Samuel Fufa5b2da142020-05-28 16:55:26 -070033import com.android.launcher3.AbstractFloatingView;
Samuel Fufaaed008d2019-12-19 10:57:40 -080034import com.android.launcher3.CellLayout;
35import com.android.launcher3.DeviceProfile;
36import com.android.launcher3.Insettable;
37import com.android.launcher3.Launcher;
38import com.android.launcher3.R;
Samuel Fufaaed008d2019-12-19 10:57:40 -080039import com.android.launcher3.anim.Interpolators;
Samuel Fufaa4211432020-02-25 18:47:54 -080040import com.android.launcher3.config.FeatureFlags;
Sunny Goyale396abf2020-04-06 15:11:17 -070041import com.android.launcher3.model.data.WorkspaceItemInfo;
Samuel Fufaaed008d2019-12-19 10:57:40 -080042import com.android.launcher3.uioverrides.PredictedAppIcon;
43import com.android.launcher3.userevent.nano.LauncherLogProto;
44import com.android.launcher3.views.AbstractSlideInView;
45
46import java.util.List;
47
48/**
49 * User education dialog for hybrid hotseat. Allows user to migrate hotseat items to a new page in
50 * the workspace and shows predictions on the whole hotseat
51 */
52public class HotseatEduDialog extends AbstractSlideInView implements Insettable {
53
54 private static final int DEFAULT_CLOSE_DURATION = 200;
Samuel Fufaa4211432020-02-25 18:47:54 -080055 protected static final int FINAL_SCRIM_BG_COLOR = 0x88000000;
Samuel Fufaaed008d2019-12-19 10:57:40 -080056
Samuel Fufaa4211432020-02-25 18:47:54 -080057
Samuel Fufa82bbdac2020-03-09 18:24:47 -070058 // we use this value to keep track of migration logs as we experiment with different migrations
59 private static final int MIGRATION_EXPERIMENT_IDENTIFIER = 1;
Samuel Fufaaed008d2019-12-19 10:57:40 -080060
61 private final Rect mInsets = new Rect();
62 private View mHotseatWrapper;
63 private CellLayout mSampleHotseat;
Samuel Fufaa4211432020-02-25 18:47:54 -080064 private Button mDismissBtn;
65
Samuel Fufaaed008d2019-12-19 10:57:40 -080066 public void setHotseatEduController(HotseatEduController hotseatEduController) {
67 mHotseatEduController = hotseatEduController;
68 }
69
70 private HotseatEduController mHotseatEduController;
71
72 public HotseatEduDialog(Context context, AttributeSet attr) {
73 this(context, attr, 0);
74 }
75
76 public HotseatEduDialog(Context context, AttributeSet attrs,
77 int defStyleAttr) {
78 super(context, attrs, defStyleAttr);
79 mContent = this;
80 }
81
82
83 @Override
84 protected void onFinishInflate() {
85 super.onFinishInflate();
86 mHotseatWrapper = findViewById(R.id.hotseat_wrapper);
87 mSampleHotseat = findViewById(R.id.sample_prediction);
88
89 DeviceProfile grid = mLauncher.getDeviceProfile();
90 Rect padding = grid.getHotseatLayoutPadding();
91
92 mSampleHotseat.getLayoutParams().height = grid.cellHeightPx;
93 mSampleHotseat.setGridSize(grid.inv.numHotseatIcons, 1);
94 mSampleHotseat.setPadding(padding.left, 0, padding.right, 0);
95
96 Button turnOnBtn = findViewById(R.id.turn_predictions_on);
Samuel Fufaa4211432020-02-25 18:47:54 -080097 turnOnBtn.setOnClickListener(this::onAccept);
Samuel Fufaaed008d2019-12-19 10:57:40 -080098
Samuel Fufaa4211432020-02-25 18:47:54 -080099 mDismissBtn = findViewById(R.id.no_thanks);
100 mDismissBtn.setOnClickListener(this::onDismiss);
Samuel Fufaaed008d2019-12-19 10:57:40 -0800101
Samuel Fufa82bbdac2020-03-09 18:24:47 -0700102 // update ui to reflect which migration method is going to be used
103 if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
104 ((TextView) findViewById(R.id.hotseat_edu_content)).setText(
105 R.string.hotseat_edu_message_migrate_alt);
106 }
Samuel Fufaaed008d2019-12-19 10:57:40 -0800107 }
108
Samuel Fufaa4211432020-02-25 18:47:54 -0800109 private void onAccept(View v) {
Samuel Fufa82bbdac2020-03-09 18:24:47 -0700110 mHotseatEduController.migrate();
Samuel Fufaaed008d2019-12-19 10:57:40 -0800111 handleClose(true);
Samuel Fufaaa2aff52020-03-24 18:34:12 -0700112
113 mHotseatEduController.moveHotseatItems();
Samuel Fufaaed008d2019-12-19 10:57:40 -0800114 mHotseatEduController.finishOnboarding();
Samuel Fufa6fd62fd2020-06-09 18:10:31 -0700115 mLauncher.getStatsLogManager().log(LAUNCHER_HOTSEAT_EDU_ACCEPT);
Samuel Fufaaed008d2019-12-19 10:57:40 -0800116 }
117
Samuel Fufaa4211432020-02-25 18:47:54 -0800118 private void onDismiss(View v) {
Samuel Fufaaa2aff52020-03-24 18:34:12 -0700119 mHotseatEduController.showDimissTip();
Samuel Fufaaed008d2019-12-19 10:57:40 -0800120 mHotseatEduController.finishOnboarding();
Samuel Fufa6fd62fd2020-06-09 18:10:31 -0700121 mLauncher.getStatsLogManager().log(LAUNCHER_HOTSEAT_EDU_DENY);
Samuel Fufaaed008d2019-12-19 10:57:40 -0800122 handleClose(true);
123 }
124
125 @Override
126 public void logActionCommand(int command) {
127 // Since this is on-boarding popup, it is not a user controlled action.
128 }
129
130 @Override
131 public int getLogContainerType() {
132 return LauncherLogProto.ContainerType.TIP;
133 }
134
135 @Override
136 protected boolean isOfType(int type) {
137 return (type & TYPE_ON_BOARD_POPUP) != 0;
138 }
139
140 @Override
141 public void setInsets(Rect insets) {
142 int leftInset = insets.left - mInsets.left;
143 int rightInset = insets.right - mInsets.right;
144 int bottomInset = insets.bottom - mInsets.bottom;
145 mInsets.set(insets);
Samuel Fufabe40b292020-05-18 12:50:29 -0700146 if (mLauncher.getOrientation() == Configuration.ORIENTATION_PORTRAIT) {
147 setPadding(leftInset, getPaddingTop(), rightInset, 0);
148 mHotseatWrapper.setPadding(mHotseatWrapper.getPaddingLeft(), getPaddingTop(),
149 mHotseatWrapper.getPaddingRight(), bottomInset);
150 mHotseatWrapper.getLayoutParams().height =
151 mLauncher.getDeviceProfile().hotseatBarSizePx + insets.bottom;
152
153 } else {
154 setPadding(0, getPaddingTop(), 0, 0);
155 mHotseatWrapper.setPadding(mHotseatWrapper.getPaddingLeft(), getPaddingTop(),
156 mHotseatWrapper.getPaddingRight(),
157 (int) getResources().getDimension(R.dimen.bottom_sheet_edu_padding));
158 ((TextView) findViewById(R.id.hotseat_edu_heading)).setText(
159 R.string.hotseat_edu_title_migrate_landscape);
160 ((TextView) findViewById(R.id.hotseat_edu_content)).setText(
161 R.string.hotseat_edu_message_migrate_landscape);
162 }
Samuel Fufaaed008d2019-12-19 10:57:40 -0800163 }
164
Samuel Fufaaed008d2019-12-19 10:57:40 -0800165 private void animateOpen() {
166 if (mIsOpen || mOpenCloseAnimator.isRunning()) {
167 return;
168 }
169 mIsOpen = true;
170 mOpenCloseAnimator.setValues(
171 PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
172 mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
173 mOpenCloseAnimator.start();
174 }
175
176 @Override
177 protected void handleClose(boolean animate) {
178 handleClose(true, DEFAULT_CLOSE_DURATION);
179 }
180
181 @Override
182 protected void onConfigurationChanged(Configuration newConfig) {
183 super.onConfigurationChanged(newConfig);
184 handleClose(false);
185 }
186
Samuel Fufaa4211432020-02-25 18:47:54 -0800187 @Override
188 protected int getScrimColor(Context context) {
189 return FINAL_SCRIM_BG_COLOR;
190 }
191
192 private void populatePreview(List<WorkspaceItemInfo> predictions) {
Samuel Fufaaed008d2019-12-19 10:57:40 -0800193 for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
194 WorkspaceItemInfo info = predictions.get(i);
195 PredictedAppIcon icon = PredictedAppIcon.createIcon(mSampleHotseat, info);
196 icon.setEnabled(false);
Samuel Fufa6eaf9892020-04-01 11:40:40 -0700197 icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
Samuel Fufaaed008d2019-12-19 10:57:40 -0800198 icon.verifyHighRes();
199 CellLayout.LayoutParams lp = new CellLayout.LayoutParams(i, 0, 1, 1);
200 mSampleHotseat.addViewToCellLayout(icon, i, info.getViewId(), lp, true);
201 }
202 }
203
Samuel Fufaa4211432020-02-25 18:47:54 -0800204 /**
205 * Opens User education dialog with a list of suggested apps
206 */
207 public void show(List<WorkspaceItemInfo> predictions) {
208 if (getParent() != null
209 || predictions.size() < mLauncher.getDeviceProfile().inv.numHotseatIcons
210 || mHotseatEduController == null) {
211 return;
212 }
Samuel Fufa5b2da142020-05-28 16:55:26 -0700213 AbstractFloatingView.closeAllOpenViews(mLauncher);
Samuel Fufaa4211432020-02-25 18:47:54 -0800214 attachToContainer();
Samuel Fufa6fd62fd2020-06-09 18:10:31 -0700215 mLauncher.getStatsLogManager().log(LAUNCHER_HOTSEAT_EDU_SEEN);
Samuel Fufaa4211432020-02-25 18:47:54 -0800216 animateOpen();
217 populatePreview(predictions);
218 }
219
Samuel Fufaaed008d2019-12-19 10:57:40 -0800220 /**
221 * Factory method for HotseatPredictionUserEdu dialog
222 */
223 public static HotseatEduDialog getDialog(Launcher launcher) {
224 LayoutInflater layoutInflater = LayoutInflater.from(launcher);
225 return (HotseatEduDialog) layoutInflater.inflate(
226 R.layout.predicted_hotseat_edu, launcher.getDragLayer(),
227 false);
228
229 }
230}