• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server.input;
18 
19 import android.text.TextUtils;
20 import android.util.Slog;
21 import android.util.Xml;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 import com.android.internal.util.XmlUtils;
25 import com.android.modules.utils.TypedXmlPullParser;
26 
27 import java.io.InputStream;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 
33 
34 class ConfigurationProcessor {
35     private static final String TAG = "ConfigurationProcessor";
36 
processExcludedDeviceNames(InputStream xml)37     static List<String> processExcludedDeviceNames(InputStream xml) throws Exception {
38         List<String> names = new ArrayList<>();
39         {
40             TypedXmlPullParser parser = Xml.resolvePullParser(xml);
41             XmlUtils.beginDocument(parser, "devices");
42             while (true) {
43                 XmlUtils.nextElement(parser);
44                 if (!"device".equals(parser.getName())) {
45                     break;
46                 }
47                 String name = parser.getAttributeValue(null, "name");
48                 if (name != null) {
49                     names.add(name);
50                 }
51             }
52         }
53         return names;
54     }
55 
56     /**
57      * Parse the configuration for input port associations.
58      *
59      * Configuration format:
60      * <code>
61      * &lt;ports>
62      *     &lt;port display="0" input="usb-xhci-hcd.0.auto-1.4.3/input0" />
63      *     &lt;port display="1" input="usb-xhci-hcd.0.auto-1.4.2/input0" />
64      * &lt;/ports>
65      * </code>
66      *
67      * In this example, any input device that has physical port of
68      * "usb-xhci-hcd.0.auto-1.4.3/input0" will be associated with a display
69      * that has the physical port "0". If such a display does not exist, the input device
70      * will be disabled and no input events will be dispatched from that input device until a
71      * matching display appears. Likewise, an input device that has port "..1.4.2.." will have
72      * its input events forwarded to a display that has physical port of "1".
73      *
74      * Note: display port must be a numeric value, and this is checked at runtime for validity.
75      * At the same time, it is specified as a string for simplicity.
76      *
77      * Note: do not confuse "display id" with "display port".
78      * The "display port" is the physical port on which the display is connected. This could
79      * be something like HDMI0, HDMI1, etc. For virtual displays, "display port" will be null.
80      * The "display id" is a way to identify a particular display, and is not a stable API.
81      * All displays, including virtual ones, will have a display id.
82      *
83      * Return the pairs of associations. The first item in the pair is the input port,
84      * the second item in the pair is the display port.
85      */
86     @VisibleForTesting
processInputPortAssociations(InputStream xml)87     static Map<String, Integer> processInputPortAssociations(InputStream xml)
88             throws Exception {
89         Map<String, Integer> associations = new HashMap<String, Integer>();
90         {
91             TypedXmlPullParser parser = Xml.resolvePullParser(xml);
92             XmlUtils.beginDocument(parser, "ports");
93 
94             while (true) {
95                 XmlUtils.nextElement(parser);
96                 String entryName = parser.getName();
97                 if (!"port".equals(entryName)) {
98                     break;
99                 }
100                 String inputPort = parser.getAttributeValue(null, "input");
101                 String displayPortStr = parser.getAttributeValue(null, "display");
102                 if (TextUtils.isEmpty(inputPort) || TextUtils.isEmpty(displayPortStr)) {
103                     // This is likely an error by an OEM during device configuration
104                     Slog.wtf(TAG, "Ignoring incomplete entry");
105                     continue;
106                 }
107                 try {
108                     int displayPort = Integer.parseUnsignedInt(displayPortStr);
109                     associations.put(inputPort, displayPort);
110                 } catch (NumberFormatException e) {
111                     Slog.wtf(TAG, "Display port should be an integer");
112                 }
113             }
114         }
115         return associations;
116     }
117 }
118