รองรับการแสดงผล

การอัปเดตที่ทำขึ้นในพื้นที่เฉพาะเหล่านี้แสดงไว้ด้านล่าง:

การปรับขนาดกิจกรรมและการแสดงผล

เพื่อระบุว่าแอพอาจไม่รองรับโหมดหลายหน้าต่างหรือการปรับขนาด กิจกรรมใช้แอตทริบิวต์ resizeableActivity=false ปัญหาทั่วไปที่แอปพบเมื่อมีการปรับขนาดกิจกรรม ได้แก่:

  • กิจกรรมสามารถมีการกำหนดค่าที่แตกต่างจากแอพหรือส่วนประกอบอื่นที่ไม่ใช่ภาพ ข้อผิดพลาดทั่วไปคือการอ่านเมตริกการแสดงผลจากบริบทของแอป ค่าที่ส่งคืนจะไม่ถูกปรับเป็นเมตริกพื้นที่ที่มองเห็นได้ซึ่งมีการแสดงกิจกรรม
  • กิจกรรมไม่สามารถจัดการการปรับขนาดและข้อขัดข้อง แสดง UI ที่บิดเบี้ยว หรือสูญเสียสถานะเนื่องจากเปิดใหม่โดยไม่บันทึกสถานะอินสแตนซ์
  • แอปอาจพยายามใช้พิกัดอินพุตแบบสัมบูรณ์ (แทนที่จะเป็นพิกัดที่สัมพันธ์กับตำแหน่งหน้าต่าง) ซึ่งอาจทำให้อินพุตเสียหายในหลายหน้าต่าง

ใน Android 7 (และสูงกว่า) แอปสามารถตั้งค่า resizeableActivity=false ให้ทำงานในโหมดเต็มหน้าจอเสมอ ในกรณีนี้ แพลตฟอร์มจะป้องกันไม่ให้กิจกรรมที่ไม่สามารถปรับขนาดได้แยกออกเป็นหน้าจอแยก หากผู้ใช้พยายามเรียกใช้กิจกรรมที่ไม่สามารถปรับขนาดได้จากตัวเรียกใช้งานในขณะที่อยู่ในโหมดแยกหน้าจอ แพลตฟอร์มจะออกจากโหมดแยกหน้าจอและเปิดกิจกรรมที่ไม่สามารถปรับขนาดได้ในโหมดเต็มหน้าจอ

แอปที่ตั้งค่าแอตทริบิวต์นี้ false อย่างชัดแจ้งในไฟล์ Manifest จะต้องไม่เปิดในโหมดหลายหน้าต่าง เว้นแต่ว่าจะใช้โหมดความเข้ากันได้:

  • การกำหนดค่าเดียวกันกับกระบวนการ ซึ่งประกอบด้วยกิจกรรมและส่วนประกอบที่ไม่ใช่กิจกรรมทั้งหมด
  • การกำหนดค่าที่ใช้เป็นไปตามข้อกำหนด CDD สำหรับจอแสดงผลที่เข้ากันได้กับแอป

ใน Android 10 แพลตฟอร์มยังคงป้องกันไม่ให้กิจกรรมที่ไม่สามารถปรับขนาดได้เข้าสู่โหมดแยกหน้าจอ แต่สามารถปรับขนาดได้ชั่วคราวหากกิจกรรมได้ประกาศการวางแนวคงที่หรืออัตราส่วนกว้างยาว หากไม่เป็นเช่นนั้น กิจกรรมจะปรับขนาดให้เต็มหน้าจอเหมือนใน Android 9 และต่ำกว่า

การใช้งานเริ่มต้นใช้นโยบายต่อไปนี้:

