From 673faf59ee21faa4cb4af6d26b214fcb0820ea5d Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Fri, 16 Apr 2021 12:50:22 -0700 Subject: [PATCH] Add IME switcher/hide button bar when IME showing Bug: 180046394 Change-Id: Ic2bd919ab3d27e0a430b081c771ea8dc5827be81 --- quickstep/res/drawable/ic_ime_switcher.xml | 25 +++++ quickstep/res/layout/taskbar.xml | 6 ++ .../launcher3/BaseQuickstepLauncher.java | 34 +++++++ .../launcher3/taskbar/ButtonProvider.java | 76 +++++++++++++++ .../android/launcher3/taskbar/ImeBarView.java | 92 +++++++++++++++++++ .../taskbar/TaskbarAnimationController.java | 12 ++- .../launcher3/taskbar/TaskbarController.java | 78 +++++++++++++--- .../taskbar/TaskbarNavButtonController.java | 13 ++- .../launcher3/taskbar/TaskbarView.java | 46 +++++----- .../quickstep/TouchInteractionService.java | 41 ++++++++- 10 files changed, 383 insertions(+), 40 deletions(-) create mode 100644 quickstep/res/drawable/ic_ime_switcher.xml create mode 100644 quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java create mode 100644 quickstep/src/com/android/launcher3/taskbar/ImeBarView.java diff --git a/quickstep/res/drawable/ic_ime_switcher.xml b/quickstep/res/drawable/ic_ime_switcher.xml new file mode 100644 index 0000000000..a86d3904c7 --- /dev/null +++ b/quickstep/res/drawable/ic_ime_switcher.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml index 732222ade8..240fe556da 100644 --- a/quickstep/res/layout/taskbar.xml +++ b/quickstep/res/layout/taskbar.xml @@ -26,4 +26,10 @@ android:layout_height="wrap_content" android:gravity="center"/> + + \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index c6c6c01542..fb26e76994 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -30,8 +30,11 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.content.IntentSender; +import android.content.ComponentName; +import android.content.ServiceConnection; import android.os.Bundle; import android.os.CancellationSignal; +import android.os.IBinder; import android.view.View; import androidx.annotation.Nullable; @@ -61,6 +64,7 @@ import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; +import com.android.quickstep.TouchInteractionService; import com.android.quickstep.util.RemoteAnimationProvider; import com.android.quickstep.util.RemoteFadeOutAnimationListener; import com.android.quickstep.util.SplitSelectStateController; @@ -82,6 +86,8 @@ public abstract class BaseQuickstepLauncher extends Launcher private DepthController mDepthController = new DepthController(this); private QuickstepTransitionManager mAppTransitionManager; + private ServiceConnection mTisBinderConnection; + protected TouchInteractionService.TISBinder mTisBinder; /** * Reusable command for applying the back button alpha on the background thread. @@ -103,6 +109,24 @@ public abstract class BaseQuickstepLauncher extends Launcher super.onCreate(savedInstanceState); SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this); addMultiWindowModeChangedListener(mDepthController); + setupTouchInteractionServiceBinder(); + } + + private void setupTouchInteractionServiceBinder() { + Intent intent = new Intent(this, TouchInteractionService.class); + mTisBinderConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder binder) { + mTisBinder = ((TouchInteractionService.TISBinder) binder); + mTisBinder.setTaskbarOverviewProxyDelegate(mTaskbarController); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + mTisBinder = null; + } + }; + bindService(intent, mTisBinderConnection, 0); } @Override @@ -113,6 +137,10 @@ public abstract class BaseQuickstepLauncher extends Launcher if (mTaskbarController != null) { mTaskbarController.cleanup(); mTaskbarController = null; + if (mTisBinder != null) { + mTisBinder.setTaskbarOverviewProxyDelegate(null); + unbindService(mTisBinderConnection); + } } super.onDestroy(); @@ -248,6 +276,9 @@ public abstract class BaseQuickstepLauncher extends Launcher private void addTaskbarIfNecessary() { if (mTaskbarController != null) { mTaskbarController.cleanup(); + if (mTisBinder != null) { + mTisBinder.setTaskbarOverviewProxyDelegate(null); + } mTaskbarController = null; } if (mDeviceProfile.isTaskbarPresent) { @@ -256,6 +287,9 @@ public abstract class BaseQuickstepLauncher extends Launcher mTaskbarController = new TaskbarController(this, taskbarActivityContext.getTaskbarContainerView(), taskbarViewOnHome); mTaskbarController.init(); + if (mTisBinder != null) { + mTisBinder.setTaskbarOverviewProxyDelegate(mTaskbarController); + } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java new file mode 100644 index 0000000000..0d4130d1bc --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java @@ -0,0 +1,76 @@ +/* + * Copyright 2021 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.taskbar; + +import android.annotation.DrawableRes; +import android.content.Context; +import android.view.View; +import android.widget.ImageView; + +import com.android.launcher3.R; + +/** + * Creates Buttons for Taskbar for 3 button nav. + * Can add animations and state management for buttons in this class as things progress. + */ +public class ButtonProvider { + + private int mMarginLeftRight; + private final Context mContext; + + public ButtonProvider(Context context) { + mContext = context; + } + + public void setMarginLeftRight(int margin) { + mMarginLeftRight = margin; + } + + public View getBack() { + // Back button + return getButtonForDrawable(R.drawable.ic_sysbar_back); + } + + public View getDown() { + // Ime down button + return getButtonForDrawable(R.drawable.ic_sysbar_back); + } + + public View getHome() { + // Home button + return getButtonForDrawable(R.drawable.ic_sysbar_home); + } + + public View getRecents() { + // Recents button + return getButtonForDrawable(R.drawable.ic_sysbar_recent); + } + + public View getImeSwitcher() { + // IME Switcher Button + return getButtonForDrawable(R.drawable.ic_ime_switcher); + } + + private View getButtonForDrawable(@DrawableRes int drawableId) { + ImageView buttonView = new ImageView(mContext); + buttonView.setImageResource(drawableId); + buttonView.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect); + buttonView.setPadding(mMarginLeftRight, 0, mMarginLeftRight, 0); + return buttonView; + } + +} diff --git a/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java new file mode 100644 index 0000000000..bb3669beed --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java @@ -0,0 +1,92 @@ +/* + * Copyright 2021 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.taskbar; + +import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; +import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.RelativeLayout; + +import com.android.launcher3.views.ActivityContext; + +public class ImeBarView extends RelativeLayout { + + private ButtonProvider mButtonProvider; + private TaskbarController.TaskbarViewCallbacks mControllerCallbacks; + private View mImeView; + + public ImeBarView(Context context) { + this(context, null); + } + + public ImeBarView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ImeBarView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public void construct(ButtonProvider buttonProvider) { + mButtonProvider = buttonProvider; + } + + public void init(TaskbarController.TaskbarViewCallbacks taskbarCallbacks) { + mControllerCallbacks = taskbarCallbacks; + ActivityContext context = getActivityContext(); + RelativeLayout.LayoutParams imeParams = new RelativeLayout.LayoutParams( + context.getDeviceProfile().iconSizePx, + context.getDeviceProfile().iconSizePx + ); + RelativeLayout.LayoutParams downParams = new RelativeLayout.LayoutParams(imeParams); + + imeParams.addRule(ALIGN_PARENT_END); + imeParams.setMarginEnd(context.getDeviceProfile().iconSizePx); + downParams.setMarginStart(context.getDeviceProfile().iconSizePx); + downParams.addRule(ALIGN_PARENT_START); + + // Down Arrow + View downView = mButtonProvider.getDown(); + downView.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick( + BUTTON_BACK)); + downView.setLayoutParams(downParams); + downView.setRotation(-90); + addView(downView); + + // IME switcher button + mImeView = mButtonProvider.getImeSwitcher(); + mImeView.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick( + BUTTON_IME_SWITCH)); + mImeView.setLayoutParams(imeParams); + addView(mImeView); + } + + public void cleanup() { + removeAllViews(); + } + + public void setImeSwitcherVisibility(boolean show) { + mImeView.setVisibility(show ? VISIBLE : GONE); + } + + private T getActivityContext() { + return ActivityContext.lookupContext(getContext()); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java index 46e4506f1f..29f6935f8a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java @@ -44,7 +44,7 @@ public class TaskbarAnimationController { private final AnimatedFloat mTaskbarVisibilityAlphaForLauncherState = new AnimatedFloat( this::updateVisibilityAlpha); private final AnimatedFloat mTaskbarVisibilityAlphaForIme = new AnimatedFloat( - this::updateVisibilityAlpha); + this::updateVisibilityAlphaForIme); // Scale. private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat( @@ -110,16 +110,22 @@ public class TaskbarAnimationController { // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the // assumption being that Taskbar should always be visible regardless of the current // LauncherState if Launcher is paused. + float alphaDueToIme = mTaskbarVisibilityAlphaForIme.value; float alphaDueToLauncher = Math.max(mTaskbarBackgroundAlpha.value, mTaskbarVisibilityAlphaForLauncherState.value); - float alphaDueToOther = mTaskbarVisibilityAlphaForIme.value; - float taskbarAlpha = alphaDueToLauncher * alphaDueToOther; + float taskbarAlpha = alphaDueToLauncher * alphaDueToIme; mTaskbarCallbacks.updateTaskbarVisibilityAlpha(taskbarAlpha); // Make the nav bar invisible if taskbar is visible. setNavBarButtonAlpha(1f - taskbarAlpha); } + private void updateVisibilityAlphaForIme() { + updateVisibilityAlpha(); + float taskbarAlphaDueToIme = mTaskbarVisibilityAlphaForIme.value; + mTaskbarCallbacks.updateImeBarVisibilityAlpha(1f - taskbarAlphaDueToIme); + } + private void updateScale() { // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the // assumption being that Taskbar should always be at scale 1f regardless of the current diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index cf6cfb34e8..6084e10d85 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -15,6 +15,9 @@ */ package com.android.launcher3.taskbar; +import static android.view.View.GONE; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -28,6 +31,7 @@ import android.app.ActivityOptions; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.inputmethodservice.InputMethodService; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -53,7 +57,7 @@ import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.views.ActivityContext; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.SysUINavigationMode; -import com.android.quickstep.TaskAnimationManager; +import com.android.quickstep.TouchInteractionService.TaskbarOverviewProxyDelegate; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -61,13 +65,15 @@ import com.android.systemui.shared.system.WindowManagerWrapper; /** * Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView. */ -public class TaskbarController { +public class TaskbarController implements TaskbarOverviewProxyDelegate { private static final String WINDOW_TITLE = "Taskbar"; private final TaskbarContainerView mTaskbarContainerView; private final TaskbarView mTaskbarViewInApp; private final TaskbarView mTaskbarViewOnHome; + private final ImeBarView mImeBarView; + private final BaseQuickstepLauncher mLauncher; private final WindowManager mWindowManager; // Layout width and height of the Taskbar in the default state. @@ -92,10 +98,13 @@ public class TaskbarController { mLauncher = launcher; mTaskbarContainerView = taskbarContainerView; mTaskbarContainerView.construct(createTaskbarContainerViewCallbacks()); + ButtonProvider buttonProvider = new ButtonProvider(launcher); mTaskbarViewInApp = mTaskbarContainerView.findViewById(R.id.taskbar_view); - mTaskbarViewInApp.construct(createTaskbarViewCallbacks()); + mTaskbarViewInApp.construct(createTaskbarViewCallbacks(), buttonProvider); mTaskbarViewOnHome = taskbarViewOnHome; - mTaskbarViewOnHome.construct(createTaskbarViewCallbacks()); + mTaskbarViewOnHome.construct(createTaskbarViewCallbacks(), buttonProvider); + mImeBarView = mTaskbarContainerView.findViewById(R.id.ime_bar_view); + mImeBarView.construct(buttonProvider); mNavButtonController = new TaskbarNavButtonController(launcher); mWindowManager = mLauncher.getWindowManager(); mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getDeviceProfile().taskbarSize); @@ -116,10 +125,20 @@ public class TaskbarController { @Override public void updateTaskbarVisibilityAlpha(float alpha) { - mTaskbarContainerView.setAlpha(alpha); + mTaskbarViewInApp.setAlpha(alpha); mTaskbarViewOnHome.setAlpha(alpha); } + @Override + public void updateImeBarVisibilityAlpha(float alpha) { + if (mNavMode != SysUINavigationMode.Mode.THREE_BUTTONS) { + // TODO Remove sysui IME bar for gesture nav as well + return; + } + mImeBarView.setAlpha(alpha); + mImeBarView.setVisibility(alpha == 0 ? GONE : VISIBLE); + } + @Override public void updateTaskbarScale(float scale) { mTaskbarViewInApp.setScaleX(scale); @@ -144,16 +163,21 @@ public class TaskbarController { return new TaskbarContainerViewCallbacks() { @Override public void onViewRemoved() { - if (mTaskbarContainerView.getChildCount() == 1) { - // Only TaskbarView remains. - setTaskbarWindowFullscreen(false); + // Ensure no other children present (like Folders, etc) + for (int i = 0; i < mTaskbarContainerView.getChildCount(); i++) { + View v = mTaskbarContainerView.getChildAt(i); + if (!((v instanceof TaskbarView) || (v instanceof ImeBarView))){ + return; + } } + setTaskbarWindowFullscreen(false); } @Override public boolean isTaskbarTouchable() { return mTaskbarContainerView.getAlpha() > AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD - && mTaskbarViewInApp.getVisibility() == View.VISIBLE + && (mTaskbarViewInApp.getVisibility() == VISIBLE + || mImeBarView.getVisibility() == VISIBLE) && !mIsAnimatingToLauncher; } }; @@ -206,7 +230,7 @@ public class TaskbarController { // space so that the others line up with the home screen hotseat. boolean isOnHomeScreen = taskbarView == mTaskbarViewOnHome || mLauncher.hasBeenResumed() || mIsAnimatingToLauncher; - return isOnHomeScreen ? View.INVISIBLE : View.GONE; + return isOnHomeScreen ? INVISIBLE : GONE; } @Override @@ -246,6 +270,7 @@ public class TaskbarController { mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons(), mNavMode); mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons(), mNavMode); mTaskbarContainerView.init(mTaskbarViewInApp); + mImeBarView.init(createTaskbarViewCallbacks()); addToWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks()); mTaskbarAnimationController.init(); @@ -287,6 +312,7 @@ public class TaskbarController { mTaskbarViewInApp.cleanup(); mTaskbarViewOnHome.cleanup(); mTaskbarContainerView.cleanup(); + mImeBarView.cleanup(); removeFromWindowManager(); mTaskbarStateHandler.setTaskbarCallbacks(null); mTaskbarAnimationController.cleanup(); @@ -410,6 +436,28 @@ public class TaskbarController { */ public void setIsImeVisible(boolean isImeVisible) { mTaskbarAnimationController.animateToVisibilityForIme(isImeVisible ? 0 : 1); + blockTaskbarTouchesForIme(isImeVisible); + } + + /** + * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from + * instantiating at all, which is what's responsible for sending sysui state flags over. + * + * @param vis IME visibility flag + * @param backDisposition Used to determine back button behavior for software keyboard + * See BACK_DISPOSITION_* constants in {@link InputMethodService} + */ + public void updateImeStatus(int displayId, int vis, int backDisposition, + boolean showImeSwitcher) { + if (displayId != mTaskbarContainerView.getContext().getDisplayId() || + mNavMode != SysUINavigationMode.Mode.THREE_BUTTONS) { + return; + } + + boolean imeVisible = (vis & InputMethodService.IME_VISIBLE) != 0; + mTaskbarAnimationController.animateToVisibilityForIme(imeVisible ? 0 : 1); + mImeBarView.setImeSwitcherVisibility(showImeSwitcher); + blockTaskbarTouchesForIme(imeVisible); } /** @@ -459,12 +507,17 @@ public class TaskbarController { private void setWhichTaskbarViewIsVisible(@Nullable TaskbarView visibleTaskbar) { mTaskbarViewInApp.setVisibility(visibleTaskbar == mTaskbarViewInApp - ? View.VISIBLE : View.INVISIBLE); + ? VISIBLE : INVISIBLE); mTaskbarViewOnHome.setVisibility(visibleTaskbar == mTaskbarViewOnHome - ? View.VISIBLE : View.INVISIBLE); + ? VISIBLE : INVISIBLE); mLauncher.getHotseat().setIconsAlpha(visibleTaskbar != mTaskbarViewInApp ? 1f : 0f); } + private void blockTaskbarTouchesForIme(boolean block) { + mTaskbarViewOnHome.setTouchesEnabled(!block); + mTaskbarViewInApp.setTouchesEnabled(!block); + } + /** * Returns the ratio of the taskbar icon size on home vs in an app. */ @@ -508,6 +561,7 @@ public class TaskbarController { protected interface TaskbarAnimationControllerCallbacks { void updateTaskbarBackgroundAlpha(float alpha); void updateTaskbarVisibilityAlpha(float alpha); + void updateImeBarVisibilityAlpha(float alpha); void updateTaskbarScale(float scale); void updateTaskbarTranslationY(float translationY); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java index cf8ff381b1..54e1610cd1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java @@ -18,6 +18,7 @@ package com.android.launcher3.taskbar; import android.content.Context; import android.content.Intent; +import android.view.inputmethod.InputMethodManager; import androidx.annotation.IntDef; @@ -41,7 +42,8 @@ public class TaskbarNavButtonController { @IntDef(value = { BUTTON_BACK, BUTTON_HOME, - BUTTON_RECENTS + BUTTON_RECENTS, + BUTTON_IME_SWITCH }) public @interface TaskbarButton {} @@ -49,6 +51,7 @@ public class TaskbarNavButtonController { static final int BUTTON_BACK = 1; static final int BUTTON_HOME = BUTTON_BACK << 1; static final int BUTTON_RECENTS = BUTTON_HOME << 1; + static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1; private final Context mContext; @@ -68,6 +71,9 @@ public class TaskbarNavButtonController { case BUTTON_RECENTS: navigateToOverview();; break; + case BUTTON_IME_SWITCH: + showIMESwitcher(); + break; } } @@ -86,4 +92,9 @@ public class TaskbarNavButtonController { SystemUiProxy.INSTANCE.getNoCreate().onBackPressed(); } + private void showIMESwitcher() { + mContext.getSystemService(InputMethodManager.class).showInputMethodPickerFromSystem( + true /* showAuxiliarySubtypes */, mContext.getDisplayId()); + } + } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index 5be25b9bbb..9e8013e63e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -15,9 +15,6 @@ */ package com.android.launcher3.taskbar; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; - import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS; @@ -38,7 +35,6 @@ import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; -import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.LayoutRes; @@ -83,18 +79,21 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa private LayoutTransition mLayoutTransition; private int mHotseatStartIndex; private int mHotseatEndIndex; - private LinearLayout mButtonRegion; // Delegate touches to the closest view if within mIconTouchSize. private boolean mDelegateTargeted; private View mDelegateView; + // Prevents dispatching touches to children if true + private boolean mTouchEnabled = true; private boolean mIsDraggingItem; // Only non-null when the corresponding Folder is open. private @Nullable FolderIcon mLeaveBehindFolderIcon; private int mNavButtonStartIndex; + /** Provider of buttons added to taskbar in 3 button nav */ + private ButtonProvider mButtonProvider; public TaskbarView(@NonNull Context context) { this(context, null); @@ -119,11 +118,14 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } - protected void construct(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) { + protected void construct(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks, + ButtonProvider buttonProvider) { mControllerCallbacks = taskbarViewCallbacks; mNonIconScale = mControllerCallbacks.getNonIconScale(this); mItemMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.taskbar_icon_spacing); mItemMarginLeftRight = Math.round(mItemMarginLeftRight * mNonIconScale); + mButtonProvider = buttonProvider; + mButtonProvider.setMarginLeftRight(mItemMarginLeftRight); } protected void init(int numHotseatIcons, SysUINavigationMode.Mode newMode) { @@ -272,12 +274,24 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa } } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (!mTouchEnabled) { + return true; + } + return super.dispatchTouchEvent(ev); + } + @Override public boolean onTouchEvent(MotionEvent event) { boolean handled = delegateTouchIfNecessary(event); return super.onTouchEvent(event) || handled; } + public void setTouchesEnabled(boolean touchEnabled) { + this.mTouchEnabled = touchEnabled; + } + /** * User touched the Taskbar background. Determine whether the touch is close enough to a view * that we should forward the touches to it. @@ -383,9 +397,6 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa mButtonRegion.removeAllViews(); } mButtonRegion.setVisibility(VISIBLE); - LayoutParams regionParams = new LayoutParams(WRAP_CONTENT, MATCH_PARENT); - regionParams.gravity = Gravity.START; // check left/right preference - regionParams.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0); LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams( context.getDeviceProfile().iconSizePx, @@ -393,29 +404,18 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa ); buttonParams.gravity = Gravity.CENTER; - // Back button - ImageView backButton = new ImageView(getContext()); - backButton.setImageResource(R.drawable.ic_sysbar_back); - backButton.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect); - backButton.setPadding(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0); + View backButton = mButtonProvider.getBack(); backButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick( BUTTON_BACK)); mButtonRegion.addView(backButton, buttonParams); // Home button - ImageView homeButton = new ImageView(getContext()); - homeButton.setImageResource(R.drawable.ic_sysbar_home); - homeButton.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect); - homeButton.setPadding(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0); + View homeButton = mButtonProvider.getHome(); homeButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick( BUTTON_HOME)); mButtonRegion.addView(homeButton, buttonParams); - // Recents button - ImageView recentsButton = new ImageView(getContext()); - recentsButton.setImageResource(R.drawable.ic_sysbar_recent); - recentsButton.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect); - recentsButton.setPadding(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0); + View recentsButton = mButtonProvider.getRecents(); recentsButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick( BUTTON_RECENTS)); mButtonRegion.addView(recentsButton, buttonParams); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index afda3b9486..47defaa599 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -52,6 +52,7 @@ import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; +import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Log; @@ -145,7 +146,22 @@ public class TouchInteractionService extends Service implements PluginListener mDeviceState.setDeferredGestureRegion(region)); } + @Override public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) { WindowBounds wb = new WindowBounds(bounds, insets); MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb)); } + + @Override + public void onImeWindowStatusChanged(int displayId, IBinder token, int vis, + int backDisposition, boolean showImeSwitcher) throws RemoteException { + if (mTaskbarOverviewProxyDelegate == null) { + return; + } + MAIN_EXECUTOR.execute(() -> { + if (mTaskbarOverviewProxyDelegate == null) { + return; + } + mTaskbarOverviewProxyDelegate + .updateImeStatus(displayId, vis, backDisposition, showImeSwitcher); + }); + } }; + public interface TaskbarOverviewProxyDelegate { + void updateImeStatus(int displayId, int vis, int backDisposition, + boolean showImeSwitcher); + } + private static boolean sConnected = false; private static TouchInteractionService sInstance; private static boolean sIsInitialized = false; private RotationTouchHelper mRotationTouchHelper; + @Nullable + private TaskbarOverviewProxyDelegate mTaskbarOverviewProxyDelegate; public static boolean isConnected() { return sConnected;