diff options
| author | Michael Wright <michaelwr@google.com> | 2015-08-19 22:52:47 +0100 |
|---|---|---|
| committer | Michael Wright <michaelwr@google.com> | 2015-08-21 17:12:22 +0100 |
| commit | 39e5e947447bc611205404ae6a4690656f1aa0f9 (patch) | |
| tree | e3b56256bffed70d030498b2b69520e0adef2cc6 /core/java/android/hardware/input | |
| parent | 99b252adc78a0450b7a881aff93a77f6d0e160ce (diff) | |
| download | frameworks_base-39e5e947447bc611205404ae6a4690656f1aa0f9.zip frameworks_base-39e5e947447bc611205404ae6a4690656f1aa0f9.tar.gz frameworks_base-39e5e947447bc611205404ae6a4690656f1aa0f9.tar.bz2 | |
Add TabletModeChangedListener for SystemUI.
Bug: 23256614
Change-Id: I6e5d636c24a84846cfad84da800911a469689dda
Diffstat (limited to 'core/java/android/hardware/input')
3 files changed, 168 insertions, 0 deletions
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 465d142..c8b45c7 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -19,6 +19,7 @@ package android.hardware.input; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.KeyboardLayout; import android.hardware.input.IInputDevicesChangedListener; +import android.hardware.input.ITabletModeChangedListener; import android.hardware.input.TouchCalibration; import android.os.IBinder; import android.view.InputDevice; @@ -60,6 +61,9 @@ interface IInputManager { // Registers an input devices changed listener. void registerInputDevicesChangedListener(IInputDevicesChangedListener listener); + // Registers a tablet mode change listener + void registerTabletModeChangedListener(ITabletModeChangedListener listener); + // Input device vibrator control. void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token); void cancelVibrate(int deviceId, IBinder token); diff --git a/core/java/android/hardware/input/ITabletModeChangedListener.aidl b/core/java/android/hardware/input/ITabletModeChangedListener.aidl new file mode 100644 index 0000000..a8559a7 --- /dev/null +++ b/core/java/android/hardware/input/ITabletModeChangedListener.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 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 android.hardware.input; + +/** @hide */ +interface ITabletModeChangedListener { + /* Called when the device enters or exits tablet mode. */ + oneway void onTabletModeChanged(long whenNanos, boolean inTabletMode); +} diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 444f020..a754d6b 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -16,6 +16,7 @@ package android.hardware.input; +import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import android.annotation.SdkConstant; @@ -29,6 +30,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.Vibrator; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -38,6 +40,7 @@ import android.view.InputDevice; import android.view.InputEvent; import java.util.ArrayList; +import java.util.List; /** * Provides information about input devices and available key layouts. @@ -67,6 +70,11 @@ public final class InputManager { private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = new ArrayList<InputDeviceListenerDelegate>(); + // Guarded by mTabletModeLock + private final Object mTabletModeLock = new Object(); + private TabletModeChangedListener mTabletModeChangedListener; + private List<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners; + /** * Broadcast Action: Query available keyboard layouts. * <p> @@ -331,6 +339,72 @@ public final class InputManager { } /** + * Register a tablet mode changed listener. + * + * @param listener The listener to register. + * @param handler The handler on which the listener should be invoked, or null + * if the listener should be invoked on the calling thread's looper. + * @hide + */ + public void registerOnTabletModeChangedListener( + OnTabletModeChangedListener listener, Handler handler) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + synchronized (mTabletModeLock) { + if (mOnTabletModeChangedListeners == null) { + initializeTabletModeListenerLocked(); + } + int idx = findOnTabletModeChangedListenerLocked(listener); + if (idx < 0) { + OnTabletModeChangedListenerDelegate d = + new OnTabletModeChangedListenerDelegate(listener, handler); + mOnTabletModeChangedListeners.add(d); + } + } + } + + /** + * Unregister a tablet mode changed listener. + * + * @param listener The listener to unregister. + * @hide + */ + public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + synchronized (mTabletModeLock) { + int idx = findOnTabletModeChangedListenerLocked(listener); + if (idx >= 0) { + OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx); + d.removeCallbacksAndMessages(null); + } + } + } + + private void initializeTabletModeListenerLocked() { + final TabletModeChangedListener listener = new TabletModeChangedListener(); + try { + mIm.registerTabletModeChangedListener(listener); + } catch (RemoteException ex) { + throw new RuntimeException("Could not register tablet mode changed listener", ex); + } + mTabletModeChangedListener = listener; + mOnTabletModeChangedListeners = new ArrayList<>(); + } + + private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) { + final int N = mOnTabletModeChangedListeners.size(); + for (int i = 0; i < N; i++) { + if (mOnTabletModeChangedListeners.get(i).mListener == listener) { + return i; + } + } + return -1; + } + + /** * Gets information about all supported keyboard layouts. * <p> * The input manager consults the built-in keyboard layouts as well @@ -769,6 +843,22 @@ public final class InputManager { return false; } + + private void onTabletModeChanged(long whenNanos, boolean inTabletMode) { + if (DEBUG) { + Log.d(TAG, "Received tablet mode changed: " + + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode); + } + synchronized (mTabletModeLock) { + final int N = mOnTabletModeChangedListeners.size(); + for (int i = 0; i < N; i++) { + OnTabletModeChangedListenerDelegate listener = + mOnTabletModeChangedListeners.get(i); + listener.sendTabletModeChanged(whenNanos, inTabletMode); + } + } + } + /** * Gets a vibrator service associated with an input device, assuming it has one. * @return The vibrator, never null. @@ -838,6 +928,57 @@ public final class InputManager { } } + /** @hide */ + public interface OnTabletModeChangedListener { + /** + * Called whenever the device goes into or comes out of tablet mode. + * + * @param whenNanos The time at which the device transitioned into or + * out of tablet mode. This is given in nanoseconds in the + * {@link SystemClock#uptimeMillis} time base. + */ + void onTabletModeChanged(long whenNanos, boolean inTabletMode); + } + + private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub { + @Override + public void onTabletModeChanged(long whenNanos, boolean inTabletMode) { + InputManager.this.onTabletModeChanged(whenNanos, inTabletMode); + } + } + + private static final class OnTabletModeChangedListenerDelegate extends Handler { + private static final int MSG_TABLET_MODE_CHANGED = 0; + + public final OnTabletModeChangedListener mListener; + + public OnTabletModeChangedListenerDelegate( + OnTabletModeChangedListener listener, Handler handler) { + super(handler != null ? handler.getLooper() : Looper.myLooper()); + mListener = listener; + } + + public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) { + SomeArgs args = SomeArgs.obtain(); + args.argi1 = (int) (whenNanos & 0xFFFFFFFF); + args.argi2 = (int) (whenNanos >> 32); + args.arg1 = (Boolean) inTabletMode; + obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget(); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_TABLET_MODE_CHANGED: + SomeArgs args = (SomeArgs) msg.obj; + long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32); + boolean inTabletMode = (boolean) args.arg1; + mListener.onTabletModeChanged(whenNanos, inTabletMode); + break; + } + } + } + private final class InputDeviceVibrator extends Vibrator { private final int mDeviceId; private final Binder mToken; |