เมื่อกิจกรรมที่ประกาศว่าเข้ากันไม่ได้กับหลายหน้าต่างโดยใช้แอตทริบิวต์ android:resizeableActivity และเมื่อกิจกรรมนั้นตรงตามเงื่อนไขที่อธิบายไว้ด้านล่าง เมื่อต้องเปลี่ยนการกำหนดค่าหน้าจอที่ใช้ กิจกรรมและกระบวนการจะถูกบันทึกด้วยการกำหนดค่าดั้งเดิม และผู้ใช้จะได้รับเงินในการเปิดใช้งานกระบวนการแอปอีกครั้งเพื่อใช้การกำหนดค่าหน้าจอที่อัปเดต

  • เป็นการวางแนวคงที่ผ่านแอปพลิเคชันของ android:screenOrientation
  • แอปมีอัตราส่วนกว้างยาวสูงสุดหรือต่ำสุดเริ่มต้นโดยกำหนดเป้าหมายระดับ API หรือประกาศอัตราส่วนอย่างชัดเจน

รูปนี้แสดงกิจกรรมที่ไม่สามารถปรับขนาดได้โดยมีอัตราส่วนกว้างยาวที่ประกาศไว้ เมื่อพับอุปกรณ์ หน้าต่างจะถูกลดขนาดลงเพื่อให้พอดีกับพื้นที่โดยคงอัตราส่วนกว้างยาวไว้โดยใช้แถบดำแถบดำที่เหมาะสม นอกจากนี้ ผู้ใช้จะมีตัวเลือกกิจกรรมการรีสตาร์ททุกครั้งที่เปลี่ยนพื้นที่แสดงผลสำหรับกิจกรรม

เมื่อกางอุปกรณ์ การกำหนดค่า ขนาด และอัตราส่วนภาพของกิจกรรมจะไม่เปลี่ยนแปลง แต่ตัวเลือกในการเริ่มกิจกรรมใหม่จะแสดงขึ้น

เมื่อไม่ได้ตั้งค่า resizeableActivity (หรือตั้งค่า true ) แอปจะรองรับการปรับขนาดอย่างสมบูรณ์

การดำเนินการ

กิจกรรมที่ไม่สามารถปรับขนาดได้โดยมีการวางแนวคงที่หรืออัตราส่วนกว้างยาวเรียกว่าโหมดความเข้ากันได้ของขนาด (SCM) ในโค้ด เงื่อนไขถูกกำหนดใน ActivityRecord#shouldUseSizeCompatMode() เมื่อเปิดใช้งานกิจกรรม SCM การกำหนดค่าที่เกี่ยวข้องกับหน้าจอ (เช่น ขนาดหรือความหนาแน่น) จะได้รับการแก้ไขในการกำหนดค่าการแทนที่ที่ร้องขอ ดังนั้นกิจกรรมจะไม่ขึ้นอยู่กับการกำหนดค่าการแสดงผลปัจจุบันอีกต่อไป

หากกิจกรรม SCM ไม่สามารถเต็มหน้าจอได้ แสดงว่ามีการจัดตำแหน่งด้านบนและจัดกึ่งกลางในแนวนอน ขอบเขตของกิจกรรมคำนวณโดย AppWindowToken#calculateCompatBoundsTransformation()

เมื่อกิจกรรม SCM ใช้การกำหนดค่าหน้าจอที่แตกต่างจากคอนเทนเนอร์ (เช่น จอภาพถูกปรับขนาด หรือกิจกรรมถูกย้ายไปยังจอภาพอื่น) ActivityRecord#inSizeCompatMode() จะเป็น true และ SizeCompatModeActivityController (ใน UI ของระบบ) จะได้รับการเรียกกลับเพื่อแสดงกระบวนการ ปุ่มรีสตาร์ท

ขนาดจอแสดงผลและอัตราส่วนภาพ

Android 10 รองรับอัตราส่วนกว้างยาวใหม่ตั้งแต่อัตราส่วนหน้าจอยาวและบางไปจนถึงอัตราส่วน 1:1 แอปสามารถกำหนด ApplicationInfo#maxAspectRatio และ ApplicationInfo#minAspectRatio ของหน้าจอที่จัดการได้

อัตราส่วนแอปใน Android 10

