1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.util;
17 
18 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
19 
20 import android.app.Activity;
21 import android.content.Context;
22 import android.os.Handler;
23 import android.os.IBinder;
24 import android.os.Message;
25 import android.view.inputmethod.InputMethodManager;
26 
27 /**
28  * Utility class for offloading some class from UI thread
29  */
30 public class UiThreadHelper {
31 
32     private static final MainThreadInitializedObject<Handler> HANDLER =
33             new MainThreadInitializedObject<>(
34                     c -> new Handler(UI_HELPER_EXECUTOR.getLooper(), new UiCallbacks(c)));
35 
36     private static final int MSG_HIDE_KEYBOARD = 1;
37     private static final int MSG_SET_ORIENTATION = 2;
38     private static final int MSG_RUN_COMMAND = 3;
39 
hideKeyboardAsync(Context context, IBinder token)40     public static void hideKeyboardAsync(Context context, IBinder token) {
41         Message.obtain(HANDLER.get(context), MSG_HIDE_KEYBOARD, token).sendToTarget();
42     }
43 
setOrientationAsync(Activity activity, int orientation)44     public static void setOrientationAsync(Activity activity, int orientation) {
45         Message.obtain(HANDLER.get(activity), MSG_SET_ORIENTATION, orientation, 0, activity)
46                 .sendToTarget();
47     }
48 
setBackButtonAlphaAsync(Context context, AsyncCommand command, float alpha, boolean animate)49     public static void setBackButtonAlphaAsync(Context context, AsyncCommand command, float alpha,
50             boolean animate) {
51         runAsyncCommand(context, command, Float.floatToIntBits(alpha), animate ? 1 : 0);
52     }
53 
runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2)54     public static void runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2) {
55         Message.obtain(HANDLER.get(context), MSG_RUN_COMMAND, arg1, arg2, command).sendToTarget();
56     }
57 
58     private static class UiCallbacks implements Handler.Callback {
59 
60         private final Context mContext;
61         private final InputMethodManager mIMM;
62 
UiCallbacks(Context context)63         UiCallbacks(Context context) {
64             mContext = context;
65             mIMM = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
66         }
67 
68         @Override
handleMessage(Message message)69         public boolean handleMessage(Message message) {
70             switch (message.what) {
71                 case MSG_HIDE_KEYBOARD:
72                     mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0);
73                     return true;
74                 case MSG_SET_ORIENTATION:
75                     ((Activity) message.obj).setRequestedOrientation(message.arg1);
76                     return true;
77                 case MSG_RUN_COMMAND:
78                     ((AsyncCommand) message.obj).execute(mContext, message.arg1, message.arg2);
79                     return true;
80             }
81             return false;
82         }
83     }
84 
85     public interface AsyncCommand {
execute(Context proxy, int arg1, int arg2)86         void execute(Context proxy, int arg1, int arg2);
87     }
88 }
89