مسیریابی ورودی

در اندروید ۹ و پایین‌تر، هیچ راهی برای تعامل با چندین نمایشگر از طریق لمس وجود نداشت، زیرا هیچ مکانیسم ارتباطی بین نمایشگرها و دستگاه‌های ورودی وجود نداشت. به عنوان مثال، یک نمایشگر لمسی می‌توانست یک خروجی ویدیوی HDMI (که به عنوان نمایشگر در اندروید ثبت می‌شود) و یک خروجی USB برای صفحه لمسی (که به عنوان دستگاه ورودی ثبت می‌شود) ارائه دهد. اگر چندین دستگاه به این روش متصل شوند، هیچ راهی برای تعیین اینکه کدام دستگاه ورودی متعلق به کدام نمایشگر است، وجود نخواهد داشت. همین مسئله در مورد دستگاه‌های تاشو با چندین نمایشگر داخلی نیز صدق می‌کند.

اندروید ۱۰ مکانیزمی را اضافه کرده است تا مشخص کند کدام دستگاه‌های ورودی به کدام نمایشگرها تعلق دارند. این ارتباط توسط شماره پورت‌ها انجام می‌شود که در آن پورت به پورت فیزیکی که یک نمایشگر به آن متصل است اشاره دارد.

برای مثال، اگر یک دستگاه اندروید دو پورت HDMI با برچسب‌های hdmi1 و hdmi2 داشته باشد، مقادیر پورت نمایشگر می‌تواند 1 و 2 باشد. مقادیر پورت حتی زمانی که یک نمایشگر متفاوت (مانند یک مدل یا سازنده نمایشگر متفاوت) به همان پورت HDMI فیزیکی متصل شود، یکسان باقی می‌مانند. این امر به تولیدکنندگان دستگاه امکان می‌دهد دستورالعمل‌هایی برای مونتاژ و ارتقاء نمایشگرها ارائه دهند.

این ارتباط در /vendor/etc/input-port-associations.xml پیکربندی شده است. برای مثال:

<ports>
    <port display="0" input="usb-xhci-hcd.0.auto-1.1/input0" />
    <port display="1" input="usb-xhci-hcd.0.auto-1.2/input0" />
</ports>

در مثال بالا، display="0" پورتی را که نمایشگر به آن متصل است مشخص می‌کند. input="usb-xhci-hcd.0.auto-1.1/input0" پورتی را که دستگاه ورودی به آن متصل است مشخص می‌کند. برای تعیین پورت‌های مرتبط با دستگاه‌های خاص، از دستور ترمینال زیر استفاده کنید و سپس ویژگی location آن دستگاه‌ها را در Event Hub State بررسی کنید.

adb shell dumpsys input

اگر دستگاه‌های زیادی متصل هستند، روی یک دستگاه خاص ضربه بزنید تا آرایه RecentQueue را در Input Dispatcher State بررسی کنید. سپس می‌توانید دستگاه‌هایی را که جدیدترین رویداد را ایجاد کرده‌اند شناسایی کنید. سپس می‌توانید دستگاه مربوطه را در Event Hub State پیدا کنید.

برای تعیین پورت‌های نمایش اختصاص داده شده به نمایشگرهای متصل، از adb shell dumpsys display استفاده کنید و سپس برای هر نمایشگر در بخش Display Devices به دنبال ویژگی address DisplayDeviceInfo بگردید. روش دیگر، استفاده از adb shell dumpsys SurfaceFlinger --display-id برای نمایش اطلاعات شناسایی برای همه نمایشگرهای متصل است. همچنین به بخش Static display identifiers مراجعه کنید.

اگر برای یک دستگاه ورودی خاص، ارتباطی مشخص کنید و نمایشگر مربوطه در سیستم وجود نداشته باشد، دستگاه ورودی تا زمانی که نمایشگر مربوطه ظاهر شود، غیرفعال می‌شود. این ارتباط فقط برای دستگاه‌های لمسی انجام می‌شود.

مسیریابی برای نمایشگرهای چندگانه پویا

اندروید ۱۰ به شما امکان می‌دهد دستگاه‌های چند نمایشگره ایستا را راه‌اندازی کنید. ارتباطات پویا هنوز فعال نشده‌اند. با این حال، برخی از موارد استفاده را می‌توان با ارائه اطلاعات مسیریابی برای نمایشگرها و پنل‌های ورودی که همیشه وجود ندارند یا استفاده از دستگاه‌های ورودی مجازی و سپس ارائه اطلاعات مسیریابی اضافی به آن دستگاه‌های مجازی برطرف کرد. اگر پیاده‌سازی دستگاه از موارد زیر پشتیبانی کند:

  • تجربه‌ای شبیه به دسکتاپ با یک داک استیشن، سپس می‌توان یک پیکربندی مسیریابی ارائه داد تا ورودی را از لوازم جانبی ورودی متصل به داک (که به طور منحصر به فرد توسط پورت شناسایی می‌شود) به نمایشگر خارجی (که توسط پورت شناسایی می‌شود) هدایت کند.
  • صفحه نمایش اصلی هنگام اتصال به صفحه نمایش خارجی به عنوان منبع ورودی (مانند صفحه لمسی) عمل می‌کند، سپس می‌توان یک پیکربندی مسیریابی برای هدف قرار دادن ورودی از پنل لمسی مجازی (که با شناسه مجازی منحصر به فرد شناسایی می‌شود) به صفحه نمایش خارجی (که با پورت شناسایی می‌شود) ارائه داد.

پیاده‌سازی

  • برای دستگاه‌های فیزیکی، از پورتی که دستگاه ورودی به آن متصل است و پورتی که نمایشگر به آن متصل است، برای تطبیق نمایشگرها با صفحات لمسی استفاده می‌شود.
  • نگاشت‌ها در InputReaderConfiguration ذخیره می‌شوند.
  • TouchInputMapper.mViewport روی پورتی تنظیم شده است که با پورت مشخص شده برای InputDevice.location مطابقت دارد.
  • اگر یک پورت دستگاه ورودی در فایل نگاشت مشخص شده باشد، و در حال حاضر هیچ پورت نمایشی با پورت نمایش منطبق وجود نداشته باشد، آنگاه دستگاه ورودی روی آن پورت غیرفعال است.
  • اگر پورتی برای یک دستگاه ورودی خاص مشخص نشده باشد، پورت نمایش طبق قوانین موجود تنظیم می‌شود.
  • هیچ تغییر هسته ای در درایورهای ورودی لازم نیست.
  • پورت‌های دستگاه ورودی با استفاده از تابع EVIOCGPHYS ioctl تعیین می‌شوند.