Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/input/ITabletModeChangedListener.aidl \ core/java/android/hardware/location/IActivityRecognitionHardware.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \ Loading core/java/android/hardware/input/IInputManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading core/java/android/hardware/input/ITabletModeChangedListener.aidl 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * 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); } core/java/android/hardware/input/InputManager.java +141 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.hardware.input; import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import android.annotation.SdkConstant; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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> Loading Loading @@ -330,6 +338,72 @@ public final class InputManager { return -1; } /** * 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> Loading Loading @@ -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. Loading Loading @@ -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; Loading core/res/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -2054,6 +2054,12 @@ <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" android:protectionLevel="signature" /> <!-- Allows an application to monitor changes in tablet mode. <p>Not for use by third-party applications. @hide --> <permission android:name="android.permission.TABLET_MODE_LISTENER" android:protectionLevel="signature" /> <!-- Allows an application to request installing packages. Apps targeting APIs greater than 22 must hold this permission in order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}. Loading Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/input/ITabletModeChangedListener.aidl \ core/java/android/hardware/location/IActivityRecognitionHardware.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \ Loading
core/java/android/hardware/input/IInputManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
core/java/android/hardware/input/ITabletModeChangedListener.aidl 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * 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); }
core/java/android/hardware/input/InputManager.java +141 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.hardware.input; import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import android.annotation.SdkConstant; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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> Loading Loading @@ -330,6 +338,72 @@ public final class InputManager { return -1; } /** * 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> Loading Loading @@ -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. Loading Loading @@ -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; Loading
core/res/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -2054,6 +2054,12 @@ <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" android:protectionLevel="signature" /> <!-- Allows an application to monitor changes in tablet mode. <p>Not for use by third-party applications. @hide --> <permission android:name="android.permission.TABLET_MODE_LISTENER" android:protectionLevel="signature" /> <!-- Allows an application to request installing packages. Apps targeting APIs greater than 22 must hold this permission in order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}. Loading