From 413aded6007032278120de0f43c4d520c269b53c Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 18 Jul 2014 08:30:12 +0900 Subject: [PATCH] Add a compatibility library for newly added methods in L This CL adds an compatibility library for InputConnection#requestCursorAnchorInfo method that is supposed to be available in L and later. BUG: 16382260 Change-Id: I68be0c56b9fd929546e8706ccece938ae4f33339 --- .../compat/InputConnectionCompatUtils.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java new file mode 100644 index 000000000..d7d53a48b --- /dev/null +++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 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.inputmethod.compat; + +import android.view.inputmethod.InputConnection; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +public final class InputConnectionCompatUtils { + // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later. + private static Class getCursorAnchorInfoRequestClass() { + try { + return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest"); + } catch (ClassNotFoundException e) { + return null; + } + } + + private static final Class TYPE_CursorAnchorInfoRequest; + private static final Constructor CONSTRUCTOR_CursorAnchorInfoRequest; + private static final Method METHOD_requestCursorAnchorInfo; + static { + TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass(); + CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor( + TYPE_CursorAnchorInfoRequest, int.class, int.class); + METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class, + "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest); + } + + public static boolean isRequestCursorAnchorInfoAvailable() { + return METHOD_requestCursorAnchorInfo != null && + CONSTRUCTOR_CursorAnchorInfoRequest != null; + } + + /** + * A local copy of CursorAnchorInfoRequest.RESULT_NOT_HANDLED until the SDK becomes publicly + * available. + */ + private final static int CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED = 0; + + public static int requestCursorAnchorInfo(final InputConnection inputConnection, + final int type, final int flags) { + if (!isRequestCursorAnchorInfoAvailable()) { + return CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED; + } + final Object requestObject = CompatUtils.newInstance( + CONSTRUCTOR_CursorAnchorInfoRequest, type, flags); + if (requestObject == null) { + return CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED; + } + return (Integer) CompatUtils.invoke(inputConnection, + CURSOR_ANCHOR_INFO_REQUEST_RESULT_NOT_HANDLED /* defaultValue */, + METHOD_requestCursorAnchorInfo, requestObject); + } +}