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

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

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

Android 10 เพิ่มการสนับสนุนสำหรับการกำหนดค่าจอแสดงผลรองเพื่อแสดงการตกแต่งระบบบางอย่าง เช่น วอลเปเปอร์ แถบนำทาง และตัวเรียกใช้งาน โดยค่าเริ่มต้น จอแสดงผลหลักจะแสดงการตกแต่งระบบทั้งหมด และจอแสดงผลรองจะแสดงตัวเลือกที่เปิดใช้งาน รองรับ Input Method Editor (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 เดียวที่รับฟังการเพิ่ม/ลบจอแสดงผลและนำเสนอเนื้อหาที่เหมาะสม

คอมโพเนนต์ 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 ในตัวกรองเจตนา อินสแตนซ์ของกิจกรรมนี้ใช้กับจอแสดงผลทั้งหมดที่สนับสนุนการตกแต่งระบบ หนึ่งรายการต่อหนึ่งจอแสดงผล

<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 วอลเปเปอร์เคลื่อนไหวบนจอแสดงผลภายใน (ด้านบน) และจอแสดงผลภายนอก (ด้านล่าง)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

รูปที่ 3 ลอจิกทางเลือกของวอลเปเปอร์สำหรับจอภาพรอง