รองรับการตกแต่งระบบ

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

ตกแต่งระบบ

Android 10 เพิ่มการรองรับการกำหนดค่าจอแสดงผลรองเพื่อแสดงการตกแต่งระบบบางอย่าง เช่น วอลเปเปอร์ แถบนำทาง และ Launcher ตามค่าเริ่มต้น จอแสดงผลหลักจะแสดงการตกแต่งระบบทั้งหมด และจอแสดงผลรองจะแสดงการตกแต่งที่เลือกได้ การสนับสนุนตัวแก้ไขวิธีการป้อนข้อมูล (IME) สามารถตั้งค่าแยกต่างหากจากการตกแต่งระบบอื่นๆ

ใช้ DisplayWindowSettings#setShouldShowSystemDecorsLocked() เพื่อเพิ่มการสนับสนุนสำหรับการตกแต่งระบบบนจอแสดงผลเฉพาะหรือระบุค่าเริ่มต้นใน /data/system/display_settings.xml ตัวอย่างเช่น โปรดดู การตั้งค่าหน้าต่างการแสดงผล

การนำไปปฏิบัติ

DisplayWindowSettings#setShouldShowSystemDecorsLocked() ยังถูกเปิดเผยใน WindowManager#setShouldShowSystemDecors() สำหรับการทดสอบอีกด้วย การเรียกใช้วิธีนี้โดยมีเจตนาที่จะเปิดใช้งานการตกแต่งระบบจะไม่เพิ่มหน้าต่างการตกแต่งที่หายไปก่อนหน้านี้ หรือลบออกหากก่อนหน้านี้มีอยู่ ในกรณีส่วนใหญ่ การเปลี่ยนแปลงการสนับสนุนการตกแต่งระบบจะมีผลสมบูรณ์หลังจากการรีบูตอุปกรณ์เท่านั้น

การตรวจสอบการสนับสนุนการตกแต่งระบบในฐานโค้ด WindowManager มักจะดำเนินการผ่าน DisplayContent#supportsSystemDecorations() ในขณะที่ตรวจสอบบริการภายนอก (เช่น System UI เพื่อตรวจสอบว่าควรแสดงแถบนำทางหรือไม่) ให้ใช้ WindowManager#shouldShowSystemDecors() เพื่อทำความเข้าใจสิ่งที่ควบคุมโดยการตั้งค่านี้ ให้สำรวจจุดโทรของวิธีการเหล่านี้

หน้าต่างตกแต่ง UI ของระบบ

Android 10 เพิ่มการรองรับหน้าต่างตกแต่งระบบสำหรับแถบนำทาง เท่านั้น เนื่องจากแถบนำทางจำเป็นสำหรับการนำทางระหว่างกิจกรรมและแอพ ตามค่าเริ่มต้น แถบนำทางจะแสดงค่า Back และ Home ซึ่งจะรวมไว้เฉพาะในกรณีที่จอแสดงผลเป้าหมายรองรับการตกแต่งระบบ (ดู DisplayWindowSettings )

แถบสถานะ เป็นหน้าต่างระบบที่ซับซ้อนกว่า เนื่องจากมีแถบการแจ้งเตือน การตั้งค่าด่วน และหน้าจอล็อคด้วย ใน Android 10 ไม่รองรับแถบสถานะบนจอแสดงผลรอง ดังนั้นการแจ้งเตือน การตั้งค่า และการป้องกันปุ่มแบบเต็มจึงใช้งานได้บนจอแสดงผลหลักเท่านั้น

ไม่รองรับหน้าต่างระบบ ภาพรวม/ล่าสุด บนหน้าจอรอง ใน Android 10 AOSP จะแสดงเฉพาะล่าสุดบนจอแสดงผลเริ่มต้นและมีกิจกรรมจากจอแสดงผลทั้งหมด เมื่อเปิดใช้งานจากล่าสุด กิจกรรมที่อยู่บนจอแสดงผลรองจะถูกนำมาที่ด้านหน้าของจอแสดงผลนั้นตามค่าเริ่มต้น วิธีการนี้มีปัญหาที่ทราบบางประการ เช่น การไม่อัปเดตทันทีเมื่อแอปปรากฏบนหน้าจออื่น

การนำไปปฏิบัติ

หากต้องการใช้คุณลักษณะ System UI เพิ่มเติม ผู้ผลิตอุปกรณ์ควรใช้ส่วนประกอบ System UI เดียวที่คอยรับฟังการเพิ่ม/ลบจอแสดงผลและนำเสนอเนื้อหาที่เหมาะสม

