Merge "Simplifying hideKeyboardAsync method" into tm-qpr-dev am: 69b9e736a8

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/19914922

Change-Id: I42ce34aed46e52caa44246c9d026c3334948f79e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-09-10 05:25:36 +00:00
committed by Automerger Merge Worker
7 changed files with 61 additions and 93 deletions
@@ -16,7 +16,6 @@
package com.android.launcher3;
import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.SHOW;
import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
import android.content.Context;
import android.text.TextUtils;
@@ -90,7 +89,7 @@ public class ExtendedEditText extends EditText {
}
public void hideKeyboard() {
hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
ActivityContext.lookupContext(getContext()).hideKeyboard();
clearFocus();
}
-11
View File
@@ -194,7 +194,6 @@ import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.FloatingIconView;
@@ -1653,16 +1652,6 @@ public class Launcher extends StatefulActivity<LauncherState>
}
}
/**
* Hides the keyboard if visible
*/
public void hideKeyboard() {
final View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
UiThreadHelper.hideKeyboardAsync(this, v.getWindowToken());
}
}
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
@@ -21,7 +21,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END;
import static com.android.launcher3.util.LogConfig.SEARCH_LOGGING;
import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
import android.content.Context;
import android.graphics.Canvas;
@@ -162,8 +161,7 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
requestFocus();
mgr.logger().sendToInteractionJankMonitor(
LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN, this);
hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
getApplicationWindowToken());
ActivityContext.lookupContext(getContext()).hideKeyboard();
break;
case SCROLL_STATE_IDLE:
mgr.logger().sendToInteractionJankMonitor(
@@ -17,7 +17,6 @@ package com.android.launcher3.allapps;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -504,8 +503,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
mActivityContext.getStatsLogManager().logger()
.log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB);
}
hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
getApplicationWindowToken());
mActivityContext.hideKeyboard();
});
findViewById(R.id.tab_work)
.setOnClickListener((View view) -> {
@@ -513,8 +511,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
mActivityContext.getStatsLogManager().logger()
.log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB);
}
hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
getApplicationWindowToken());
mActivityContext.hideKeyboard();
});
setDeviceManagementResources();
onActivePageChanged(mViewPager.getNextPage());
@@ -15,24 +15,12 @@
*/
package com.android.launcher3.util;
import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_KEYBOARD_CLOSED;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.inputmethod.InputMethodManager;
import com.android.launcher3.Utilities;
import com.android.launcher3.views.ActivityContext;
/**
* Utility class for offloading some class from UI thread
@@ -43,54 +31,8 @@ public class UiThreadHelper {
new MainThreadInitializedObject<>(
c -> new Handler(UI_HELPER_EXECUTOR.getLooper(), new UiCallbacks(c)));
private static final int MSG_HIDE_KEYBOARD = 1;
private static final int MSG_SET_ORIENTATION = 2;
private static final int MSG_RUN_COMMAND = 3;
private static final String STATS_LOGGER_KEY = "STATS_LOGGER_KEY";
@SuppressLint("NewApi")
public static void hideKeyboardAsync(ActivityContext activityContext, IBinder token) {
View root = activityContext.getDragLayer();
if (Utilities.ATLEAST_R) {
Preconditions.assertUIThread();
// Hide keyboard with WindowInsetsController if could. In case
// hideSoftInputFromWindow may get ignored by input connection being finished
// when the screen is off.
//
// In addition, inside IMF, the keyboards are closed asynchronously that launcher no
// longer need to post to the message queue.
final WindowInsetsController wic = root.getWindowInsetsController();
WindowInsets insets = root.getRootWindowInsets();
boolean isImeShown = insets != null && insets.isVisible(WindowInsets.Type.ime());
if (wic != null && isImeShown) {
activityContext.getStatsLogManager().keyboardStateManager().setKeyboardState(HIDE);
// this method cannot be called cross threads
wic.hide(WindowInsets.Type.ime());
activityContext.getStatsLogManager().logger()
.log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
return;
}
}
// Since the launcher context cannot be accessed directly from callback, adding secondary
// message to log keyboard close event asynchronously.
Bundle mHideKeyboardLoggerMsg = new Bundle();
mHideKeyboardLoggerMsg.putParcelable(
STATS_LOGGER_KEY,
Message.obtain(
HANDLER.get(root.getContext()),
() -> activityContext
.getStatsLogManager()
.logger()
.log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED)
)
);
Message mHideKeyboardMsg = Message.obtain(HANDLER.get(root.getContext()), MSG_HIDE_KEYBOARD,
token);
mHideKeyboardMsg.setData(mHideKeyboardLoggerMsg);
mHideKeyboardMsg.sendToTarget();
}
private static final int MSG_SET_ORIENTATION = 1;
private static final int MSG_RUN_COMMAND = 2;
public static void setOrientationAsync(Activity activity, int orientation) {
Message.obtain(HANDLER.get(activity), MSG_SET_ORIENTATION, orientation, 0, activity)
@@ -109,23 +51,14 @@ public class UiThreadHelper {
private static class UiCallbacks implements Handler.Callback {
private final Context mContext;
private final InputMethodManager mIMM;
UiCallbacks(Context context) {
mContext = context;
mIMM = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
}
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case MSG_HIDE_KEYBOARD:
if (mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0)) {
// log keyboard close event only when keyboard is actually closed
((Message) message.getData().getParcelable(STATS_LOGGER_KEY))
.sendToTarget();
}
return true;
case MSG_SET_ORIENTATION:
((Activity) message.obj).setRequestedOrientation(message.arg1);
return true;
@@ -15,16 +15,26 @@
*/
package com.android.launcher3.views;
import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_KEYBOARD_CLOSED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.dot.DotInfo;
@@ -36,6 +46,7 @@ import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.ViewCache;
/**
@@ -202,4 +213,47 @@ public interface ActivityContext {
ActivityAllAppsContainerView<?> appsView) {
return null;
}
/**
* Hides the keyboard if it is visible
*/
default void hideKeyboard() {
View root = getDragLayer();
if (root == null) {
return;
}
if (Utilities.ATLEAST_R) {
Preconditions.assertUIThread();
// Hide keyboard with WindowInsetsController if could. In case
// hideSoftInputFromWindow may get ignored by input connection being finished
// when the screen is off.
//
// In addition, inside IMF, the keyboards are closed asynchronously that launcher no
// longer need to post to the message queue.
final WindowInsetsController wic = root.getWindowInsetsController();
WindowInsets insets = root.getRootWindowInsets();
boolean isImeShown = insets != null && insets.isVisible(WindowInsets.Type.ime());
if (wic != null && isImeShown) {
StatsLogManager slm = getStatsLogManager();
slm.keyboardStateManager().setKeyboardState(HIDE);
// this method cannot be called cross threads
wic.hide(WindowInsets.Type.ime());
slm.logger().log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
return;
}
}
InputMethodManager imm = root.getContext().getSystemService(InputMethodManager.class);
IBinder token = root.getWindowToken();
if (imm != null && token != null) {
UI_HELPER_EXECUTOR.execute(() -> {
if (imm.hideSoftInputFromWindow(token, 0)) {
// log keyboard close event only when keyboard is actually closed
MAIN_EXECUTOR.execute(() ->
getStatsLogManager().logger().log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED));
}
});
}
}
}
@@ -20,8 +20,6 @@ import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
@@ -313,7 +311,7 @@ public class RecyclerViewFastScroller extends View {
}
private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
ActivityContext.lookupContext(getContext()).hideKeyboard();
mIsDragging = true;
if (mCanThumbDetach) {
mIsThumbDetached = true;