blob: 3888b1b71096789f91101c8efc6fb9b277512bc3 [file] [log] [blame]
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -07001/*
2 * Copyright (C) 2018 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
17package com.android.server.input;
18
19import android.text.TextUtils;
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -070020import android.util.Slog;
21import android.util.Xml;
22
23import com.android.internal.annotations.VisibleForTesting;
24import com.android.internal.util.XmlUtils;
25
26import org.xmlpull.v1.XmlPullParser;
27
28import java.io.InputStream;
29import java.io.InputStreamReader;
30import java.util.ArrayList;
Arthur Hungcf6070e2019-12-04 16:09:42 +080031import java.util.HashMap;
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -070032import java.util.List;
Arthur Hungcf6070e2019-12-04 16:09:42 +080033import java.util.Map;
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -070034
35
36class ConfigurationProcessor {
37 private static final String TAG = "ConfigurationProcessor";
38
39 static List<String> processExcludedDeviceNames(InputStream xml) throws Exception {
40 List<String> names = new ArrayList<>();
41 try (InputStreamReader confReader = new InputStreamReader(xml)) {
42 XmlPullParser parser = Xml.newPullParser();
43 parser.setInput(confReader);
44 XmlUtils.beginDocument(parser, "devices");
45 while (true) {
46 XmlUtils.nextElement(parser);
47 if (!"device".equals(parser.getName())) {
48 break;
49 }
50 String name = parser.getAttributeValue(null, "name");
51 if (name != null) {
52 names.add(name);
53 }
54 }
55 }
56 return names;
57 }
58
59 /**
60 * Parse the configuration for input port associations.
61 *
62 * Configuration format:
63 * <code>
64 * &lt;ports>
65 * &lt;port display="0" input="usb-xhci-hcd.0.auto-1.4.3/input0" />
66 * &lt;port display="1" input="usb-xhci-hcd.0.auto-1.4.2/input0" />
67 * &lt;/ports>
68 * </code>
69 *
70 * In this example, any input device that has physical port of
71 * "usb-xhci-hcd.0.auto-1.4.3/input0" will be associated with a display
72 * that has the physical port "0". If such a display does not exist, the input device
73 * will be disabled and no input events will be dispatched from that input device until a
74 * matching display appears. Likewise, an input device that has port "..1.4.2.." will have
75 * its input events forwarded to a display that has physical port of "1".
76 *
77 * Note: display port must be a numeric value, and this is checked at runtime for validity.
78 * At the same time, it is specified as a string for simplicity.
79 *
80 * Note: do not confuse "display id" with "display port".
81 * The "display port" is the physical port on which the display is connected. This could
82 * be something like HDMI0, HDMI1, etc. For virtual displays, "display port" will be null.
83 * The "display id" is a way to identify a particular display, and is not a stable API.
84 * All displays, including virtual ones, will have a display id.
85 *
86 * Return the pairs of associations. The first item in the pair is the input port,
87 * the second item in the pair is the display port.
88 */
89 @VisibleForTesting
Arthur Hungcf6070e2019-12-04 16:09:42 +080090 static Map<String, Integer> processInputPortAssociations(InputStream xml)
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -070091 throws Exception {
Arthur Hungcf6070e2019-12-04 16:09:42 +080092 Map<String, Integer> associations = new HashMap<String, Integer>();
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -070093 try (InputStreamReader confReader = new InputStreamReader(xml)) {
94 XmlPullParser parser = Xml.newPullParser();
95 parser.setInput(confReader);
96 XmlUtils.beginDocument(parser, "ports");
97
98 while (true) {
99 XmlUtils.nextElement(parser);
100 String entryName = parser.getName();
101 if (!"port".equals(entryName)) {
102 break;
103 }
104 String inputPort = parser.getAttributeValue(null, "input");
Arthur Hungcf6070e2019-12-04 16:09:42 +0800105 String displayPortStr = parser.getAttributeValue(null, "display");
106 if (TextUtils.isEmpty(inputPort) || TextUtils.isEmpty(displayPortStr)) {
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -0700107 // This is likely an error by an OEM during device configuration
108 Slog.wtf(TAG, "Ignoring incomplete entry");
109 continue;
110 }
111 try {
Arthur Hungcf6070e2019-12-04 16:09:42 +0800112 int displayPort = Integer.parseUnsignedInt(displayPortStr);
113 associations.put(inputPort, displayPort);
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -0700114 } catch (NumberFormatException e) {
115 Slog.wtf(TAG, "Display port should be an integer");
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -0700116 }
Siarhei Vishniakou15a412d2018-10-04 19:01:04 -0700117 }
118 }
119 return associations;
120 }
121}