ส่วนประกอบ System UI ที่รองรับ Multi-Display (MD) ควรจัดการกับกรณีต่อไปนี้:

  • การเริ่มต้นการแสดงผลหลายจอเมื่อเริ่มต้น
  • เพิ่มจอแสดงผลเมื่อรันไทม์
  • จอแสดงผลถูกลบออกขณะรันไทม์

เมื่อ System UI ตรวจพบการเพิ่มจอแสดงผลก่อน WindowManager ระบบจะสร้างสภาวะการแข่งขัน สิ่งนี้สามารถหลีกเลี่ยงได้โดยการใช้การเรียกกลับแบบกำหนดเองจาก WindowManager ไปยัง System UI เมื่อมีการเพิ่มจอแสดงผลแทนที่จะสมัครรับเหตุการณ์ DisplayManager .DisplayListener สำหรับการดำเนินการอ้างอิง โปรดดูที่ CommandQueue.Callbacks#onDisplayReady สำหรับการรองรับแถบนำทาง และ WallpaperManagerInternal#onDisplayReady สำหรับวอลเปเปอร์

นอกจากนี้ Android 10 ยังมีการอัปเดตเหล่านี้:

  • คลาส NavigationBarController ควบคุมการทำงานทั้งหมดที่เฉพาะเจาะจงสำหรับแถบนำทาง
  • หากต้องการดูแถบนำทางแบบกำหนดเอง โปรดดูที่ CarStatusBar
  • TYPE_NAVIGATION_BAR ไม่ได้จำกัดอยู่เพียงอินสแตนซ์เดียวอีกต่อไป และสามารถใช้ได้ต่อจอแสดงผล
  • IWindowManager#hasNavigationBar() ได้รับการอัปเดตเพื่อรวมพารามิเตอร์ displayId สำหรับ System UI เท่านั้น

ตัวเปิด

ใน Android 10 จอแสดงผลแต่ละจอที่กำหนดค่าให้รองรับการตกแต่งระบบจะมีโฮมสแต็กเฉพาะสำหรับกิจกรรมตัวเรียกใช้งานประเภท WindowConfiguration#ACTIVITY_TYPE_HOME ตามค่าเริ่มต้น แต่ละจอแสดงผลใช้กิจกรรมตัวเรียกใช้งานแยกต่างหาก

รูปที่ 1 ตัวอย่างตัวเรียกใช้งานหลายจอแสดงผลสำหรับ platform/development/samples/MultiDisplay

ตัวเรียกใช้งานที่มีอยู่ส่วนใหญ่ไม่รองรับหลายอินสแตนซ์และไม่ได้รับการปรับให้เหมาะกับขนาดหน้าจอขนาดใหญ่ นอกจากนี้ มักจะคาดหวังประสบการณ์ที่แตกต่างออกไปในจอแสดงผลรอง/จอแสดงผลภายนอก เพื่อจัดเตรียมกิจกรรมเฉพาะสำหรับหน้าจอรอง Android 10 ขอแนะนำหมวดหมู่ SECONDARY_HOME ในตัวกรอง Intent อินสแตนซ์ของกิจกรรมนี้ใช้กับจอแสดงผลทั้งหมดที่รองรับการตกแต่งระบบ หนึ่งจอต่อจอแสดงผล

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

กิจกรรมต้องมีโหมดการเปิดตัวที่ไม่ป้องกันหลายอินสแตนซ์ และคาดว่าจะปรับให้เข้ากับขนาดหน้าจอที่แตกต่างกัน โหมดการเปิดตัวไม่สามารถเป็น singleInstance หรือ singleTask

การนำไปปฏิบัติ

ใน Android 10 นั้น RootActivityContainer#startHomeOnDisplay() จะเลือกส่วนประกอบและจุดประสงค์ที่ต้องการโดยอัตโนมัติ ขึ้นอยู่กับจอแสดงผลที่หน้าจอหลักเปิดขึ้น RootActivityContainer#resolveSecondaryHomeActivity() มีตรรกะเพื่อค้นหาคอมโพเนนต์กิจกรรมตัวเรียกใช้งาน ขึ้นอยู่กับตัวเรียกทำงานที่เลือกในปัจจุบัน และสามารถใช้ค่าดีฟอลต์ของระบบได้ หากจำเป็น (ดู ActivityTaskManagerService#getSecondaryHomeIntent()