รูปที่ 1. ตัวอย่างอัตราส่วนแอพที่รองรับใน Android 10

การใช้งานอุปกรณ์สามารถมีจอแสดงผลรองที่มีขนาดและความละเอียดที่เล็กกว่าที่กำหนดโดย Android 9 และต่ำกว่า (ความกว้างหรือความสูงขั้นต่ำ 2.5 นิ้วหรือความสูงขั้นต่ำ 320 DP สำหรับ smallestScreenWidth ) แต่เฉพาะกิจกรรมที่เลือกใช้เพื่อรองรับจอแสดงผลขนาดเล็กเหล่านี้เท่านั้น วางไว้ที่นั่น

แอปสามารถเลือกได้โดยการประกาศขนาดขั้นต่ำที่รองรับซึ่งเล็กกว่า oe เท่ากับขนาดการแสดงผลเป้าหมาย ใช้แอตทริบิวต์เค้าโครงกิจกรรม android:minHeight และ android:minWidth ใน AndroidManifest เพื่อดำเนินการดังกล่าว

นโยบายการแสดงผล

Android 10 แยกและย้ายนโยบายการแสดงผลบางอย่างจากการใช้งาน WindowManagerPolicy เริ่มต้นใน PhoneWindowManager ไปยังคลาสต่อการแสดงผล เช่น:

  • แสดงสถานะและการหมุน
  • คีย์บางตัวและการติดตามเหตุการณ์การเคลื่อนไหว
  • UI ของระบบและหน้าต่างตกแต่ง

ใน Android 9 (และต่ำกว่า) คลาส PhoneWindowManager จัดการนโยบายการแสดงผล สถานะและการตั้งค่า การหมุน การติดตามกรอบหน้าต่างการตกแต่ง และอื่นๆ Android 10 ย้ายสิ่งนี้ส่วนใหญ่ไปยังคลาส DisplayPolicy ยกเว้นการติดตามการหมุนซึ่งถูกย้ายไปที่ DisplayRotation

การตั้งค่าหน้าต่างแสดงผล

ใน Android 10 ได้มีการขยายการตั้งค่าหน้าต่างสำหรับแต่ละการแสดงผลที่กำหนดค่าได้เพื่อรวม:

  • โหมดหน้าต่างแสดงผลเริ่มต้น
  • ค่าโอเวอร์สแกน
  • โหมดการหมุนและการหมุนของผู้ใช้
  • ขนาดบังคับ ความหนาแน่น และโหมดมาตราส่วน
  • โหมดการลบเนื้อหา (เมื่อนำจอแสดงผลออก)
  • รองรับการตกแต่งระบบและ IME

คลาส DisplayWindowSettings มีการตั้งค่าสำหรับตัวเลือกเหล่านี้ โดยจะคงอยู่ในดิสก์ในพาร์ติชั่น /data ใน display_settings.xml ทุกครั้งที่มีการเปลี่ยนแปลงการตั้งค่า สำหรับรายละเอียด โปรดดู DisplayWindowSettings.AtomicFileStorage และ DisplayWindowSettings#writeSettings() ผู้ผลิตอุปกรณ์สามารถระบุค่าเริ่มต้นใน display_settings.xml สำหรับการกำหนดค่าอุปกรณ์ อย่างไรก็ตาม เนื่องจากไฟล์ถูกเก็บไว้ใน /data อาจจำเป็นต้องใช้ตรรกะเพิ่มเติมในการกู้คืนไฟล์หากลบโดยการเช็ด

