Merge "Remove debug logs for b/193125090" into sc-v2-dev
diff --git a/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml b/go/quickstep/res/layout/niu_actions_dialog.xml
similarity index 72%
rename from go/quickstep/res/layout/niu_actions_confirmation_dialog.xml
rename to go/quickstep/res/layout/niu_actions_dialog.xml
index 5dbcca5..6e944f8 100644
--- a/go/quickstep/res/layout/niu_actions_confirmation_dialog.xml
+++ b/go/quickstep/res/layout/niu_actions_dialog.xml
@@ -16,7 +16,8 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/niu_actions_confirmation_dialog_layout"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/niu_actions_dialog_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
@@ -41,29 +42,37 @@
<TextView
style="@style/ModalDialogTitle"
- android:id="@+id/niu_actions_confirmation_header"
- android:text="@string/niu_actions_confirmation_title"/>
+ android:id="@+id/niu_actions_dialog_header"/>
<Space
android:layout_width="0dp"
android:layout_height="@dimen/modal_dialog_vertical_spacer"/>
- <ScrollView
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
- android:layout_height="@dimen/confirmation_dialog_text_height">
+ android:layout_height="wrap_content">
- <TextView
- style="@style/ModalDialogText"
- android:id="@+id/niu_actions_confirmation_description"
- android:text="@string/niu_actions_confirmation_text"/>
- </ScrollView>
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constrainedHeight="true"
+ app:layout_constraintHeight_max="@dimen/modal_dialog_text_height">
+
+ <TextView
+ style="@style/ModalDialogText"
+ android:id="@+id/niu_actions_dialog_description"/>
+ </ScrollView>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
<Space
android:layout_width="0dp"
android:layout_height="@dimen/modal_dialog_vertical_spacer"/>
<LinearLayout
- android:id="@+id/niu_actions_confirmation_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
@@ -75,12 +84,12 @@
<Button
style="@style/ModalDialogButton"
- android:id="@+id/niu_actions_confirmation_reject"
+ android:id="@+id/niu_actions_dialog_button_1"
android:text="@string/dialog_cancel"/>
<Button
style="@style/ModalDialogButton"
- android:id="@+id/niu_actions_confirmation_accept"
+ android:id="@+id/niu_actions_dialog_button_2"
android:text="@string/dialog_acknowledge"/>
</LinearLayout>
diff --git a/go/quickstep/res/values-land/dimens.xml b/go/quickstep/res/values-land/dimens.xml
index 5097016..6b5d0b4 100644
--- a/go/quickstep/res/values-land/dimens.xml
+++ b/go/quickstep/res/values-land/dimens.xml
@@ -18,5 +18,5 @@
<resources>
<!-- Modal Dialogs -->
<dimen name="modal_dialog_width">360dp</dimen>
- <dimen name="confirmation_dialog_text_height">168dp</dimen>
+ <dimen name="modal_dialog_text_height">168dp</dimen>
</resources>
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
index c14df50..84d7fe5 100644
--- a/go/quickstep/res/values/dimens.xml
+++ b/go/quickstep/res/values/dimens.xml
@@ -35,7 +35,7 @@
<dimen name="modal_dialog_padding_bottom">8dp</dimen>
<dimen name="modal_dialog_vertical_spacer">12dp</dimen>
<dimen name="modal_dialog_corner_radius">8dp</dimen>
- <dimen name="confirmation_dialog_text_height">216dp</dimen>
+ <dimen name="modal_dialog_text_height">216dp</dimen>
<!-- Tooltip -->
<dimen name="tooltip_corner_radius">8dp</dimen>
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index fc07162..91cab3c 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -21,6 +21,8 @@
import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL;
import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.assist.AssistContent;
@@ -32,6 +34,7 @@
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.os.UserManager;
@@ -41,7 +44,9 @@
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
+import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BaseActivity;
@@ -55,6 +60,8 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import java.lang.annotation.Retention;
+
/**
* Go-specific extension of the factory class that adds an overlay to TaskView
*/
@@ -69,11 +76,21 @@
public static final int ERROR_PERMISSIONS_STRUCTURE = 1;
public static final int ERROR_PERMISSIONS_SCREENSHOT = 2;
private static final String NIU_ACTIONS_CONFIRMED = "launcher_go.niu_actions_confirmed";
+ private static final String ASSIST_SETTINGS_ARGS_BUNDLE = ":settings:show_fragment_args";
+ private static final String ASSIST_SETTINGS_ARGS_KEY = ":settings:fragment_args_key";
+ private static final String ASSIST_SETTINGS_PREFERENCE_KEY = "default_assist";
private static final String TAG = "TaskOverlayFactoryGo";
public static final String LISTEN_TOOL_TIP_SEEN = "launcher.go_listen_tip_seen";
public static final String TRANSLATE_TOOL_TIP_SEEN = "launcher.go_translate_tip_seen";
+ @Retention(SOURCE)
+ @IntDef({PRIVACY_CONFIRMATION, ASSISTANT_NOT_SELECTED, ASSISTANT_NOT_SUPPORTED})
+ private @interface DialogType{}
+ private static final int PRIVACY_CONFIRMATION = 0;
+ private static final int ASSISTANT_NOT_SELECTED = 1;
+ private static final int ASSISTANT_NOT_SUPPORTED = 2;
+
private AssistContentRequester mContentRequester;
public TaskOverlayFactoryGo(Context context) {
@@ -99,8 +116,7 @@
private boolean mAssistScreenshotPermitted;
private AssistContentRequester mFactoryContentRequester;
private SharedPreferences mSharedPreferences;
- private String mPreviousAction;
- private AlertDialog mConfirmationDialog;
+ private OverlayDialogGo mDialog;
private TaskOverlayGo(TaskThumbnailView taskThumbnailView,
AssistContentRequester assistContentRequester) {
@@ -115,15 +131,14 @@
@Override
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix,
boolean rotated) {
- if (mConfirmationDialog != null && mConfirmationDialog.isShowing()) {
+ if (mDialog != null && mDialog.isShowing()) {
// Redraw the dialog in case the layout changed
- mConfirmationDialog.dismiss();
- showConfirmationDialog();
+ mDialog.dismiss();
+ showDialog(mDialog.getAction(), mDialog.getType());
}
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
- checkSettings();
- if (thumbnail == null || TextUtils.isEmpty(mNIUPackageName)) {
+ if (thumbnail == null) {
return;
}
@@ -135,8 +150,10 @@
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
mTaskPackageName = task.key.getPackageName();
mSharedPreferences = Utilities.getPrefs(mApplicationContext);
+ checkSettings();
- if (!mAssistStructurePermitted || !mAssistScreenshotPermitted) {
+ if (!mAssistStructurePermitted || !mAssistScreenshotPermitted
+ || TextUtils.isEmpty(mNIUPackageName)) {
return;
}
@@ -179,9 +196,13 @@
* Creates and sends an Intent corresponding to the button that was clicked
*/
private void sendNIUIntent(String actionType) {
+ if (TextUtils.isEmpty(mNIUPackageName)) {
+ showDialog(actionType, ASSISTANT_NOT_SELECTED);
+ return;
+ }
+
if (!mSharedPreferences.getBoolean(NIU_ACTIONS_CONFIRMED, false)) {
- mPreviousAction = actionType;
- showConfirmationDialog();
+ showDialog(actionType, PRIVACY_CONFIRMATION);
return;
}
@@ -199,6 +220,7 @@
mApplicationContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "No activity found to receive permission error intent");
+ showDialog(actionType, ASSISTANT_NOT_SUPPORTED);
}
}
}
@@ -273,33 +295,86 @@
mImageApi = imageActionsApi;
}
- private void showConfirmationDialog() {
+ // TODO (b/192406446): Test that these dialogs are shown at the appropriate times
+ private void showDialog(String action, @DialogType int type) {
+ switch (type) {
+ case PRIVACY_CONFIRMATION:
+ showDialog(action, PRIVACY_CONFIRMATION,
+ R.string.niu_actions_confirmation_title,
+ R.string.niu_actions_confirmation_text, R.string.dialog_cancel,
+ this::onDialogClickCancel, R.string.dialog_acknowledge,
+ this::onNiuActionsConfirmationAccept);
+ break;
+ case ASSISTANT_NOT_SELECTED:
+ showDialog(action, ASSISTANT_NOT_SELECTED,
+ R.string.assistant_not_selected_title,
+ R.string.assistant_not_selected_text, R.string.dialog_cancel,
+ this::onDialogClickCancel, R.string.dialog_settings,
+ this::onDialogClickSettings);
+ break;
+ case ASSISTANT_NOT_SUPPORTED:
+ showDialog(action, ASSISTANT_NOT_SUPPORTED,
+ R.string.assistant_not_supported_title,
+ R.string.assistant_not_supported_text, R.string.dialog_cancel,
+ this::onDialogClickCancel, R.string.dialog_settings,
+ this::onDialogClickSettings);
+ break;
+ default:
+ Log.e(TAG, "Unexpected dialog type");
+ }
+ }
+
+ private void showDialog(String action, @DialogType int type, int titleTextID,
+ int bodyTextID, int button1TextID,
+ View.OnClickListener button1Callback, int button2TextID,
+ View.OnClickListener button2Callback) {
BaseDraggingActivity activity = BaseActivity.fromContext(getActionsView().getContext());
LayoutInflater inflater = LayoutInflater.from(activity);
- View view = inflater.inflate(R.layout.niu_actions_confirmation_dialog, /* root */ null);
+ View view = inflater.inflate(R.layout.niu_actions_dialog, /* root */ null);
- Button acceptButton = view.findViewById(R.id.niu_actions_confirmation_accept);
- acceptButton.setOnClickListener(this::onNiuActionsConfirmationAccept);
+ TextView dialogTitle = view.findViewById(R.id.niu_actions_dialog_header);
+ dialogTitle.setText(titleTextID);
- Button rejectButton = view.findViewById(R.id.niu_actions_confirmation_reject);
- rejectButton.setOnClickListener(this::onNiuActionsConfirmationReject);
+ TextView dialogBody = view.findViewById(R.id.niu_actions_dialog_description);
+ dialogBody.setText(bodyTextID);
- mConfirmationDialog = new AlertDialog.Builder(activity)
- .setView(view)
- .create();
- mConfirmationDialog.getWindow()
- .setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- mConfirmationDialog.show();
+ Button button1 = view.findViewById(R.id.niu_actions_dialog_button_1);
+ button1.setText(button1TextID);
+ button1.setOnClickListener(button1Callback);
+
+ Button button2 = view.findViewById(R.id.niu_actions_dialog_button_2);
+ button2.setText(button2TextID);
+ button2.setOnClickListener(button2Callback);
+
+ mDialog = new OverlayDialogGo(activity, type, action);
+ mDialog.setView(view);
+ mDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ mDialog.show();
}
private void onNiuActionsConfirmationAccept(View v) {
- mConfirmationDialog.dismiss();
+ mDialog.dismiss();
mSharedPreferences.edit().putBoolean(NIU_ACTIONS_CONFIRMED, true).apply();
- sendNIUIntent(mPreviousAction);
+ sendNIUIntent(mDialog.getAction());
}
- private void onNiuActionsConfirmationReject(View v) {
- mConfirmationDialog.cancel();
+ private void onDialogClickCancel(View v) {
+ mDialog.cancel();
+ }
+
+ private void onDialogClickSettings(View v) {
+ mDialog.dismiss();
+
+ Bundle fragmentArgs = new Bundle();
+ fragmentArgs.putString(ASSIST_SETTINGS_ARGS_KEY, ASSIST_SETTINGS_PREFERENCE_KEY);
+ Intent intent = new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ .putExtra(ASSIST_SETTINGS_ARGS_BUNDLE, fragmentArgs);
+ try {
+ mApplicationContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "No activity found to receive assistant settings intent");
+ }
}
/**
@@ -317,6 +392,24 @@
}
}
+ private static final class OverlayDialogGo extends AlertDialog {
+ private final String mAction;
+ private final @DialogType int mType;
+
+ OverlayDialogGo(Context context, @DialogType int type, String action) {
+ super(context);
+ mType = type;
+ mAction = action;
+ }
+
+ public String getAction() {
+ return mAction;
+ }
+ public @DialogType int getType() {
+ return mType;
+ }
+ }
+
/**
* Callbacks the Ui can generate. This is the only way for a Ui to call methods on the
* controller.
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index 249699b..c57b75a 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -62,8 +62,7 @@
android:text="@string/add_item_request_drag_hint"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"
- android:alpha="0.7"
- android:importantForAccessibility="no"/>
+ android:alpha="0.7"/>
<ScrollView
android:id="@+id/widget_preview_scroll_view"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ddd838d..d1774e5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -63,6 +63,9 @@
<string name="add_item_request_drag_hint">Touch & hold the widget to move it around the Home screen</string>
<!-- Button label to automatically add a widget to home screen [CHAR_LIMIT=50] -->
<string name="add_to_home_screen">Add to Home screen</string>
+ <!-- Accessibility spoken message announced when a widget gets added to the home screen using a
+ button in a dialog. [CHAR_LIMIT=none] -->
+ <string name="added_to_home_screen_accessibility_text"><xliff:g id="widget_name" example="Calendar month view">%1$s</xliff:g> widget added to home screen</string>
<!-- Label for showing the number of widgets an app has in the full widgets picker.
[CHAR_LIMIT=25] -->
<plurals name="widgets_count">
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index df97bfb..905a701 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -27,10 +27,12 @@
import android.annotation.TargetApi;
import android.app.ActivityOptions;
import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Intent;
import android.content.pm.LauncherApps.PinItemRequest;
+import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Point;
@@ -39,12 +41,15 @@
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;
import com.android.launcher3.BaseActivity;
@@ -92,6 +97,7 @@
private InvariantDeviceProfile mIdp;
private BaseDragLayer<AddItemActivity> mDragLayer;
private AddItemWidgetsBottomSheet mSlideInView;
+ private AccessibilityManager mAccessibilityManager;
private WidgetCell mWidgetCell;
@@ -127,6 +133,8 @@
mDragLayer = findViewById(R.id.add_item_drag_layer);
mDragLayer.recreateControllers();
mWidgetCell = findViewById(R.id.widget_cell);
+ mAccessibilityManager =
+ getApplicationContext().getSystemService(AccessibilityManager.class);
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
setupShortcut();
@@ -291,17 +299,25 @@
*/
public void onPlaceAutomaticallyClick(View v) {
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
- ItemInstallQueue.INSTANCE.get(this).queueItem(mRequest.getShortcutInfo());
+ ShortcutInfo shortcutInfo = mRequest.getShortcutInfo();
+ ItemInstallQueue.INSTANCE.get(this).queueItem(shortcutInfo);
logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY);
mRequest.accept();
+ CharSequence label = shortcutInfo.getLongLabel();
+ if (TextUtils.isEmpty(label)) {
+ label = shortcutInfo.getShortLabel();
+ }
+ sendWidgetAddedToScreenAccessibilityEvent(label.toString());
mSlideInView.close(/* animate= */ true);
return;
}
mPendingBindWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ AppWidgetProviderInfo widgetProviderInfo = mRequest.getAppWidgetProviderInfo(this);
boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
- mPendingBindWidgetId, mRequest.getAppWidgetProviderInfo(this), mWidgetOptions);
+ mPendingBindWidgetId, widgetProviderInfo, mWidgetOptions);
if (success) {
+ sendWidgetAddedToScreenAccessibilityEvent(widgetProviderInfo.label);
acceptWidget(mPendingBindWidgetId);
return;
}
@@ -375,6 +391,17 @@
isSheetDark ? SystemUiController.FLAG_DARK_NAV : SystemUiController.FLAG_LIGHT_NAV);
}
+ private void sendWidgetAddedToScreenAccessibilityEvent(String widgetName) {
+ if (mAccessibilityManager.isEnabled()) {
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT);
+ event.setContentDescription(
+ getApplicationContext().getResources().getString(
+ R.string.added_to_home_screen_accessibility_text, widgetName));
+ mAccessibilityManager.sendAccessibilityEvent(event);
+ }
+ }
+
private void logCommand(StatsLogManager.EventEnum command) {
getStatsLogManager().logger()
.withItemInfo((ItemInfo) mWidgetCell.getWidgetView().getTag())
diff --git a/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java b/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java
index 00b1cdd..7a5cf2c 100644
--- a/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java
+++ b/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java
@@ -62,12 +62,17 @@
ParcelFileDescriptor output =
automation.executeShellCommand("screenrecord " + outputFile);
String screenRecordPid = device.executeShellCommand("pidof screenrecord");
+ boolean success = false;
try {
base.evaluate();
+ success = true;
} finally {
device.executeShellCommand("kill -INT " + screenRecordPid);
Log.e(TAG, "Screenrecord captured at: " + outputFile);
output.close();
+ if (success) {
+ automation.executeShellCommand("rm " + outputFile);
+ }
}
}
};
@@ -78,5 +83,6 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
- public @interface ScreenRecord { }
+ public @interface ScreenRecord {
+ }
}