ข้อจำกัดด้านความปลอดภัย

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

วอลเปเปอร์

ใน Android 10 (และสูงกว่า) วอลเปเปอร์ได้รับการรองรับบนจอแสดงผลรอง:

รูปที่ 2 Live Wallpaper บนจอแสดงผลภายใน (ด้านบน) และภายนอก (ด้านล่าง)

นักพัฒนาสามารถประกาศการสนับสนุนคุณสมบัติวอลเปเปอร์ได้โดยระบุ android:supportsMultipleDisplays="true" ในคำจำกัดความ WallpaperInfo XML นักพัฒนาวอลเปเปอร์ยังได้รับการคาดหวังให้โหลดเนื้อหาโดยใช้บริบทการแสดงผลใน WallpaperService.Engine#getDisplayContext()

เฟรมเวิร์กจะสร้างอินสแตนซ์ WallpaperService.Engine หนึ่งอินสแตนซ์ต่อจอแสดงผล ดังนั้นแต่ละเอ็นจิ้นจึงมีพื้นผิวและบริบทการแสดงผลของตัวเอง นักพัฒนาจำเป็นต้องตรวจสอบให้แน่ใจว่าแต่ละเอ็นจิ้นสามารถวาดได้อย่างอิสระที่อัตราเฟรมที่แตกต่างกัน โดยคำนึงถึง VSYNC

เลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ

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

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

  1. ใช้ WallpaperManager API เพื่อตั้งค่าวอลเปเปอร์
  2. WallpaperManager ได้มาจาก Context บริบท และแต่ละ Context บริบทมีข้อมูลเกี่ยวกับการแสดงผลที่สอดคล้องกัน ( Context#getDisplay()/getDisplayId() ) ดังนั้น คุณสามารถรับ displayId จากอินสแตนซ์ WallpaperManager ได้โดยไม่ต้องเพิ่มวิธีการใหม่
  3. ในด้านเฟรมเวิร์ก ให้ใช้ displayId ที่ได้รับจาก Context บริบท และแมปกับตัวระบุแบบคงที่ (เช่น พอร์ตของจอแสดงผลจริง) ใช้ตัวระบุแบบคงที่เพื่อคงวอลเปเปอร์ที่เลือกไว้

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

หากจำเป็นต้องตั้งค่าวอลเปเปอร์สำหรับจอแสดงผลอื่นที่ไม่ใช่จอแสดงผลปัจจุบัน ให้สร้าง Context บริบทใหม่สำหรับจอแสดงผลเป้าหมาย ( Context#createDisplayContext ) และรับอินสแตนซ์ WallpaperManager จากจอแสดงผลนั้น

ข้อจำกัดด้านความปลอดภัย

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

การนำไปปฏิบัติ

ใน Android 10 IWallpaperConnection#attachEngine() และ IWallpaperService#attach() ยอมรับพารามิเตอร์ displayId เพื่อสร้างการเชื่อมต่อต่อจอแสดงผล WallpaperManagerService.DisplayConnector สรุปเอ็นจิ้นวอลเปเปอร์ต่อการแสดงผลและการเชื่อมต่อ ใน WindowManager ตัวควบคุมวอลเปเปอร์จะถูกสร้างขึ้นสำหรับออบเจ็กต์ DisplayContent แต่ละรายการในขณะที่สร้าง แทนที่จะเป็น WallpaperController ตัวเดียวสำหรับจอแสดงผลทั้งหมด

การใช้งานเมธอด WallpaperManager สาธารณะบางส่วน (เช่น WallpaperManager#getDesiredMinimumWidth() ) ได้รับการอัปเดตเพื่อคำนวณและให้ข้อมูลสำหรับจอแสดงผลที่เกี่ยวข้อง WallpaperInfo#supportsMultipleDisplays() และแอตทริบิวต์ทรัพยากรที่เกี่ยวข้องถูกเพิ่มเข้ามา เพื่อให้นักพัฒนาแอปสามารถรายงานว่าวอลเปเปอร์ใดบ้างที่พร้อมสำหรับหลายหน้าจอ

หากบริการวอลเปเปอร์ที่แสดงบนจอแสดงผลเริ่มต้นไม่รองรับจอแสดงผลหลายจอ ระบบจะแสดงวอลเปเปอร์เริ่มต้นบนจอแสดงผลรอง

รูปที่ 3. ตรรกะทางเลือกของวอลเปเปอร์สำหรับจอแสดงผลรอง