Merge "Revert "Revert "Use autogenerated SysUiStatsLog for statsd logging""" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml b/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml
index f0e70a8..fa3a0f8 100644
--- a/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml
+++ b/quickstep/recents_ui_overrides/res/drawable/hotseat_edu_notification_icon.xml
@@ -15,5 +15,5 @@
-->
<vector android:height="24dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@color/hotseat_edu_background" android:pathData="M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zm-7.5.5L9 4 6.5 9.5 1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z"/>
+ <path android:fillColor="@color/bottom_panel_background" android:pathData="M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zm-7.5.5L9 4 6.5 9.5 1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z"/>
</vector>
diff --git a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
index ee38e3b..a7cd167 100644
--- a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
+++ b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
@@ -24,12 +24,13 @@
<View
android:layout_width="match_parent"
android:layout_height="32dp"
- android:background="@drawable/hotseat_prediction_edu_top" />
+ android:backgroundTint="@color/bottom_panel_background"
+ android:background="@drawable/bottom_sheet_top_border" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@color/hotseat_edu_background"
+ android:background="@color/bottom_panel_background"
android:orientation="vertical">
<TextView
@@ -37,8 +38,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:fontFamily="google-sans"
- android:paddingLeft="@dimen/hotseat_edu_padding"
- android:paddingRight="@dimen/hotseat_edu_padding"
+ android:paddingLeft="@dimen/bottom_sheet_edu_padding"
+ android:paddingRight="@dimen/bottom_sheet_edu_padding"
android:text="@string/hotseat_migrate_title"
android:textAlignment="center"
android:textColor="@android:color/white"
@@ -50,8 +51,8 @@
android:layout_marginTop="18dp"
android:layout_marginBottom="18dp"
android:fontFamily="roboto-medium"
- android:paddingLeft="@dimen/hotseat_edu_padding"
- android:paddingRight="@dimen/hotseat_edu_padding"
+ android:paddingLeft="@dimen/bottom_sheet_edu_padding"
+ android:paddingRight="@dimen/bottom_sheet_edu_padding"
android:text="@string/hotseat_migrate_message"
android:textAlignment="center"
android:textColor="@android:color/white"
@@ -72,9 +73,9 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="@dimen/hotseat_edu_padding"
+ android:paddingLeft="@dimen/bottom_sheet_edu_padding"
android:paddingTop="8dp"
- android:paddingRight="@dimen/hotseat_edu_padding">
+ android:paddingRight="@dimen/bottom_sheet_edu_padding">
<Button
android:id="@+id/turn_predictions_on"
diff --git a/quickstep/recents_ui_overrides/res/values/colors.xml b/quickstep/recents_ui_overrides/res/values/colors.xml
index 4fa5684..7426e30 100644
--- a/quickstep/recents_ui_overrides/res/values/colors.xml
+++ b/quickstep/recents_ui_overrides/res/values/colors.xml
@@ -6,6 +6,4 @@
<color name="all_apps_label_text_dark">#61FFFFFF</color>
<color name="all_apps_prediction_row_separator">#3c000000</color>
<color name="all_apps_prediction_row_separator_dark">#3cffffff</color>
-
- <color name="hotseat_edu_background">#f01A73E8</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/res/values/dimens.xml b/quickstep/recents_ui_overrides/res/values/dimens.xml
index c458ec7..de97d08 100644
--- a/quickstep/recents_ui_overrides/res/values/dimens.xml
+++ b/quickstep/recents_ui_overrides/res/values/dimens.xml
@@ -29,7 +29,4 @@
<dimen name="swipe_up_y_overshoot">10dp</dimen>
<dimen name="swipe_up_max_workspace_trans_y">-60dp</dimen>
- <!-- Hybrid hotseat related -->
- <dimen name="hotseat_edu_padding">24dp</dimen>
-
</resources>
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 923e050..bfbd00e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -109,7 +109,7 @@
NOTIFICATION_CHANNEL_ID)
.setContentTitle(name)
.setOngoing(true)
- .setColor(mLauncher.getColor(R.color.hotseat_edu_background))
+ .setColor(mLauncher.getColor(R.color.bottom_panel_background))
.setContentIntent(PendingIntent.getActivity(mLauncher, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT))
.setSmallIcon(R.drawable.hotseat_edu_notification_icon)
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index cb20ed0..c1ea533 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -1918,6 +1918,11 @@
@Override
public void addView(View child, int index) {
+ // RecentsView is set to RTL in the constructor when system is using LTR. Here we set the
+ // child direction back to match system settings.
+ child.setLayoutDirection(
+ Utilities.isRtl(getResources())
+ ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
super.addView(child, index);
if (isExtraCardView(child, index)) {
mTaskViewStartIndex++;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 5539b3e..3c6537a 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -18,6 +18,8 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
@@ -25,6 +27,7 @@
import android.os.RemoteException;
import android.util.Log;
import android.view.MotionEvent;
+
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.quickstep.util.SharedApiCompat;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -282,4 +285,15 @@
}
}
}
+
+ @Override
+ public void handleImageAsScreenshot(Bitmap bitmap, Rect rect, Insets insets, int i) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSystemUiProxy.handleImageAsScreenshot(bitmap, rect, insets, i);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call handleImageAsScreenshot", e);
+ }
+ }
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 71d77fc..e34ea4a 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -56,6 +56,7 @@
@Before
public void setUp() throws Exception {
+ mLauncherPid = 0;
super.setUp();
TaplTestsLauncher3.initialize(this);
mLauncherPid = mLauncher.getPid();
@@ -63,7 +64,9 @@
@After
public void teardown() {
- assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid());
+ if (mLauncherPid != 0) {
+ assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid());
+ }
}
private void startTestApps() throws Exception {
diff --git a/res/drawable-hdpi/work_tab_user_education.png b/res/drawable-hdpi/work_tab_user_education.png
deleted file mode 100644
index 1879dfb..0000000
--- a/res/drawable-hdpi/work_tab_user_education.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/work_tab_user_education.png b/res/drawable-mdpi/work_tab_user_education.png
deleted file mode 100644
index 65c7e63..0000000
--- a/res/drawable-mdpi/work_tab_user_education.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/work_tab_user_education.png b/res/drawable-xhdpi/work_tab_user_education.png
deleted file mode 100644
index 59df7a8..0000000
--- a/res/drawable-xhdpi/work_tab_user_education.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/work_tab_user_education.png b/res/drawable-xxhdpi/work_tab_user_education.png
deleted file mode 100644
index 3c6aa20..0000000
--- a/res/drawable-xxhdpi/work_tab_user_education.png
+++ /dev/null
Binary files differ
diff --git a/quickstep/recents_ui_overrides/res/drawable/hotseat_prediction_edu_top.xml b/res/drawable/bottom_sheet_top_border.xml
similarity index 84%
rename from quickstep/recents_ui_overrides/res/drawable/hotseat_prediction_edu_top.xml
rename to res/drawable/bottom_sheet_top_border.xml
index e3cc549..23f4e51 100644
--- a/quickstep/recents_ui_overrides/res/drawable/hotseat_prediction_edu_top.xml
+++ b/res/drawable/bottom_sheet_top_border.xml
@@ -15,5 +15,5 @@
-->
<vector android:height="15.53398dp" android:viewportHeight="32"
android:viewportWidth="412" android:width="200dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@color/hotseat_edu_background" android:pathData="M412,32v-2.64C349.26,10.51 279.5,0 206,0S62.74,10.51 0,29.36V32H412z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M412,32v-2.64C349.26,10.51 279.5,0 206,0S62.74,10.51 0,29.36V32H412z"/>
</vector>
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index a1033f0..893d796 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -41,7 +41,7 @@
android:paddingLeft="12dp"
android:paddingRight="12dp" >
- <com.android.launcher3.ExtendedEditText
+ <com.android.launcher3.folder.FolderNameEditText
android:id="@+id/folder_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
diff --git a/res/layout/work_profile_edu.xml b/res/layout/work_profile_edu.xml
new file mode 100644
index 0000000..a8e3d20
--- /dev/null
+++ b/res/layout/work_profile_edu.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 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.
+-->
+<com.android.launcher3.views.WorkEduView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:gravity="bottom"
+ android:orientation="vertical">
+
+ <View
+ android:layout_width="match_parent"
+ android:backgroundTint="@color/bottom_panel_background"
+ android:layout_height="32dp"
+ android:background="@drawable/bottom_sheet_top_border" />
+
+ <LinearLayout
+ android:id="@+id/view_wrapper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/bottom_panel_background"
+ android:orientation="vertical"
+ android:paddingLeft="@dimen/bottom_sheet_edu_padding"
+ android:paddingRight="@dimen/bottom_sheet_edu_padding">
+
+ <TextView
+ android:id="@+id/content_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="48dp"
+ android:layout_marginBottom="48dp"
+ android:fontFamily="google-sans"
+ android:text="@string/work_profile_edu_personal_apps"
+ android:textAlignment="center"
+ android:textColor="@android:color/white"
+ android:textSize="20sp" />
+
+ <Button
+ android:id="@+id/proceed"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_gravity="end"
+ android:background="?android:attr/selectableItemBackground"
+ android:gravity="center"
+ android:text="@string/work_profile_edu_next"
+ android:textAlignment="center"
+ android:textColor="@android:color/white" />
+ </LinearLayout>
+
+</com.android.launcher3.views.WorkEduView>
\ No newline at end of file
diff --git a/res/layout/work_tab_bottom_user_education_view.xml b/res/layout/work_tab_bottom_user_education_view.xml
deleted file mode 100644
index ac2deeb..0000000
--- a/res/layout/work_tab_bottom_user_education_view.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<com.android.launcher3.views.BottomUserEducationView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:background="?android:attr/colorAccent"
- android:elevation="2dp"
- android:focusable="true"
- android:orientation="horizontal">
-
- <ImageView
- android:layout_width="134dp"
- android:layout_height="134dp"
- android:layout_marginTop="28dp"
- android:layout_marginLeft="20dp"
- android:src="@drawable/work_tab_user_education"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="24dp"
- android:orientation="vertical">
-
- <ImageView
- android:id="@+id/close_bottom_user_tip"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_marginTop="12dp"
- android:layout_marginEnd="12dp"
- android:layout_gravity="right"
- android:contentDescription="@string/bottom_work_tab_user_education_close_button"
- android:src="@drawable/ic_remove_no_shadow"/>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:layout_marginEnd="24dp"
- android:fontFamily="roboto-medium"
- android:text="@string/bottom_work_tab_user_education_title"
- android:textColor="@android:color/white"
- android:textSize="20sp"/>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="24dp"
- android:text="@string/bottom_work_tab_user_education_body"
- android:textColor="@android:color/white"
- android:textSize="14sp"/>
-
- </LinearLayout>
-
-</com.android.launcher3.views.BottomUserEducationView>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 815ae21..36f8468 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -43,4 +43,7 @@
<color name="back_gesture_tutorial_title_color">#FF000000</color>
<color name="back_gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
<color name="back_gesture_tutorial_primary_color">#1A73E8</color> <!-- Blue -->
+
+
+ <color name="bottom_panel_background">#f01A73E8</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4bcb8a7..0293573 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -235,4 +235,7 @@
<!-- Theming related -->
<dimen name="default_dialog_corner_radius">8dp</dimen>
+ <!-- Onboarding bottomsheet related -->
+ <dimen name="bottom_sheet_edu_padding">24dp</dimen>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 218f6db..3f279f4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -327,17 +327,20 @@
<!-- This string is in the work profile tab when a user has All Apps open on their phone. This is a label for a toggle to turn the work profile on and off. "Work profile" means a separate profile on a user's phone that's specifically for their work apps and managed by their company. "Work" is used as an adjective.-->
<string name="work_profile_toggle_label">Work profile</string>
- <!-- Title of an overlay in All Apps. This overlay is letting a user know about their work profile, which is managed by their employer. "Work apps" are apps in a user's work profile.-->
- <string name="bottom_work_tab_user_education_title">Find work apps here</string>
- <!-- Text in an overlay in All Apps. This overlay is letting a user know about their work profile, which is managed by their employer.-->
- <string name="bottom_work_tab_user_education_body">Each work app has a badge and is kept secure by your organization. Move apps to your Home screen for easier access.</string>
+ <!--- User onboarding title for personal apps -->
+ <string name="work_profile_edu_personal_apps">Personal apps are private & can\'t be seen by IT</string>
+ <!--- User onboarding title for work profile apps -->
+ <string name="work_profile_edu_work_apps">Work apps are badged and monitored by IT</string>
+ <!-- Action label to proceed to the next work profile edu section-->
+ <string name="work_profile_edu_next">Next</string>
+ <!-- Action label to finish work profile edu-->
+ <string name="work_profile_edu_accept">Got it</string>
+
<!-- This string is in the work profile tab when a user has All Apps open on their phone. It describes the label of a toggle, "Work profile," as being managed by the user's employer.
"Organization" is used to represent a variety of businesses, non-profits, and educational institutions).-->
<string name="work_mode_on_label">Managed by your organization</string>
<!-- This string appears under a the label of a toggle in the work profile tab on a user's phone. It describes the status of the toggle, "Work profile," when it's turned off. "Work profile" means a separate profile on a user's phone that's speficially for their work apps and is managed by their company.-->
<string name="work_mode_off_label">Notifications and apps are off</string>
- <string name="bottom_work_tab_user_education_close_button">Close</string>
- <string name="bottom_work_tab_user_education_closed">Closed</string>
<!-- Failed action error message: e.g. Failed: Pause -->
<string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 5b453c3..d64967b 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -21,15 +21,11 @@
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.View;
-import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
-import com.android.launcher3.folder.FolderNameProvider;
import com.android.launcher3.util.UiThreadHelper;
-import java.util.List;
-
/**
* The edit text that reports back when the back key has been pressed.
@@ -105,25 +101,6 @@
UiThreadHelper.hideKeyboardAsync(getContext(), getWindowToken());
}
- @Override
- public void onCommitCompletion(CompletionInfo text) {
- setText(text.getText());
- setSelection(text.getText().length());
- }
-
- /**
- * Currently only used for folder name suggestion.
- */
- public void displayCompletions(List<String> suggestList) {
- int cnt = Math.min(suggestList.size(), FolderNameProvider.SUGGEST_MAX);
- CompletionInfo[] cInfo = new CompletionInfo[cnt];
- for (int i = 0; i < cnt; i++) {
- cInfo[i] = new CompletionInfo(i, i, suggestList.get(i));
- }
- post(() -> getContext().getSystemService(InputMethodManager.class)
- .displayCompletions(this, cInfo));
- }
-
private boolean showSoftInput() {
return requestFocus() &&
getContext().getSystemService(InputMethodManager.class)
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index e2b7b68..0fea0dc 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -45,6 +45,8 @@
*/
public static final int FLAG_MULTI_PAGE_ANIMATION = 0x00000004;
+ public static final int FLAG_MANUAL_FOLDER_NAME = 0x00000008;
+
public int options;
/**
@@ -140,4 +142,10 @@
writer.updateItemInDatabase(this);
}
}
+
+ @Override
+ protected String dumpProperties() {
+ return super.dumpProperties()
+ + " manuallyTypedTitle=" + hasOption(FLAG_MANUAL_FOLDER_NAME);
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 13b7b54..27668eb 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -49,6 +49,7 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.keyboard.FocusedItemDecorator;
@@ -58,9 +59,9 @@
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.BottomUserEducationView;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.views.WorkEduView;
/**
* The all apps view container.
@@ -92,6 +93,8 @@
private boolean mUsingTabs;
private boolean mSearchModeWhileUsingTabs = false;
+ private LauncherStateManager.StateListener mWorkTabListener;
+
private RecyclerViewFastScroller mTouchHandler;
private final Point mFastScrollerOffset = new Point();
@@ -287,7 +290,8 @@
}
@Override
- public void onDropCompleted(View target, DragObject d, boolean success) { }
+ public void onDropCompleted(View target, DragObject d, boolean success) {
+ }
@Override
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
@@ -371,6 +375,7 @@
mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
onTabChanged(mViewPager.getNextPage());
+ mWorkTabListener = WorkEduView.showEduFlowIfNeeded(mLauncher, mWorkTabListener);
} else {
mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
mAH[AdapterHolder.WORK].recyclerView = null;
@@ -416,10 +421,9 @@
.setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
findViewById(R.id.tab_work)
.setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
-
- }
- if (pos == AdapterHolder.WORK) {
- BottomUserEducationView.showIfNeeded(mLauncher);
+ if (pos == AdapterHolder.WORK) {
+ WorkEduView.showWorkEduIfNeeded(mLauncher);
+ }
}
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 844189f..90d8125 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -96,7 +96,7 @@
View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener,
View.OnFocusChangeListener, DragListener, ExtendedEditText.OnBackKeyListener {
private static final String TAG = "Launcher.Folder";
-
+ private static final boolean DEBUG = false;
/**
* We avoid measuring {@link #mContent} with a 0 width or height, as this
* results in CellLayout being measured as UNSPECIFIED, which it does not support.
@@ -146,7 +146,7 @@
@Thunk FolderIcon mFolderIcon;
@Thunk FolderPagedView mContent;
- public ExtendedEditText mFolderName;
+ public FolderNameEditText mFolderName;
private PageIndicatorDots mPageIndicator;
protected View mFooter;
@@ -306,6 +306,7 @@
mFolderName.setText(suggestedNames[0]);
mFolderName.displayCompletions(Arrays.asList(suggestedNames).subList(1,
suggestedNames.length));
+ mFolderName.setEnteredCompose(false);
}
}
mFolderName.setHint("");
@@ -318,7 +319,13 @@
// Convert to a string here to ensure that no other state associated with the text field
// gets saved.
String newTitle = mFolderName.getText().toString();
+ if (DEBUG) {
+ Log.d(TAG, "onBackKey newTitle=" + newTitle);
+ }
+
mInfo.title = newTitle;
+ mInfo.setOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME, mFolderName.isEnteredCompose(),
+ mLauncher.getModelWriter());
mFolderIcon.onTitleChanged(newTitle);
mLauncher.getModelWriter().updateItemInDatabase(mInfo);
@@ -350,6 +357,10 @@
}
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (DEBUG) {
+ Log.d(TAG, "onEditorAction actionId=" + actionId + " key="
+ + (event != null ? event.getKeyCode() : "null event"));
+ }
if (actionId == EditorInfo.IME_ACTION_DONE) {
mFolderName.dispatchBackKey();
return true;
@@ -436,7 +447,8 @@
*/
public void showSuggestedTitle(String[] suggestName) {
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()
- && TextUtils.isEmpty(mFolderName.getText().toString())) {
+ && TextUtils.isEmpty(mFolderName.getText().toString())
+ && !mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) {
if (suggestName.length > 0 && !TextUtils.isEmpty(suggestName[0])) {
mFolderName.setHint("");
mFolderName.setText(suggestName[0]);
@@ -552,9 +564,6 @@
openFolder.close(true);
}
- if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
- mLauncher.getFolderNameProvider().load(getContext());
- }
mContent.bindItems(items);
centerAboutIcon();
mItemsInvalidated = true;
@@ -1495,6 +1504,9 @@
return ContainerType.FOLDER;
}
+ /**
+ * Navigation bar back key or hardware input back key has been issued.
+ */
@Override
public boolean onBackPressed() {
if (isEditingName()) {
diff --git a/src/com/android/launcher3/folder/FolderNameEditText.java b/src/com/android/launcher3/folder/FolderNameEditText.java
new file mode 100644
index 0000000..7e3f847
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderNameEditText.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 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.launcher3.folder;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputConnectionWrapper;
+import android.view.inputmethod.InputMethodManager;
+
+import com.android.launcher3.ExtendedEditText;
+
+import java.util.List;
+
+/**
+ * Handles additional edit text functionality to better support folder name suggestion.
+ * First, makes suggestion to the InputMethodManager via {@link #displayCompletions(List)}
+ * Second, intercepts whether user accepted the suggestion or manually edited their
+ * folder names.
+ */
+public class FolderNameEditText extends ExtendedEditText {
+ private static final String TAG = "FolderNameEditText";
+ private static final boolean DEBUG = false;
+
+ private boolean mEnteredCompose = false;
+
+ public FolderNameEditText(Context context) {
+ super(context);
+ }
+
+ public FolderNameEditText(Context context, AttributeSet attrs) {
+ // ctor chaining breaks the touch handling
+ super(context, attrs);
+ }
+
+ public FolderNameEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ InputConnection con = super.onCreateInputConnection(outAttrs);
+ FolderNameEditTextInputConnection connectionWrapper =
+ new FolderNameEditTextInputConnection(con, true);
+ return connectionWrapper;
+ }
+
+ public void displayCompletions(List<String> suggestList) {
+ int cnt = Math.min(suggestList.size(), FolderNameProvider.SUGGEST_MAX);
+ CompletionInfo[] cInfo = new CompletionInfo[cnt];
+ for (int i = 0; i < cnt; i++) {
+ cInfo[i] = new CompletionInfo(i, i, suggestList.get(i));
+ }
+ post(() -> getContext().getSystemService(InputMethodManager.class)
+ .displayCompletions(this, cInfo));
+ }
+
+ /**
+ * Within 's', the 'count' characters beginning at 'start' have just replaced
+ * old text 'before'
+ */
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ String reason = "unknown";
+ if (start == 0 && count == 0 && before > 0) {
+ reason = "suggestion was rejected";
+ mEnteredCompose = true;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "onTextChanged " + start + "," + before + "," + count
+ + ", " + reason);
+ }
+ }
+
+ @Override
+ public void onCommitCompletion(CompletionInfo text) {
+ setText(text.getText());
+ setSelection(text.getText().length());
+ mEnteredCompose = false;
+ }
+
+ protected void setEnteredCompose(boolean value) {
+ mEnteredCompose = value;
+ }
+
+ protected boolean isEnteredCompose() {
+ if (DEBUG) {
+ Log.d(TAG, "isEnteredCompose " + mEnteredCompose);
+ }
+ return mEnteredCompose;
+ }
+
+ private class FolderNameEditTextInputConnection extends InputConnectionWrapper {
+
+ FolderNameEditTextInputConnection(InputConnection target, boolean mutable) {
+ super(target, mutable);
+ }
+
+ @Override
+ public boolean setComposingText(CharSequence cs, int newCursorPos) {
+ mEnteredCompose = true;
+ return super.setComposingText(cs, newCursorPos);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index 782b0e2..9ea292c 100644
--- a/src/com/android/launcher3/folder/FolderNameProvider.java
+++ b/src/com/android/launcher3/folder/FolderNameProvider.java
@@ -109,11 +109,14 @@
if (contains(candidatesOut, candidate)) {
return;
}
+
for (int i = 0; i < candidate.length(); i++) {
if (TextUtils.isEmpty(candidatesOut[i])) {
candidatesOut[i] = candidate;
+ return;
}
}
+ candidatesOut[candidate.length() - 1] = candidate;
}
private boolean contains(CharSequence[] list, CharSequence key) {
diff --git a/src/com/android/launcher3/views/BottomUserEducationView.java b/src/com/android/launcher3/views/BottomUserEducationView.java
deleted file mode 100644
index bdc69af..0000000
--- a/src/com/android/launcher3/views/BottomUserEducationView.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.views;
-
-import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
-
-import android.animation.PropertyValuesHolder;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.TouchDelegate;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-
-import com.android.launcher3.Insettable;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-
-public class BottomUserEducationView extends AbstractSlideInView implements Insettable {
-
- private static final String KEY_SHOWED_BOTTOM_USER_EDUCATION = "showed_bottom_user_education";
-
- private static final int DEFAULT_CLOSE_DURATION = 200;
-
- private final Rect mInsets = new Rect();
-
- private View mCloseButton;
-
- public BottomUserEducationView(Context context, AttributeSet attr) {
- this(context, attr, 0);
- }
-
- public BottomUserEducationView(Context context, AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mContent = this;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mCloseButton = findViewById(R.id.close_bottom_user_tip);
- mCloseButton.setOnClickListener(view -> handleClose(true));
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- setTranslationShift(mTranslationShift);
- expandTouchAreaOfCloseButton();
- }
-
- @Override
- public void logActionCommand(int command) {
- // Since this is on-boarding popup, it is not a user controlled action.
- }
-
- @Override
- public int getLogContainerType() {
- return ContainerType.TIP;
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_ON_BOARD_POPUP) != 0;
- }
-
- @Override
- public void setInsets(Rect insets) {
- // Extend behind left, right, and bottom insets.
- int leftInset = insets.left - mInsets.left;
- int rightInset = insets.right - mInsets.right;
- int bottomInset = insets.bottom - mInsets.bottom;
- mInsets.set(insets);
- setPadding(getPaddingLeft() + leftInset, getPaddingTop(),
- getPaddingRight() + rightInset, getPaddingBottom() + bottomInset);
- }
-
- @Override
- protected void handleClose(boolean animate) {
- handleClose(animate, DEFAULT_CLOSE_DURATION);
- if (animate) {
- // We animate only when the user is visible, which is a proxy for an explicit
- // close action.
- mLauncher.getSharedPrefs().edit()
- .putBoolean(KEY_SHOWED_BOTTOM_USER_EDUCATION, true).apply();
- sendCustomAccessibilityEvent(
- BottomUserEducationView.this,
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
- getContext().getString(R.string.bottom_work_tab_user_education_closed));
- }
- }
-
- private void open(boolean animate) {
- if (mIsOpen || mOpenCloseAnimator.isRunning()) {
- return;
- }
- mIsOpen = true;
- if (animate) {
- mOpenCloseAnimator.setValues(
- PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
- mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mOpenCloseAnimator.start();
- } else {
- setTranslationShift(TRANSLATION_SHIFT_OPENED);
- }
- }
-
- public static void showIfNeeded(Launcher launcher) {
- if (launcher.getSharedPrefs().getBoolean(KEY_SHOWED_BOTTOM_USER_EDUCATION, false)) {
- return;
- }
-
- LayoutInflater layoutInflater = LayoutInflater.from(launcher);
- BottomUserEducationView bottomUserEducationView =
- (BottomUserEducationView) layoutInflater.inflate(
- R.layout.work_tab_bottom_user_education_view, launcher.getDragLayer(),
- false);
- launcher.getDragLayer().addView(bottomUserEducationView);
- bottomUserEducationView.open(true);
- }
-
- private void expandTouchAreaOfCloseButton() {
- Rect hitRect = new Rect();
- mCloseButton.getHitRect(hitRect);
- hitRect.left -= mCloseButton.getWidth();
- hitRect.top -= mCloseButton.getHeight();
- hitRect.right += mCloseButton.getWidth();
- hitRect.bottom += mCloseButton.getHeight();
- View parent = (View) mCloseButton.getParent();
- parent.setTouchDelegate(new TouchDelegate(hitRect, mCloseButton));
- }
-}
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
new file mode 100644
index 0000000..c3186f6
--- /dev/null
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2020 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.launcher3.views;
+
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsPagedView;
+import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+
+/**
+ * On boarding flow for users right after setting up work profile
+ */
+public class WorkEduView extends AbstractSlideInView implements Insettable {
+
+ private static final int DEFAULT_CLOSE_DURATION = 200;
+ private static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
+
+ private static final int WORK_EDU_NOT_STARTED = 0;
+ private static final int WORK_EDU_PERSONAL_APPS = 1;
+ private static final int WORK_EDU_WORK_APPS = 2;
+
+ private static LauncherStateManager.StateListener sStateListener;
+
+ private Rect mInsets = new Rect();
+ private View mViewWrapper;
+ private Button mProceedButton;
+ private TextView mContentText;
+ private AllAppsPagedView mAllAppsPagedView;
+ private int mNextWorkEduStep = WORK_EDU_PERSONAL_APPS;
+
+
+ public WorkEduView(Context context, AttributeSet attr) {
+ this(context, attr, 0);
+ }
+
+ public WorkEduView(Context context, AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mContent = this;
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ mLauncher.getSharedPrefs().edit().putInt(KEY_WORK_EDU_STEP, mNextWorkEduStep).apply();
+ handleClose(true, DEFAULT_CLOSE_DURATION);
+ }
+
+ @Override
+ public void logActionCommand(int command) {
+ // Since this is on-boarding popup, it is not a user controlled action.
+ }
+
+ @Override
+ public int getLogContainerType() {
+ return LauncherLogProto.ContainerType.TIP;
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_ON_BOARD_POPUP) != 0;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mViewWrapper = findViewById(R.id.view_wrapper);
+ mProceedButton = findViewById(R.id.proceed);
+ mContentText = findViewById(R.id.content_text);
+
+ if (mLauncher.getAppsView().getContentView() instanceof AllAppsPagedView) {
+ mAllAppsPagedView = (AllAppsPagedView) mLauncher.getAppsView().getContentView();
+ }
+
+ mProceedButton.setOnClickListener(view -> {
+ if (mAllAppsPagedView != null) {
+ mAllAppsPagedView.snapToPage(AllAppsContainerView.AdapterHolder.WORK);
+ }
+ goToWorkTab(true);
+ });
+ }
+
+ private void goToWorkTab(boolean animate) {
+ mProceedButton.setText(R.string.work_profile_edu_accept);
+ if (animate) {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(mContentText, ALPHA, 0);
+ animator.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ mContentText.setText(mLauncher.getString(R.string.work_profile_edu_work_apps));
+ ObjectAnimator.ofFloat(mContentText, ALPHA, 1).start();
+ }
+ });
+ animator.start();
+ } else {
+ mContentText.setText(mLauncher.getString(R.string.work_profile_edu_work_apps));
+ }
+ mNextWorkEduStep = WORK_EDU_WORK_APPS;
+ mProceedButton.setOnClickListener(v -> handleClose(true));
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ int leftInset = insets.left - mInsets.left;
+ int rightInset = insets.right - mInsets.right;
+ int bottomInset = insets.bottom - mInsets.bottom;
+ mInsets.set(insets);
+ setPadding(leftInset, getPaddingTop(), rightInset, 0);
+ mViewWrapper.setPaddingRelative(mViewWrapper.getPaddingStart(),
+ mViewWrapper.getPaddingTop(), mViewWrapper.getPaddingEnd(), bottomInset);
+ }
+
+ private void show() {
+ mLauncher.getDragLayer().addView(this);
+ animateOpen();
+ }
+
+ private void goToFirstPage() {
+ if (mAllAppsPagedView != null) {
+ mAllAppsPagedView.snapToPageImmediately(AllAppsContainerView.AdapterHolder.MAIN);
+ }
+ }
+
+ private void animateOpen() {
+ if (mIsOpen || mOpenCloseAnimator.isRunning()) {
+ return;
+ }
+ mIsOpen = true;
+ mOpenCloseAnimator.setValues(
+ PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
+ mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ mOpenCloseAnimator.start();
+ }
+
+ /**
+ * Checks if user has not seen onboarding UI yet and shows it when user navigates to all apps
+ */
+ public static LauncherStateManager.StateListener showEduFlowIfNeeded(Launcher launcher,
+ @Nullable LauncherStateManager.StateListener oldListener) {
+ if (oldListener != null) {
+ launcher.getStateManager().removeStateListener(oldListener);
+ }
+ if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
+ != WORK_EDU_NOT_STARTED) {
+ return null;
+ }
+
+ LauncherStateManager.StateListener listener = new LauncherStateManager.StateListener() {
+ @Override
+ public void onStateTransitionStart(LauncherState toState) {
+
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ if (finalState != LauncherState.ALL_APPS) return;
+ LayoutInflater layoutInflater = LayoutInflater.from(launcher);
+ WorkEduView v = (WorkEduView) layoutInflater.inflate(
+ R.layout.work_profile_edu, launcher.getDragLayer(),
+ false);
+ v.show();
+ v.goToFirstPage();
+ launcher.getStateManager().removeStateListener(this);
+ }
+ };
+ launcher.getStateManager().addStateListener(listener);
+ return listener;
+ }
+
+ /**
+ * Shows work apps edu if user had dismissed full edu flow
+ */
+ public static void showWorkEduIfNeeded(Launcher launcher) {
+ if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
+ != WORK_EDU_PERSONAL_APPS) {
+ return;
+ }
+ LayoutInflater layoutInflater = LayoutInflater.from(launcher);
+ WorkEduView v = (WorkEduView) layoutInflater.inflate(
+ R.layout.work_profile_edu, launcher.getDragLayer(), false);
+ v.show();
+ v.goToWorkTab(false);
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 61f5150..9b4023e 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -59,6 +59,7 @@
@Before
public void setUp() throws Exception {
+ mLauncherPid = 0;
super.setUp();
initialize(this);
mLauncherPid = mLauncher.getPid();
@@ -66,7 +67,9 @@
@After
public void teardown() {
- assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid());
+ if (mLauncherPid != 0) {
+ assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid());
+ }
}
public static void initialize(AbstractLauncherUiTest test) throws Exception {
@@ -120,7 +123,7 @@
mDevice.pressMenu();
mDevice.waitForIdle();
mLauncher.getOptionsPopupMenu().getMenuItem("Home settings")
- .launch(mDevice.getLauncherPackageName());
+ .launch(mDevice.getLauncherPackageName());
}
@Test
diff --git a/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java b/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java
index 831685a..c553b9b 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureInvestigator.java
@@ -29,6 +29,11 @@
}
static int getBugForFailure(CharSequence exception, String testsStartTime) {
+ if ("com.google.android.setupwizard".equals(
+ UiDevice.getInstance(getInstrumentation()).getLauncherPackageName())) {
+ return 145935261;
+ }
+
final String logSinceTestsStart;
try {
logSinceTestsStart =
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 0a3462f..5555eab 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -68,6 +68,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
@@ -93,10 +94,13 @@
private static final String TAG = "Tapl";
private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
private static final int GESTURE_STEP_MS = 16;
+ private static final SimpleDateFormat DATE_TIME_FORMAT =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static long START_TIME = System.currentTimeMillis();
static final Pattern EVENT_LOG_ENTRY = Pattern.compile(
- "[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\\.[0-9][0-9][0-9]"
+ "(?<time>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] "
+ + "[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\\.[0-9][0-9][0-9])"
+ ".*" + TestProtocol.TAPL_EVENTS_TAG + ": (?<event>.*)");
private static final Pattern EVENT_TOUCH_DOWN = getTouchEventPattern("ACTION_DOWN");
@@ -167,7 +171,7 @@
// Not null when we are collecting expected events to compare with actual ones.
private List<Pattern> mExpectedEvents;
- private String mTimeBeforeFirstLogEvent;
+ private Date mStartRecordingTime;
private boolean mCheckEventsForSuccessfulGestures = false;
private static Pattern getTouchEventPattern(String action) {
@@ -1187,32 +1191,38 @@
private List<String> getEvents() {
final ArrayList<String> events = new ArrayList<>();
try {
- final String logcatTimeParameter =
- mTimeBeforeFirstLogEvent != null ? " -t " + mTimeBeforeFirstLogEvent : "";
final String logcatEvents = mDevice.executeShellCommand(
- "logcat -d --pid=" + getPid() + logcatTimeParameter
+ "logcat -d -v year --pid=" + getPid() + " -t "
+ + DATE_TIME_FORMAT.format(mStartRecordingTime).replaceAll(" ", "")
+ " -s " + TestProtocol.TAPL_EVENTS_TAG);
final Matcher matcher = EVENT_LOG_ENTRY.matcher(logcatEvents);
while (matcher.find()) {
+ // Skip events before recording start time.
+ if (DATE_TIME_FORMAT.parse(matcher.group("time"))
+ .compareTo(mStartRecordingTime) < 0) {
+ continue;
+ }
+
events.add(matcher.group("event"));
}
return events;
} catch (IOException e) {
throw new RuntimeException(e);
+ } catch (ParseException e) {
+ throw new AssertionError(e);
}
}
private void startRecordingEvents() {
Assert.assertTrue("Already recording events", mExpectedEvents == null);
mExpectedEvents = new ArrayList<>();
- mTimeBeforeFirstLogEvent = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
- .format(new Date())
- .replaceAll(" ", "");
- log("startRecordingEvents: " + mTimeBeforeFirstLogEvent);
+ mStartRecordingTime = new Date();
+ log("startRecordingEvents: " + DATE_TIME_FORMAT.format(mStartRecordingTime));
}
private void stopRecordingEvents() {
mExpectedEvents = null;
+ mStartRecordingTime = null;
}
Closable eventsCheck() {