Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad2a1634 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor static input associations"

parents 1f5d183d cf6070e3
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.input;

import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.Xml;

@@ -29,7 +28,9 @@ import org.xmlpull.v1.XmlPullParser;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


class ConfigurationProcessor {
@@ -86,9 +87,9 @@ class ConfigurationProcessor {
     * the second item in the pair is the display port.
     */
    @VisibleForTesting
    static List<Pair<String, String>> processInputPortAssociations(InputStream xml)
    static Map<String, Integer> processInputPortAssociations(InputStream xml)
            throws Exception {
        List<Pair<String, String>> associations = new ArrayList<>();
        Map<String, Integer> associations = new HashMap<String, Integer>();
        try (InputStreamReader confReader = new InputStreamReader(xml)) {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(confReader);
@@ -101,19 +102,18 @@ class ConfigurationProcessor {
                    break;
                }
                String inputPort = parser.getAttributeValue(null, "input");
                String displayPort = parser.getAttributeValue(null, "display");
                if (TextUtils.isEmpty(inputPort) || TextUtils.isEmpty(displayPort)) {
                String displayPortStr = parser.getAttributeValue(null, "display");
                if (TextUtils.isEmpty(inputPort) || TextUtils.isEmpty(displayPortStr)) {
                    // This is likely an error by an OEM during device configuration
                    Slog.wtf(TAG, "Ignoring incomplete entry");
                    continue;
                }
                try {
                    Integer.parseUnsignedInt(displayPort);
                    int displayPort = Integer.parseUnsignedInt(displayPortStr);
                    associations.put(inputPort, displayPort);
                } catch (NumberFormatException e) {
                    Slog.wtf(TAG, "Display port should be an integer");
                    continue;
                }
                associations.add(new Pair<>(inputPort, displayPort));
            }
        }
        return associations;
+35 −16
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -113,8 +112,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

/*
 * Wraps the C++ InputManager and provides its callbacks.
 */
@@ -184,6 +183,10 @@ public class InputManagerService extends IInputManager.Stub
    IInputFilter mInputFilter; // guarded by mInputFilterLock
    InputFilterHost mInputFilterHost; // guarded by mInputFilterLock

    // The associations of input devices to displays by port. Maps from input device port (String)
    // to display id (int). Currently only accessed by InputReader.
    private final Map<String, Integer> mStaticAssociations;

    private static native long nativeInit(InputManagerService service,
            Context context, MessageQueue messageQueue);
    private static native void nativeStart(long ptr);
@@ -325,6 +328,7 @@ public class InputManagerService extends IInputManager.Stub
        mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
            new File(doubleTouchGestureEnablePath);

        mStaticAssociations = loadStaticInputPortAssociations();
        LocalServices.addService(InputManagerInternal.class, new LocalService());
    }

@@ -1727,6 +1731,17 @@ public class InputManagerService extends IInputManager.Stub
        String dumpStr = nativeDump(mPtr);
        if (dumpStr != null) {
            pw.println(dumpStr);
            dumpAssociations(pw);
        }
    }