ตามค่าเริ่มต้น Android 10 จะใช้ DisplayInfo#uniqueId เป็นตัวระบุสำหรับการแสดงผลเมื่อคงการตั้งค่าไว้ uniqueId มีการระบุรหัสเฉพาะสำหรับจอแสดงผลทั้งหมด นอกจากนี้ยังมีความเสถียรสำหรับการแสดงผลทางกายภาพและเครือข่าย นอกจากนี้ยังสามารถใช้พอร์ตของจอแสดงผลจริงเป็นตัวระบุ ซึ่งสามารถตั้งค่าได้ใน DisplayWindowSettings#mIdentifier ในการเขียนแต่ละครั้ง การตั้งค่าทั้งหมดจะถูกเขียนขึ้น ดังนั้นจึงปลอดภัยที่จะอัปเดตคีย์ที่ใช้สำหรับรายการแสดงผลในที่จัดเก็บ สำหรับรายละเอียด โปรดดู ตัวระบุการแสดงผลแบบคง ที่

การตั้งค่าจะคงอยู่ในไดเร็กทอรี /data ด้วยเหตุผลทางประวัติศาสตร์ ในขั้นต้น ใช้เพื่อคงการตั้งค่าที่ผู้ใช้กำหนดไว้ เช่น การหมุนหน้าจอ

ตัวระบุการแสดงผลแบบคงที่

Android 9 (และต่ำกว่า) ไม่มีตัวระบุที่เสถียรสำหรับการแสดงผลในเฟรมเวิร์ก เมื่อมีการเพิ่มการแสดงผลในระบบ Display#mDisplayId หรือ DisplayInfo#displayId จะถูกสร้างขึ้นสำหรับการแสดงผลนั้นโดยการเพิ่มตัวนับแบบคงที่ หากระบบเพิ่มและลบจอแสดงผลเดียวกัน แสดงว่า ID ต่างกัน

หากอุปกรณ์มีจอแสดงผลหลายจอตั้งแต่เปิดเครื่อง จอภาพสามารถกำหนดตัวระบุที่แตกต่างกันได้ ขึ้นอยู่กับเวลา แม้ว่า Android 9 (และรุ่นก่อนหน้า) จะรวม DisplayInfo#uniqueId แต่ก็ไม่มีข้อมูลเพียงพอที่จะแยกความแตกต่างระหว่างจอแสดงผล เนื่องจากจอแสดงผลจริงถูกระบุว่าเป็น local:0 หรือ local:1 เพื่อแสดงถึงจอแสดงผลในตัวและภายนอก

Android 10 เปลี่ยน DisplayInfo#uniqueId เพื่อเพิ่มตัวระบุที่เสถียรและเพื่อแยกความแตกต่างระหว่างจอแสดงผลในเครื่อง เครือข่าย และเสมือน

ประเภทการแสดงผล รูปแบบ
ท้องถิ่น
local:<stable-id>
เครือข่าย
network:<mac-address>
เสมือน
virtual:<package-name-and-name>

นอกเหนือจากการอัปเดต uniqueId แล้ว DisplayInfo.address มี DisplayAddress ซึ่งเป็นตัวระบุการแสดงผลที่เสถียรเมื่อรีบูต ใน Android 10 DisplayAddress รองรับการแสดงผลจริงและเครือข่าย DisplayAddress.Physical มี ID การแสดงผลที่เสถียร (เหมือนกับใน uniqueId ) และสามารถสร้างได้ด้วย DisplayAddress#fromPhysicalDisplayId()

