Introduce INPUT_CONSUMER permission for InputConsumer

Add the permission protect to createInputConsumer/destoryInputConsumer
in WindowManagerService to prevent it is possible for an app to consume
all the touch events and deny them from even reaching System UI.

Also fix the wallpaper inputconsumer should only show when we found a
visible wallpaper window.

Also limit 'createInputConsumer' to the defined types.

Test: atest PermissionPolicyTest
Test: ceate/destory an inputconsumer and test input
Fix: 162324374
Merged-In: I7a4c2c4cba7ea670873ab2ac49b9880d9a65cd86
Change-Id: I7a4c2c4cba7ea670873ab2ac49b9880d9a65cd86
(cherry picked from commit 0d0ad1b60b)
This commit is contained in:
arthurhung
2020-08-11 23:07:00 +08:00
committed by Arthur Hung
parent f1677fcee5
commit 80951fa9a8
4 changed files with 26 additions and 3 deletions

View File

@@ -5036,6 +5036,10 @@
<permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
android:protectionLevel="signature|appPredictor" />
<!-- @hide Allows an application to create/destroy input consumer. -->
<permission android:name="android.permission.INPUT_CONSUMER"
android:protectionLevel="signature" />
<!-- Attribution for Country Detector. -->
<attribution android:tag="CountryDetector" android:label="@string/country_detector"/>
<!-- Attribution for Location service. -->

View File

@@ -113,6 +113,7 @@
<uses-permission android:name="android.permission.SET_ORIENTATION" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.MONITOR_INPUT" />
<uses-permission android:name="android.permission.INPUT_CONSUMER" />
<!-- DreamManager -->
<uses-permission android:name="android.permission.READ_DREAM_STATE" />

View File

@@ -219,6 +219,11 @@ final class InputMonitor {
WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
InputEventReceiver.Factory inputEventReceiverFactory) {
if (!name.contentEquals(INPUT_CONSUMER_NAVIGATION)) {
throw new IllegalArgumentException("Illegal input consumer : " + name
+ ", display: " + mDisplayId);
}
if (mInputConsumers.containsKey(name)) {
throw new IllegalStateException("Existing input consumer found with name: " + name
+ ", display: " + mDisplayId);
@@ -248,6 +253,11 @@ final class InputMonitor {
// stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
break;
case INPUT_CONSUMER_RECENTS_ANIMATION:
break;
default:
throw new IllegalArgumentException("Illegal input consumer : " + name
+ ", display: " + mDisplayId);
}
addInputConsumer(name, consumer);
}
@@ -459,9 +469,6 @@ final class InputMonitor {
mDisplayContent.forAllWindows(this,
true /* traverseTopToBottom */);
if (mAddWallpaperInputConsumerHandle) {
mWallpaperInputConsumer.show(mInputTransaction, 0);
}
if (!mUpdateInputWindowsImmediately) {
mDisplayContent.getPendingTransaction().merge(mInputTransaction);
mDisplayContent.scheduleAnimation();

View File

@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INPUT_CONSUMER;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -5869,6 +5870,11 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void createInputConsumer(IBinder token, String name, int displayId,
InputChannel inputChannel) {
if (!mAtmInternal.isCallerRecents(Binder.getCallingUid())
&& mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) {
throw new SecurityException("createInputConsumer requires INPUT_CONSUMER permission");
}
synchronized (mGlobalLock) {
DisplayContent display = mRoot.getDisplayContent(displayId);
if (display != null) {
@@ -5880,6 +5886,11 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public boolean destroyInputConsumer(String name, int displayId) {
if (!mAtmInternal.isCallerRecents(Binder.getCallingUid())
&& mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) {
throw new SecurityException("destroyInputConsumer requires INPUT_CONSUMER permission");
}
synchronized (mGlobalLock) {
DisplayContent display = mRoot.getDisplayContent(displayId);
if (display != null) {