    private void dumpAssociations(PrintWriter pw) {
        if (!mStaticAssociations.isEmpty()) {
            pw.println("Static Associations:");
            mStaticAssociations.forEach((k, v) -> {
                pw.print("  port: " + k);
                pw.println("  display: " + v);
            });
        }
    }

@@ -1910,15 +1925,16 @@ public class InputManagerService extends IInputManager.Stub
    }

    /**
     * Flatten a list of pairs into a list, with value positioned directly next to the key
     * Flatten a map into a string list, with value positioned directly next to the
     * key.
     * @return Flattened list
     */
    private static <T> List<T> flatten(@NonNull List<Pair<T, T>> pairs) {
        List<T> list = new ArrayList<>(pairs.size() * 2);
        for (Pair<T, T> pair : pairs) {
            list.add(pair.first);
            list.add(pair.second);
        }
    private static List<String> flatten(@NonNull Map<String, Integer> map) {
        List<String> list = new ArrayList<>(map.size() * 2);
        map.forEach((k, v)-> {
            list.add(k);
            list.add(v.toString());
        });
        return list;
    }

@@ -1926,23 +1942,26 @@ public class InputManagerService extends IInputManager.Stub
     * Ports are highly platform-specific, so only allow these to be specified in the vendor
     * directory.
     */
    // Native callback
    private static String[] getInputPortAssociations() {
    private static Map<String, Integer> loadStaticInputPortAssociations() {
        File baseDir = Environment.getVendorDirectory();
        File confFile = new File(baseDir, PORT_ASSOCIATIONS_PATH);

        try {
            InputStream stream = new FileInputStream(confFile);
            List<Pair<String, String>> associations =
                    ConfigurationProcessor.processInputPortAssociations(stream);
            List<String> associationList = flatten(associations);
            return associationList.toArray(new String[0]);
            return ConfigurationProcessor.processInputPortAssociations(stream);
        } catch (FileNotFoundException e) {
            // Most of the time, file will not exist, which is expected.
        } catch (Exception e) {
            Slog.e(TAG, "Could not parse '" + confFile.getAbsolutePath() + "'", e);
        }
        return new String[0];

        return new HashMap<>();
    }

    // Native callback
    private String[] getInputPortAssociations() {
        List<String> associationList = flatten(mStaticAssociations);
        return associationList.toArray(new String[0]);
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -485,8 +485,8 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
    // Received data: ['inputPort1', '1', 'inputPort2', '2']
    // So we unpack accordingly here.
    outConfig->portAssociations.clear();
    jobjectArray portAssociations = jobjectArray(env->CallStaticObjectMethod(
            gServiceClassInfo.clazz, gServiceClassInfo.getInputPortAssociations));
    jobjectArray portAssociations = jobjectArray(env->CallObjectMethod(mServiceObj,
            gServiceClassInfo.getInputPortAssociations));
    if (!checkAndClearExceptionFromCallback(env, "getInputPortAssociations") && portAssociations) {
        jsize length = env->GetArrayLength(portAssociations);
        for (jsize i = 0; i < length / 2; i++) {
@@ -1920,7 +1920,7 @@ int register_android_server_InputManager(JNIEnv* env) {
    GET_STATIC_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
            "getExcludedDeviceNames", "()[Ljava/lang/String;");

    GET_STATIC_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
    GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
            "getInputPortAssociations", "()[Ljava/lang/String;");

    GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
+5 −7
Original line number Diff line number Diff line
@@ -18,11 +18,9 @@ package com.android.server.input;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.util.Pair;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -32,7 +30,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * Build/Install/Run:
@@ -52,7 +50,7 @@ public class ConfigurationProcessorTest {
    public void testGetInputPortAssociations() {
        final int res = com.android.frameworks.servicestests.R.raw.input_port_associations;
        InputStream xml = mContext.getResources().openRawResource(res);
        List<Pair<String, String>> associations = null;
        Map<String, Integer> associations = null;
        try {
            associations = ConfigurationProcessor.processInputPortAssociations(xml);
        } catch (Exception e) {
@@ -60,8 +58,8 @@ public class ConfigurationProcessorTest {
        }
        assertNotNull(associations);
        assertEquals(2, associations.size());
        assertTrue(associations.contains(Pair.create("USB1", "0")));
        assertTrue(associations.contains(Pair.create("USB2", "1")));
        assertEquals(0, associations.get("USB1").intValue());
        assertEquals(1, associations.get("USB2").intValue());
    }

    @Test
@@ -69,7 +67,7 @@ public class ConfigurationProcessorTest {
        final int res =
                com.android.frameworks.servicestests.R.raw.input_port_associations_bad_displayport;
        InputStream xml = mContext.getResources().openRawResource(res);
        List<Pair<String, String>> associations = null;
        Map<String, Integer> associations = null;
        try {
            associations = ConfigurationProcessor.processInputPortAssociations(xml);
        } catch (Exception e) {