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 android.app.Activity; 19 import android.content.Context; 20 import android.os.Handler; 21 import android.os.HandlerThread; 22 import android.os.IBinder; 23 import android.os.Looper; 24 import android.os.Message; 25 import android.os.Process; 26 import android.view.inputmethod.InputMethodManager; 27 28 /** 29 * Utility class for offloading some class from UI thread 30 */ 31 public class UiThreadHelper { 32 33 private static HandlerThread sHandlerThread; 34 private static Handler sHandler; 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 getBackgroundLooper()40 public static Looper getBackgroundLooper() { 41 if (sHandlerThread == null) { 42 sHandlerThread = 43 new HandlerThread("UiThreadHelper", Process.THREAD_PRIORITY_FOREGROUND); 44 sHandlerThread.start(); 45 } 46 return sHandlerThread.getLooper(); 47 } 48 getHandler(Context context)49 private static Handler getHandler(Context context) { 50 if (sHandler == null) { 51 sHandler = new Handler(getBackgroundLooper(), 52 new UiCallbacks(context.getApplicationContext())); 53 } 54 return sHandler; 55 } 56 hideKeyboardAsync(Context context, IBinder token)57 public static void hideKeyboardAsync(Context context, IBinder token) { 58 Message.obtain(getHandler(context), MSG_HIDE_KEYBOARD, token).sendToTarget(); 59 } 60 setOrientationAsync(Activity activity, int orientation)61 public static void setOrientationAsync(Activity activity, int orientation) { 62 Message.obtain(getHandler(activity), MSG_SET_ORIENTATION, orientation, 0, activity) 63 .sendToTarget(); 64 } 65 runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2)66 public static void runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2) { 67 Message.obtain(getHandler(context), MSG_RUN_COMMAND, arg1, arg2, command).sendToTarget(); 68 } 69 70 private static class UiCallbacks implements Handler.Callback { 71 72 private final InputMethodManager mIMM; 73 UiCallbacks(Context context)74 UiCallbacks(Context context) { 75 mIMM = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 76 } 77 78 @Override handleMessage(Message message)79 public boolean handleMessage(Message message) { 80 switch (message.what) { 81 case MSG_HIDE_KEYBOARD: 82 mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0); 83 return true; 84 case MSG_SET_ORIENTATION: 85 ((Activity) message.obj).setRequestedOrientation(message.arg1); 86 return true; 87 case MSG_RUN_COMMAND: 88 ((AsyncCommand) message.obj).execute(message.arg1, message.arg2); 89 return true; 90 } 91 return false; 92 } 93 } 94 95 public interface AsyncCommand { 96 execute(int arg1, int arg2)97 void execute(int arg1, int arg2); 98 } 99 } 100