Android 10 ยังมีวิธีที่สะดวกในการรับข้อมูลพอร์ต ( Physical#getPort() ) สามารถใช้วิธีนี้ในกรอบงานเพื่อระบุการแสดงผลแบบคงที่ ตัวอย่างเช่น ใช้ใน DisplayWindowSettings ) DisplayAddress.Network มีที่อยู่ MAC และสามารถสร้างได้ด้วย DisplayAddress#fromMacAddress()

การเพิ่มเติมเหล่านี้ช่วยให้ผู้ผลิตอุปกรณ์ระบุการแสดงผลในการตั้งค่าการแสดงผลหลายจอแบบคงที่ และกำหนดค่าการตั้งค่าระบบและคุณสมบัติต่างๆ โดยใช้ตัวระบุการแสดงผลแบบคงที่ เช่น พอร์ตสำหรับจอแสดงผลจริง เมธอดเหล่านี้ถูกซ่อนไว้และมีจุดประสงค์เพื่อใช้ภายใน system_server เท่านั้น

ด้วย ID การแสดงผล HWC (ซึ่งสามารถทึบและไม่เสถียรตลอดเวลา) วิธีการนี้จะส่งคืนหมายเลขพอร์ต 8 บิต (เฉพาะแพลตฟอร์ม) ที่ระบุตัวเชื่อมต่อทางกายภาพสำหรับเอาต์พุตการแสดงผล รวมถึง EDID blob ของจอแสดงผล SurfaceFlinger ดึงข้อมูลผู้ผลิตหรือรุ่นออกจาก EDID เพื่อสร้าง ID การแสดงผล 64 บิตที่เสถียรซึ่งเปิดเผยต่อเฟรมเวิร์ก หากวิธีนี้ไม่ได้รับการสนับสนุนหรือเกิดข้อผิดพลาด SurfaceFlinger จะกลับไปใช้โหมด MD ดั้งเดิม โดยที่ DisplayInfo#address เป็นโมฆะ และ DisplayInfo#uniqueId ถูกฮาร์ดโค้ดตามที่อธิบายไว้ข้างต้น

หากต้องการตรวจสอบว่าคุณลักษณะนี้ได้รับการสนับสนุน ให้เรียกใช้:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

ใช้จอแสดงผลมากกว่าสองจอ

ใน Android 9 (และต่ำกว่า) SurfaceFlinger และ DisplayManagerService ถือว่ามีจอแสดงผลจริงอย่างน้อย 2 จอที่มีรหัสฮาร์ดโค้ด 0 และ 1

เริ่มต้นด้วย Android 10 SurfaceFlinger สามารถใช้ประโยชน์จาก Hardware Composer (HWC) API เพื่อสร้าง ID การแสดงผลที่เสถียร ซึ่งช่วยให้สามารถจัดการจำนวนการแสดงผลทางกายภาพได้ตามอำเภอใจ หากต้องการเรียนรู้เพิ่มเติม โปรดดูที่ ตัวระบุการแสดงผลแบบคง ที่

กรอบงานสามารถค้นหาโทเค็น IBinder สำหรับการแสดงผลจริงผ่าน SurfaceControl#getPhysicalDisplayToken หลังจากได้รับ ID การแสดงผล 64 บิตจาก SurfaceControl#getPhysicalDisplayIds หรือจากเหตุการณ์ Hotplug ของ DisplayEventReceiver

ใน Android 10 (และต่ำกว่า) จอแสดงผลภายในหลักคือ TYPE_INTERNAL และจอแสดงผลรองทั้งหมดจะถูกตั้งค่าสถานะเป็น TYPE_EXTERNAL โดยไม่คำนึงถึงประเภทการเชื่อมต่อ ดังนั้น จอแสดงผลภายในเพิ่มเติมจะถือว่าเป็นภายนอก ในการแก้ปัญหาชั่วคราว โค้ดเฉพาะอุปกรณ์สามารถตั้งสมมติฐานเกี่ยวกับ DisplayAddress.Physical#getPort หากทราบ HWC และสามารถคาดการณ์ตรรกะการจัดสรรพอร์ตได้

ข้อจำกัดนี้จะถูกลบออกใน Android 11 (และสูงกว่า)

  • ใน Android 11 จอแสดงผลแรกที่รายงานระหว่างการบู๊ตคือจอแสดงผลหลัก ประเภทการเชื่อมต่อ (ภายในและภายนอก) ไม่เกี่ยวข้อง อย่างไรก็ตาม ยังคงเป็นความจริงที่ว่าจอแสดงผลหลักไม่สามารถตัดการเชื่อมต่อได้ และตามมาด้วยว่าจะต้องเป็นจอแสดงผลภายในในทางปฏิบัติ โปรดทราบว่าโทรศัพท์แบบพับได้บางรุ่นมีจอแสดงผลภายในหลายจอ
  • Display.TYPE_INTERNAL หรือ Display.TYPE_EXTERNAL (เดิมชื่อ Display.TYPE_BUILT_IN และ Display.TYPE_HDMI ตามลำดับ) ขึ้นอยู่กับประเภทการเชื่อมต่อ

การดำเนินการ

ใน Android 9 และต่ำกว่า จอแสดงผลจะถูกระบุด้วยรหัส 32 บิต โดยที่ 0 คือจอแสดงผลภายใน 1 คือจอแสดงผลภายนอก [2, INT32_MAX] คือจอแสดงผลเสมือน HWC และ -1 หมายถึงจอแสดงผลที่ไม่ถูกต้องหรือไม่ใช่ HWC จอแสดงผลเสมือน

ตั้งแต่ Android 10 เป็นต้นไป จอแสดงผลจะได้รับ ID ที่เสถียรและคงอยู่ ซึ่งช่วยให้ SurfaceFlinger และ DisplayManagerService ติดตามจอแสดงผลมากกว่าสองจอและจดจำจอแสดงผลที่เคยเห็นก่อนหน้านี้ หาก HWC รองรับ IComposerClient.getDisplayIdentificationData และให้ข้อมูลการระบุจอแสดงผล SurfaceFlinger จะแยกวิเคราะห์โครงสร้าง EDID และจัดสรร ID การแสดงผล 64 บิตที่เสถียรสำหรับจอแสดงผลจริงและ HWC เสมือน รหัสถูกแสดงโดยใช้ประเภทตัวเลือก โดยที่ค่า Null แสดงถึงการแสดงผลที่ไม่ถูกต้องหรือการแสดงผลเสมือนที่ไม่ใช่ HWC หากไม่ได้รับการสนับสนุน HWC SurfaceFlinger จะกลับไปใช้การทำงานแบบเดิมที่มีจอแสดงผลจริงไม่เกินสองจอ

โฟกัสต่อการแสดงผล

เพื่อรองรับแหล่งอินพุตหลายแหล่งที่กำหนดเป้าหมายการแสดงผลแต่ละรายการพร้อมกัน คุณสามารถกำหนดค่า Android 10 ให้สนับสนุนหน้าต่างที่โฟกัสหลายหน้าต่าง ได้มากสุดหนึ่งรายการต่อจอแสดงผล ซึ่งมีไว้สำหรับอุปกรณ์ประเภทพิเศษเท่านั้นเมื่อผู้ใช้หลายคนโต้ตอบกับอุปกรณ์เดียวกันพร้อมกันและใช้วิธีป้อนข้อมูลหรืออุปกรณ์ต่างกัน เช่น Android Automotive

ขอแนะนำเป็นอย่างยิ่งว่า ไม่ ควรเปิดใช้งานคุณลักษณะนี้สำหรับอุปกรณ์ทั่วไป รวมถึงอุปกรณ์ที่มีหลายหน้าจอหรืออุปกรณ์ที่ใช้สำหรับประสบการณ์เหมือนเดสก์ท็อป สาเหตุหลักมาจากข้อกังวลด้านความปลอดภัยที่อาจทำให้ผู้ใช้สงสัยว่าหน้าต่างใดมีโฟกัสอินพุต

ลองนึกภาพผู้ใช้ที่ป้อนข้อมูลที่ปลอดภัยลงในช่องป้อนข้อความ อาจลงชื่อเข้าใช้แอปธนาคารหรือป้อนข้อความที่มีข้อมูลที่ละเอียดอ่อน แอพที่เป็นอันตรายสามารถสร้างการแสดงผลนอกหน้าจอเสมือนเพื่อดำเนินกิจกรรมรวมถึงฟิลด์ป้อนข้อความ กิจกรรมที่ถูกกฎหมายและมุ่งร้ายมีจุดเน้น และทั้งคู่แสดงตัวบ่งชี้การป้อนข้อมูลที่ใช้งานอยู่ (เคอร์เซอร์กะพริบ)

อย่างไรก็ตาม เนื่องจากการป้อนข้อมูลจากแป้นพิมพ์ (ฮาร์ดแวร์หรือซอฟต์แวร์) ถูกป้อนลงในกิจกรรมระดับบนสุดเท่านั้น (แอปนั้นที่เพิ่งเปิดตัวล่าสุด) โดยการสร้างการแสดงผลเสมือนที่ซ่อนอยู่ แอปที่เป็นอันตรายอาจดึงข้อมูลของผู้ใช้ได้ แม้กระทั่งเมื่อใช้แป้นพิมพ์ซอฟต์แวร์ บนจอแสดงผลของอุปกรณ์หลัก

ใช้ com.android.internal.R.bool.config_perDisplayFocusEnabled เพื่อตั้งค่าโฟกัสต่อการแสดงผล

ความเข้ากันได้

ปัญหา: ใน Android 9 และต่ำกว่า อย่างน้อยหนึ่งหน้าต่างในระบบมีการโฟกัสในแต่ละครั้ง

วิธีแก้ไข: ในบางกรณีซึ่งเกิดขึ้นได้ยากเมื่อโฟกัสหน้าต่างสองบานจากกระบวนการเดียวกัน ระบบจะให้โฟกัสเฉพาะหน้าต่างที่อยู่สูงกว่าในลำดับ Z ข้อจำกัดนี้จะถูกลบออกสำหรับแอปที่กำหนดเป้าหมายเป็น Android 10 ซึ่ง ณ จุดนี้คาดว่าจะสามารถรองรับหลายหน้าต่างที่เน้นพร้อมกันได้

การดำเนินการ

WindowManagerService#mPerDisplayFocusEnabled ควบคุมความพร้อมใช้งานของคุณลักษณะนี้ ใน ActivityManager ตอนนี้ ActivityDisplay#getFocusedStack() ถูกใช้แทนการติดตามส่วนกลางในตัวแปร ActivityDisplay#getFocusedStack() กำหนดโฟกัสตามลำดับ Z แทนการแคชค่า เพื่อให้มีเพียงแหล่งเดียวคือ WindowManager ที่ต้องการติดตามลำดับ Z ของกิจกรรม

ActivityStackSupervisor#getTopDisplayFocusedStack() ใช้แนวทางที่คล้ายกันสำหรับกรณีเหล่านั้นเมื่อต้องระบุสแต็กที่โฟกัสบนสุดในระบบ กองจะถูกสำรวจจากบนลงล่าง ค้นหากองแรกที่มีสิทธิ์

InputDispatcher สามารถมีหน้าต่างที่โฟกัสได้หลายหน้าต่าง (หนึ่งหน้าต่างต่อจอแสดงผล) หากเหตุการณ์อินพุตเป็นแบบเฉพาะสำหรับการแสดงผล เหตุการณ์นั้นจะถูกส่งไปยังหน้าต่างที่โฟกัสในจอแสดงผลที่เกี่ยวข้อง มิฉะนั้น จะถูกส่งไปยังหน้าต่างที่โฟกัสในจอแสดงผลที่โฟกัส ซึ่งเป็นจอแสดงผลที่ผู้ใช้โต้ตอบด้วยล่าสุด

ดู InputDispatcher::mFocusedWindowHandlesByDisplay และ InputDispatcher::setFocusedDisplay() แอปที่โฟกัสจะได้รับการอัปเดตแยกต่างหากใน InputManagerService ผ่าน NativeInputManager::setFocusedApplication()

ใน WindowManager หน้าต่างที่โฟกัสจะถูกติดตามแยกกันด้วย ดู DisplayContent#mCurrentFocus และ DisplayContent#mFocusedApp และการใช้งานที่เกี่ยวข้อง วิธีการติดตามโฟกัสและการอัปเดตที่เกี่ยวข้องได้ถูกย้ายจาก WindowManagerService ไปยัง DisplayContent