diff options
Diffstat (limited to 'src/com')
21 files changed, 169 insertions, 67 deletions
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 410d590ad..08cd955a5 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -39,7 +39,7 @@ public abstract class BaseActivity extends Activity { public final UserEventDispatcher getUserEventDispatcher() { if (mUserEventDispatcher == null) { mUserEventDispatcher = UserEventDispatcher.newInstance(this, - isInMultiWindowModeCompat()); + mDeviceProfile.isLandscape, isInMultiWindowModeCompat()); } return mUserEventDispatcher; } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index cb40d3d5e..94c7e07fb 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -453,7 +453,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { final int scrollX = getScrollX(); final int scrollY = getScrollY(); canvas.translate(scrollX, scrollY); - mBadgeRenderer.draw(canvas, mIconPalette, mBadgeInfo, mTempIconBounds, mBadgeScale, + mBadgeRenderer.draw(canvas, mBadgeInfo, mTempIconBounds, mBadgeScale, mTempSpaceForBadgeOffset); canvas.translate(-scrollX, -scrollY); } @@ -660,14 +660,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver { } /** - * Returns true if the view can show custom shortcuts. - */ - public boolean hasDeepShortcuts() { - return !mLauncher.getPopupDataProvider().getShortcutIdsForItem((ItemInfo) getTag()) - .isEmpty(); - } - - /** * Interface to be implemented by the grand parent to allow click shadow effect. */ public interface BubbleTextShadowHandler { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index eef578d8f..2de10030d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -4061,8 +4061,8 @@ public class Launcher extends BaseActivity shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.custom_actions), KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON)); } - if (currentFocus instanceof BubbleTextView && - ((BubbleTextView) currentFocus).hasDeepShortcuts()) { + if (currentFocus.getTag() instanceof ItemInfo + && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) { shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.action_deep_shortcut), KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON)); } diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java index 61b8a7aa8..13cc7ba07 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java @@ -100,7 +100,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView if (Utilities.isAtLeastO()) { try { Method asyncMethod = AppWidgetHostView.class - .getMethod("setAsyncExecutor", Executor.class); + .getMethod("setExecutor", Executor.class); asyncMethod.invoke(this, Utilities.THREAD_POOL_EXECUTOR); } catch (Exception e) { Log.e(TAG, "Unable to set async executor", e); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 258676423..b2f628417 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1783,17 +1783,15 @@ public class LauncherModel extends BroadcastReceiver } private void loadDeepShortcuts() { - if (!mModelLoaded) { - sBgDataModel.deepShortcutMap.clear(); - DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext); - mHasShortcutHostPermission = shortcutManager.hasHostPermission(); - if (mHasShortcutHostPermission) { - for (UserHandle user : mUserManager.getUserProfiles()) { - if (mUserManager.isUserUnlocked(user)) { - List<ShortcutInfoCompat> shortcuts = - shortcutManager.queryForAllShortcuts(user); - sBgDataModel.updateDeepShortcutMap(null, user, shortcuts); - } + sBgDataModel.deepShortcutMap.clear(); + DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext); + mHasShortcutHostPermission = shortcutManager.hasHostPermission(); + if (mHasShortcutHostPermission) { + for (UserHandle user : mUserManager.getUserProfiles()) { + if (mUserManager.isUserUnlocked(user)) { + List<ShortcutInfoCompat> shortcuts = + shortcutManager.queryForAllShortcuts(user); + sBgDataModel.updateDeepShortcutMap(null, user, shortcuts); } } } diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index d4e3171e5..3150d5b0e 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -755,7 +755,6 @@ public class LauncherProvider extends ContentProvider { } } case 2: - removeGhostWidgets(db); case 3: // data updated return; diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java index 7ae6b261d..0902b2029 100644 --- a/src/com/android/launcher3/SettingsActivity.java +++ b/src/com/android/launcher3/SettingsActivity.java @@ -34,6 +34,11 @@ import com.android.launcher3.graphics.IconShapeOverride; * Settings activity for Launcher. Currently implements the following setting: Allow rotation */ public class SettingsActivity extends Activity { + + private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging"; + // TODO: use Settings.Secure.NOTIFICATION_BADGING + private static final String NOTIFICATION_BADGING = "notification_badging"; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -50,6 +55,7 @@ public class SettingsActivity extends Activity { public static class LauncherSettingsFragment extends PreferenceFragment { private SystemDisplayRotationLockObserver mRotationLockObserver; + private IconBadgingObserver mIconBadgingObserver; @Override public void onCreate(Bundle savedInstanceState) { @@ -57,13 +63,14 @@ public class SettingsActivity extends Activity { getPreferenceManager().setSharedPreferencesName(LauncherFiles.SHARED_PREFERENCES_KEY); addPreferencesFromResource(R.xml.launcher_preferences); + ContentResolver resolver = getActivity().getContentResolver(); + // Setup allow rotation preference Preference rotationPref = findPreference(Utilities.ALLOW_ROTATION_PREFERENCE_KEY); if (getResources().getBoolean(R.bool.allow_rotation)) { // Launcher supports rotation by default. No need to show this setting. getPreferenceScreen().removePreference(rotationPref); } else { - ContentResolver resolver = getActivity().getContentResolver(); mRotationLockObserver = new SystemDisplayRotationLockObserver(rotationPref, resolver); // Register a content observer to listen for system setting changes while @@ -77,9 +84,18 @@ public class SettingsActivity extends Activity { rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity())); } + Preference iconBadgingPref = findPreference(ICON_BADGING_PREFERENCE_KEY); if (!BuildCompat.isAtLeastO()) { getPreferenceScreen().removePreference( findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY)); + getPreferenceScreen().removePreference(iconBadgingPref); + } else { + // Listen to system notification badge settings while this UI is active. + mIconBadgingObserver = new IconBadgingObserver(iconBadgingPref, resolver); + resolver.registerContentObserver( + Settings.Secure.getUriFor(NOTIFICATION_BADGING), + false, mIconBadgingObserver); + mIconBadgingObserver.onChange(true); } Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE); @@ -98,6 +114,10 @@ public class SettingsActivity extends Activity { getActivity().getContentResolver().unregisterContentObserver(mRotationLockObserver); mRotationLockObserver = null; } + if (mIconBadgingObserver != null) { + getActivity().getContentResolver().unregisterContentObserver(mIconBadgingObserver); + mIconBadgingObserver = null; + } super.onDestroy(); } } @@ -127,4 +147,29 @@ public class SettingsActivity extends Activity { ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc); } } + + /** + * Content observer which listens for system badging setting changes, + * and updates the launcher badging setting subtext accordingly. + */ + private static class IconBadgingObserver extends ContentObserver { + + private final Preference mBadgingPref; + private final ContentResolver mResolver; + + public IconBadgingObserver(Preference badgingPref, ContentResolver resolver) { + super(new Handler()); + mBadgingPref = badgingPref; + mResolver = resolver; + } + + @Override + public void onChange(boolean selfChange) { + boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1; + mBadgingPref.setSummary(enabled + ? R.string.icon_badging_desc_on + : R.string.icon_badging_desc_off); + } + } + } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 48a62d981..36f2880cb 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -75,6 +75,7 @@ import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.graphics.DragPreviewProvider; import com.android.launcher3.graphics.PreloadIconDrawable; import com.android.launcher3.popup.PopupContainerWithArrow; +import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; @@ -2257,6 +2258,8 @@ public class Workspace extends PagedView int previewSize = grid.folderIconSizePx; dragVisualizeOffset = new Point(- halfPadding, halfPadding - child.getPaddingTop()); dragRect = new Rect(0, child.getPaddingTop(), child.getWidth(), previewSize); + } else if (previewProvider instanceof ShortcutDragPreviewProvider) { + dragVisualizeOffset = new Point(- halfPadding, halfPadding); } // Clear the pressed state if necessary @@ -2269,7 +2272,7 @@ public class Workspace extends PagedView mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent(); } - if (child instanceof BubbleTextView) { + if (child instanceof BubbleTextView && !dragOptions.isAccessibleDrag) { PopupContainerWithArrow popupContainer = PopupContainerWithArrow .showForIcon((BubbleTextView) child); if (popupContainer != null) { @@ -2521,6 +2524,8 @@ public class Workspace extends PagedView } } + boolean droppedOnOriginalCell = false; + int snapScreen = -1; boolean resizeOnDrop = false; if (d.dragSource != this) { @@ -2572,9 +2577,9 @@ public class Workspace extends PagedView minSpanY = item.minSpanY; } - droppedOnOriginalCellDuringTransition = mIsSwitchingState - && item.screenId == screenId && item.container == container + droppedOnOriginalCell = item.screenId == screenId && item.container == container && item.cellX == mTargetCell[0] && item.cellY == mTargetCell[1]; + droppedOnOriginalCellDuringTransition = droppedOnOriginalCell && mIsSwitchingState; // When quickly moving an item, a user may accidentally rearrange their // workspace. So instead we move the icon back safely to its original position. @@ -2709,7 +2714,7 @@ public class Workspace extends PagedView } parent.onDropChild(cell); } - if (d.stateAnnouncer != null) { + if (d.stateAnnouncer != null && !droppedOnOriginalCell) { d.stateAnnouncer.completeAction(R.string.item_moved); } } diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index a476650c9..70e578163 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -37,6 +37,7 @@ import com.android.launcher3.Workspace; import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; +import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.util.Thunk; import java.util.ArrayList; @@ -104,8 +105,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme // If the request came from keyboard, do not add custom shortcuts as that is already // exposed as a direct shortcut - if (!fromKeyboard && host instanceof BubbleTextView - && ((BubbleTextView) host).hasDeepShortcuts()) { + if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) { info.addAction(mActions.get(DEEP_SHORTCUTS)); } diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java index b784fe7f8..816121995 100644 --- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java @@ -18,14 +18,15 @@ package com.android.launcher3.accessibility; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; +import com.android.launcher3.notification.NotificationMainView; import com.android.launcher3.shortcuts.DeepShortcutView; import java.util.ArrayList; @@ -36,14 +37,23 @@ import java.util.ArrayList; */ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDelegate { + private static final int DISMISS_NOTIFICATION = R.id.action_dismiss_notification; + public ShortcutMenuAccessibilityDelegate(Launcher launcher) { super(launcher); + mActions.put(DISMISS_NOTIFICATION, new AccessibilityAction(DISMISS_NOTIFICATION, + launcher.getText(R.string.action_dismiss_notification))); } @Override public void addSupportedActions(View host, AccessibilityNodeInfo info, boolean fromKeyboard) { if ((host.getParent() instanceof DeepShortcutView)) { info.addAction(mActions.get(ADD_TO_WORKSPACE)); + } else if (host instanceof NotificationMainView) { + NotificationMainView notificationView = (NotificationMainView) host; + if (notificationView.canChildBeDismissed(notificationView)) { + info.addAction(mActions.get(DISMISS_NOTIFICATION)); + } } } @@ -74,6 +84,14 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele onComplete.run(); } return true; + } else if (action == DISMISS_NOTIFICATION) { + if (!(host instanceof NotificationMainView)) { + return false; + } + NotificationMainView notificationView = (NotificationMainView) host; + notificationView.onChildDismissed(notificationView); + announceConfirmation(R.string.notification_dismissed); + return true; } return false; } diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java index ba1977af4..adde4a2fc 100644 --- a/src/com/android/launcher3/badge/BadgeRenderer.java +++ b/src/com/android/launcher3/badge/BadgeRenderer.java @@ -63,6 +63,7 @@ public class BadgeRenderer { private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); private final SparseArray<Bitmap> mBackgroundsWithShadow; + private final IconPalette mIconPalette; public BadgeRenderer(Context context, int iconSizePx) { mContext = context; @@ -82,24 +83,25 @@ public class BadgeRenderer { mTextHeight = tempTextHeight.height(); mBackgroundsWithShadow = new SparseArray<>(3); + + mIconPalette = IconPalette.fromDominantColor(context.getColor(R.color.badge_color)); } /** * Draw a circle in the top right corner of the given bounds, and draw * {@link BadgeInfo#getNotificationCount()} on top of the circle. - * @param palette The colors (based on the icon) to use for the badge. * @param badgeInfo Contains data to draw on the badge. Could be null if we are animating out. * @param iconBounds The bounds of the icon being badged. * @param badgeScale The progress of the animation, from 0 to 1. * @param spaceForOffset How much space is available to offset the badge up and to the right. */ - public void draw(Canvas canvas, IconPalette palette, @Nullable BadgeInfo badgeInfo, + public void draw(Canvas canvas, @Nullable BadgeInfo badgeInfo, Rect iconBounds, float badgeScale, Point spaceForOffset) { - mTextPaint.setColor(palette.textColor); + mTextPaint.setColor(mIconPalette.textColor); IconDrawer iconDrawer = badgeInfo != null && badgeInfo.isIconLarge() ? mLargeIconDrawer : mSmallIconDrawer; Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge( - mContext, palette.backgroundColor, mSize, iconDrawer.mPadding); + mContext, mIconPalette.backgroundColor, mSize, iconDrawer.mPadding); String notificationCount = badgeInfo == null ? "0" : String.valueOf(badgeInfo.getNotificationCount()); int numChars = notificationCount.length(); @@ -125,7 +127,7 @@ public class BadgeRenderer { canvas.translate(badgeCenterX + offsetX, badgeCenterY - offsetY); canvas.scale(badgeScale, badgeScale); // Prepare the background and shadow and possible stacking effect. - mBackgroundPaint.setColorFilter(palette.backgroundColorMatrixFilter); + mBackgroundPaint.setColorFilter(mIconPalette.backgroundColorMatrixFilter); int backgroundWithShadowSize = backgroundWithShadow.getHeight(); // Same as width. boolean shouldStack = !isDot && badgeInfo != null && badgeInfo.getNotificationKeys().size() > 1; @@ -147,7 +149,7 @@ public class BadgeRenderer { -backgroundWithShadowSize / 2, mBackgroundPaint); iconDrawer.drawIcon(icon, canvas); } else if (isDot) { - mBackgroundPaint.setColorFilter(palette.saturatedBackgroundColorMatrixFilter); + mBackgroundPaint.setColorFilter(mIconPalette.saturatedBackgroundColorMatrixFilter); canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2, -backgroundWithShadowSize / 2, mBackgroundPaint); } diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItemView.java b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java index 9bb3b100e..809d7249d 100644 --- a/src/com/android/launcher3/discovery/AppDiscoveryItemView.java +++ b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java @@ -82,7 +82,7 @@ public class AppDiscoveryItemView extends RelativeLayout { mPrice.setText(info.priceFormatted != null ? info.priceFormatted : ""); mReviewCount.setVisibility(SHOW_REVIEW_COUNT ? View.VISIBLE : View.GONE); if (info.rating >= 0) { - mRatingText.setText(new DecimalFormat("#.#").format(info.rating)); + mRatingText.setText(new DecimalFormat("#.0").format(info.rating)); mRatingView.setRating(info.rating); mRatingView.setVisibility(View.VISIBLE); String reviewCountFormatted = NumberFormat.getInstance().format(info.reviewCount); diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 25123fb1d..0b356b52c 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -75,7 +75,6 @@ import com.android.launcher3.badge.FolderBadgeInfo; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; -import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.util.Thunk; import java.util.ArrayList; @@ -886,7 +885,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { // If we are animating to the accepting state, animate the badge out. float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress()); mTempSpaceForBadgeOffset.set(getWidth() - mTempBounds.right, mTempBounds.top); - mBadgeRenderer.draw(canvas, IconPalette.FOLDER_ICON_PALETTE, mBadgeInfo, mTempBounds, + mBadgeRenderer.draw(canvas, mBadgeInfo, mTempBounds, badgeScale, mTempSpaceForBadgeOffset); } } diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java index 0182e53b9..60ca7b236 100644 --- a/src/com/android/launcher3/graphics/IconPalette.java +++ b/src/com/android/launcher3/graphics/IconPalette.java @@ -49,7 +49,7 @@ public class IconPalette { private IconPalette(int color) { dominantColor = color; - backgroundColor = getMutedColor(dominantColor); + backgroundColor = dominantColor; ColorMatrix backgroundColorMatrix = new ColorMatrix(); Themes.setColorScaleOnMatrix(backgroundColor, backgroundColorMatrix); backgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix); @@ -176,10 +176,6 @@ public class IconPalette { return ColorUtils.LABToColor(low, a, b); } - private static int getMutedColor(int color) { - return getMutedColor(color, 0.87f); - } - private static int getMutedColor(int color, float whiteScrimAlpha) { int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha)); return ColorUtils.compositeColors(whiteScrim, color); diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java index 07e99c693..258af1689 100644 --- a/src/com/android/launcher3/logging/UserEventDispatcher.java +++ b/src/com/android/launcher3/logging/UserEventDispatcher.java @@ -62,9 +62,11 @@ public class UserEventDispatcher { private static final boolean IS_VERBOSE = ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT); - public static UserEventDispatcher newInstance(Context context, boolean isInMultiWindowMode) { + public static UserEventDispatcher newInstance(Context context, boolean isInLandscapeMode, + boolean isInMultiWindowMode) { UserEventDispatcher ued = Utilities.getOverrideObject(UserEventDispatcher.class, context.getApplicationContext(), R.string.user_event_dispatcher_class); + ued.mIsInLandscapeMode = isInLandscapeMode; ued.mIsInMultiWindowMode = isInMultiWindowMode; return ued; } @@ -112,6 +114,7 @@ public class UserEventDispatcher { private long mElapsedSessionMillis; private long mActionDurationMillis; private boolean mIsInMultiWindowMode; + private boolean mIsInLandscapeMode; // Used for filling in predictedRank on {@link Target}s. private List<ComponentKey> mPredictedApps; @@ -296,6 +299,7 @@ public class UserEventDispatcher { } public void dispatchUserEvent(LauncherEvent ev, Intent intent) { + ev.isInLandscapeMode = mIsInLandscapeMode; ev.isInMultiWindowMode = mIsInMultiWindowMode; ev.elapsedContainerMillis = SystemClock.uptimeMillis() - mElapsedContainerMillis; ev.elapsedSessionMillis = SystemClock.uptimeMillis() - mElapsedSessionMillis; @@ -315,6 +319,7 @@ public class UserEventDispatcher { ev.elapsedContainerMillis, ev.elapsedSessionMillis, ev.actionDurationMillis); + log += "\n isInLandscapeMode " + ev.isInLandscapeMode; log += "\n isInMultiWindowMode " + ev.isInMultiWindowMode; Log.d(TAG, log); } diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java index 1eef743fe..051c0333d 100644 --- a/src/com/android/launcher3/notification/NotificationFooterLayout.java +++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java @@ -141,6 +141,7 @@ public class NotificationFooterLayout extends FrameLayout { icon.setBackground(info.getIconForBackground(getContext(), mBackgroundColor)); icon.setOnClickListener(info); icon.setTag(info); + icon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); mIconRow.addView(icon, 0, mIconLayoutParams); return icon; } diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index e5bf35a1e..997def277 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -21,6 +21,7 @@ import android.app.Notification; import android.content.Context; import android.graphics.Rect; import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -76,6 +77,10 @@ public class NotificationItemView extends PopupItemView implements LogContainerP mSwipeHelper.setDisableHardwareLayers(true); } + public NotificationMainView getMainView() { + return mMainView; + } + public int getHeightMinusFooter() { int footerHeight = mFooter.getParent() == null ? 0 : mFooter.getHeight(); return getHeight() - footerHeight; @@ -93,7 +98,7 @@ public class NotificationItemView extends PopupItemView implements LogContainerP if (mNotificationHeaderTextColor == Notification.COLOR_DEFAULT) { mNotificationHeaderTextColor = IconPalette.resolveContrastColor(getContext(), palette.dominantColor, - getResources().getColor(R.color.notification_header_background_color)); + getResources().getColor(R.color.popup_header_background_color)); } mHeaderCount.setTextColor(mNotificationHeaderTextColor); } @@ -158,6 +163,13 @@ public class NotificationItemView extends PopupItemView implements LogContainerP } @Override + public int getArrowColor(boolean isArrowAttachedToBottom) { + return ContextCompat.getColor(getContext(), isArrowAttachedToBottom + ? R.color.popup_background_color + : R.color.popup_header_background_color); + } + + @Override public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target, LauncherLogProto.Target targetParent) { target.itemType = LauncherLogProto.ItemType.NOTIFICATION; diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java index d6e0272fe..0d6da77ee 100644 --- a/src/com/android/launcher3/notification/NotificationMainView.java +++ b/src/com/android/launcher3/notification/NotificationMainView.java @@ -122,7 +122,7 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal @Override public boolean canChildBeDismissed(View v) { - return mNotificationInfo.dismissable; + return mNotificationInfo != null && mNotificationInfo.dismissable; } @Override diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index fb7f80ceb..ccead37dc 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -25,7 +25,6 @@ import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; -import android.graphics.Color; import android.graphics.CornerPathEffect; import android.graphics.Paint; import android.graphics.PointF; @@ -115,7 +114,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra mStartDragThreshold = getResources().getDimensionPixelSize( R.dimen.deep_shortcuts_start_drag_threshold); - // TODO: make sure the delegate works for all items, not just shortcuts. mAccessibilityDelegate = new ShortcutMenuAccessibilityDelegate(mLauncher); mIsRtl = Utilities.isRtl(getResources()); } @@ -169,8 +167,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra final Resources resources = getResources(); final int arrowWidth = resources.getDimensionPixelSize(R.dimen.popup_arrow_width); final int arrowHeight = resources.getDimensionPixelSize(R.dimen.popup_arrow_height); - final int arrowHorizontalOffset = resources.getDimensionPixelSize( - R.dimen.popup_arrow_horizontal_offset); final int arrowVerticalOffset = resources.getDimensionPixelSize( R.dimen.popup_arrow_vertical_offset); @@ -179,7 +175,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra // Add dummy views first, and populate with real info when ready. PopupPopulator.Item[] itemsToPopulate = PopupPopulator .getItemsToPopulate(shortcutIds, notificationKeys, systemShortcuts); - addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1); + addDummyViews(itemsToPopulate, notificationKeys.size() > 1); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset); @@ -190,7 +186,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra mNotificationItemView = null; mShortcutsItemView = null; itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate); - addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1); + addDummyViews(itemsToPopulate, notificationKeys.size() > 1); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset); @@ -207,7 +203,21 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra updateNotificationHeader(); } + int numShortcuts = shortcutViews.size() + systemShortcutViews.size(); + int numNotifications = notificationKeys.size(); + if (numNotifications == 0) { + setContentDescription(getContext().getString(R.string.shortcuts_menu_description, + numShortcuts, originalIcon.getContentDescription().toString())); + } else { + setContentDescription(getContext().getString( + R.string.shortcuts_menu_with_notifications_description, numShortcuts, + numNotifications, originalIcon.getContentDescription().toString())); + } + // Add the arrow. + final int arrowHorizontalOffset = resources.getDimensionPixelSize(isAlignedWithStart() ? + R.dimen.popup_arrow_horizontal_offset_start : + R.dimen.popup_arrow_horizontal_offset_end); mArrow = addArrowView(arrowHorizontalOffset, arrowVerticalOffset, arrowWidth, arrowHeight); mArrow.setPivotX(arrowWidth / 2); mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight); @@ -225,8 +235,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra systemShortcuts, systemShortcutViews)); } - private void addDummyViews(BubbleTextView originalIcon, - PopupPopulator.Item[] itemTypesToPopulate, boolean notificationFooterHasIcons) { + private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate, + boolean notificationFooterHasIcons) { final Resources res = getResources(); final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing); final LayoutInflater inflater = mLauncher.getLayoutInflater(); @@ -243,12 +253,14 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra int footerHeight = notificationFooterHasIcons ? res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0; item.findViewById(R.id.footer).getLayoutParams().height = footerHeight; + mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate); + } else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) { + item.setAccessibilityDelegate(mAccessibilityDelegate); } boolean shouldAddBottomMargin = nextItemTypeToPopulate != null && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut; - item.setAccessibilityDelegate(mAccessibilityDelegate); if (itemTypeToPopulate.isShortcut) { if (mShortcutsItemView == null) { mShortcutsItemView = (ShortcutsItemView) inflater.inflate( @@ -266,9 +278,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } } } - // TODO: update this, since not all items are shortcuts - setContentDescription(getContext().getString(R.string.shortcuts_menu_description, - numItems, originalIcon.getContentDescription().toString())); } protected PopupItemView getItemViewAt(int index) { @@ -493,7 +502,11 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create( width, height, !mIsAboveIcon)); Paint arrowPaint = arrowDrawable.getPaint(); - arrowPaint.setColor(Color.WHITE); + // Note that we have to use getChildAt() instead of getItemViewAt(), + // since the latter expects the arrow which hasn't been added yet. + PopupItemView itemAttachedToArrow = (PopupItemView) + (getChildAt(mIsAboveIcon ? getChildCount() - 1 : 0)); + arrowPaint.setColor(itemAttachedToArrow.getArrowColor(mIsAboveIcon)); // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable. int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius); arrowPaint.setPathEffect(new CornerPathEffect(radius)); diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java index a18f650c1..384f554e1 100644 --- a/src/com/android/launcher3/popup/PopupItemView.java +++ b/src/com/android/launcher3/popup/PopupItemView.java @@ -48,7 +48,7 @@ public abstract class PopupItemView extends FrameLayout protected final Rect mPillRect; private float mOpenAnimationProgress; - + protected final boolean mIsRtl; protected View mIconView; private final Paint mBackgroundClipPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); @@ -75,6 +75,8 @@ public abstract class PopupItemView extends FrameLayout canvas.setBitmap(mRoundedCornerBitmap); canvas.drawArc(0, 0, radius*2, radius*2, 180, 90, true, mBackgroundClipPaint); mBackgroundClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); + + mIsRtl = Utilities.isRtl(getResources()); } @Override @@ -120,7 +122,9 @@ public abstract class PopupItemView extends FrameLayout */ public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { Point center = getIconCenter(); - int arrowCenter = getResources().getDimensionPixelSize(R.dimen.popup_arrow_horizontal_center); + int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ? + R.dimen.popup_arrow_horizontal_center_start: + R.dimen.popup_arrow_horizontal_center_end); ValueAnimator openAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter) .createRevealAnimator(this, false); @@ -144,7 +148,9 @@ public abstract class PopupItemView extends FrameLayout public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, long duration) { Point center = getIconCenter(); - int arrowCenter = getResources().getDimensionPixelSize(R.dimen.popup_arrow_horizontal_center); + int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ? + R.dimen.popup_arrow_horizontal_center_start : + R.dimen.popup_arrow_horizontal_center_end); ValueAnimator closeAnimator = new ZoomRevealOutlineProvider(center.x, center.y, mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter) .createRevealAnimator(this, true); @@ -177,6 +183,8 @@ public abstract class PopupItemView extends FrameLayout return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius); } + public abstract int getArrowColor(boolean isArrowAttachedToBottom); + /** * Extension of {@link PillRevealOutlineProvider} which scales the icon based on the height. */ diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java index ee64b984a..5b3b02eac 100644 --- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java +++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.content.Context; import android.graphics.Point; +import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -109,7 +110,7 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x; mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx; - DragView dv = mLauncher.getWorkspace().beginDragShared(sv.getBubbleText(), + DragView dv = mLauncher.getWorkspace().beginDragShared(sv.getIconView(), (PopupContainerWithArrow) getParent(), sv.getFinalInfo(), new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions()); dv.animateShift(-mIconShift.x, -mIconShift.y); @@ -246,6 +247,14 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick } @Override + public int getArrowColor(boolean isArrowAttachedToBottom) { + return ContextCompat.getColor(getContext(), + isArrowAttachedToBottom || mSystemShortcutIcons == null + ? R.color.popup_background_color + : R.color.popup_header_background_color); + } + + @Override public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target, LauncherLogProto.Target targetParent) { target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT; |