Xử lý tính năng cắm nóng

Các chức năng hiển thị (chẳng hạn như chế độ hiển thị và các loại HDR được hỗ trợ) có thể thay đổi linh hoạt trên các thiết bị có màn hình kết nối bên ngoài (có HDMI hoặc DisplayPort), chẳng hạn như hộp giải mã tín hiệu truyền hình (STB) Android TV và thiết bị truyền hình trực tuyến (OTT). Thay đổi này có thể xảy ra do tín hiệu cắm nóng HDMI, chẳng hạn như khi người dùng chuyển từ màn hình này sang màn hình khác hoặc khởi động thiết bị mà không có màn hình kết nối. Android 12 trở lên có những thay đổi trong khung để xử lý khả năng cắm nóng và khả năng hiển thị động.

Trang này mô tả cách xử lý các thay đổi về khả năng hiển thị và việc cắm nóng màn hình trong quá trình triển khai Composer HAL. Ngoài ra, bài viết này cũng thảo luận về cách quản lý framebuffer được liên kết và ngăn chặn tình trạng tranh đua trong những trường hợp này.

Cập nhật các chức năng hiển thị

Phần này mô tả cách khung Android xử lý các thay đổi về khả năng hiển thị do Composer HAL khởi tạo.

Trước khi Android có thể xử lý đúng các thay đổi về khả năng hiển thị, OEM phải triển khai Composer HAL để sử dụng onHotplug(display, connection=CONNECTED) để thông báo cho khung về mọi thay đổi đối với khả năng hiển thị. Sau khi bạn triển khai, Android sẽ xử lý các thay đổi về khả năng hiển thị như sau:

  1. Khi phát hiện thấy thay đổi về khả năng hiển thị, khung sẽ nhận được một thông báo onHotplug(display, connection=CONNECTED).
  2. Khi nhận được thông báo, khung sẽ loại bỏ trạng thái hiển thị và tạo lại trạng thái đó bằng các chức năng mới từ HAL bằng cách sử dụng các phương thức getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilitiesgetDisplayCapabilities.
  3. Sau khi tạo lại trạng thái hiển thị mới, khung sẽ gửi lệnh gọi lại onDisplayChanged đến những ứng dụng đang theo dõi các sự kiện như vậy.

Khung này sẽ phân bổ lại các vùng đệm khung trong các sự kiện onHotplug(display, connection=CONNECTED) tiếp theo. Hãy xem phần Quản lý bộ đệm khung hình của ứng dụng để biết thêm thông tin về cách quản lý bộ nhớ bộ đệm khung hình đúng cách nhằm tránh lỗi trong quá trình phân bổ bộ đệm khung hình mới.

Xử lý các trường hợp kết nối phổ biến

Phần này trình bày cách xử lý đúng cách các tình huống kết nối khác nhau trong quá trình triển khai khi màn hình chính được kết nối và ngắt kết nối.

Được thiết kế cho thiết bị di động, khung Android không có hỗ trợ tích hợp cho màn hình chính bị ngắt kết nối. Thay vào đó, HAL phải thay thế màn hình chính bằng một màn hình giữ chỗ trong các hoạt động tương tác với khung hình trong trường hợp màn hình chính bị ngắt kết nối vật lý.

Các trường hợp sau có thể xảy ra trên hộp giải mã tín hiệu truyền hình và TV dongle có màn hình kết nối bên ngoài có thể ngắt kết nối. Để triển khai hỗ trợ cho các trường hợp này, hãy sử dụng thông tin trong bảng dưới đây:

Trường hợp Sử dụng
Không có màn hình nào được kết nối tại thời điểm khởi động
  • Gửi một onHotplug(display, connection=CONNECTED)tín hiệu từ Composer HAL đến khung.
  • Thay thế trạng thái hiển thị thực tế bên trong Composer HAL bằng trạng thái hiển thị của phần giữ chỗ.
Màn hình chính được kết nối bằng cáp
Màn hình chính bị ngắt kết nối vật lý
  • Gửi một sự kiện onHotplug(display, connection=CONNECTED) khác từ Composer HAL đến khung.
  • Thay thế trạng thái hiển thị thực tế bên trong Composer HAL bằng trạng thái hiển thị của phần giữ chỗ. Màn hình giữ chỗ phải có một chế độ hiển thị duy nhất để khung gửi lệnh gọi lại onDisplayChanged đến các ứng dụng (vì tập hợp các chế độ được hỗ trợ đã thay đổi). Chế độ một màn hình này phải khớp với chế độ hoạt động gần đây nhất của màn hình thực trước khi ngắt kết nối, để các ứng dụng không nhận được sự kiện thay đổi cấu hình.

Những điều cần cân nhắc khi không kết nối qua HDMI

Android TV chỉ hỗ trợ các độ phân giải sau:

  • 720x1280
  • 1080x1920
  • 2160x3840
  • 4320x7680

Khi STB hoặc TV dongle cố gắng hiển thị một độ phân giải không được hỗ trợ, chẳng hạn như 480i qua kết nối CVBS, người dùng sẽ thấy một thông báo lỗi.

Nếu STB hoặc TV dongle có cả cổng HDMI và cổng không phải HDMI, thì cổng HDMI là màn hình chính và cổng không phải HDMI không hoạt động. Do đó, nếu kết nối HDMI bị ngắt trong khi kết nối không phải HDMI vẫn được kết nối, thì một sự kiện sẽ được gửi đến SurfaceFlinger và các chức năng của màn hình không phải HDMI phải được phản ánh thông qua getDisplayAttribute và các API iComposerClient khác (chẳng hạn như getHdrCapabilities).

Sử dụng mã nhận dạng cấu hình tuần tự để ngăn tình trạng tranh đua

Tình trạng xung đột có thể xảy ra nếu Composer HAL cập nhật các cấu hình màn hình được hỗ trợ đồng thời với việc khung gọi setActiveConfig hoặc setActiveConfigWithConstraints. Giải pháp là triển khai Composer HAL để sử dụng các mã nhận dạng tuần tự và ngăn chặn vấn đề này.

Phần này mô tả cách các điều kiện xung đột có thể xảy ra, sau đó là thông tin chi tiết về cách triển khai Composer HAL để sử dụng các mã nhận dạng tuần tự nhằm ngăn chặn những điều kiện như vậy.

Hãy xem xét chuỗi sự kiện sau đây, khi các mã nhận dạng tuần tự mới KHÔNG được chỉ định cho các cấu hình hiển thị mới, gây ra tình trạng xung đột:

  1. Sau đây là các mã nhận dạng cấu hình màn hình được hỗ trợ:

    • id=1, 1080x1920 60 Hz
    • id=2, 1080x1920 50 Hz
  2. Khung này gọi setActiveConfig(display, config=1).

  3. Đồng thời, Composer HAL xử lý một thay đổi về cấu hình màn hình và cập nhật trạng thái nội bộ của cấu hình đó thành một nhóm cấu hình màn hình mới, như sau:

    • id=1, 2160x3840 60 Hz
    • id=2, 2160x3840 50 Hz
    • id=3, 1080x1920 60 Hz
    • id=4, 1080x1920 50 Hz
  4. Composer HAL gửi một sự kiện onHotplug đến khung để thông báo rằng tập hợp các chế độ được hỗ trợ đã thay đổi.

  5. HAL của Composer nhận được setActiveConfig(display, config=1) (từ bước 2).

  6. HAL diễn giải rằng khung hình đã yêu cầu thay đổi cấu hình thành 2160x3840 60 Hz, mặc dù trên thực tế, khung hình mong muốn là 1080x1920 60 Hz.

Quy trình sử dụng việc chỉ định mã nhận dạng không tuần tự kết thúc ở đây với việc diễn giải sai thay đổi cấu hình mong muốn.

Định cấu hình Composer HAL để sử dụng các mã nhận dạng tuần tự

Để tránh các điều kiện xung đột như vậy, OEM phải triển khai Composer HAL như sau:

  • Khi Composer HAL cập nhật các cấu hình màn hình được hỗ trợ, HAL này sẽ chỉ định các mã nhận dạng tuần tự mới cho các cấu hình màn hình mới.
  • Khi khung gọi setActiveConfig hoặc setActiveConfigWithConstraints bằng mã nhận dạng cấu hình không hợp lệ, Composer HAL sẽ bỏ qua lệnh gọi.

Các bước này giúp ngăn chặn tình trạng tranh đua như minh hoạ trong phần thảo luận sau.

Hãy xem xét chuỗi sự kiện sau đây khi mã nhận dạng tuần tự mới được chỉ định cho cấu hình hiển thị mới:

  1. Sau đây là các mã nhận dạng cấu hình màn hình được hỗ trợ:

    • id=1, 1080x1920 60 Hz
    • id=2, 1080x1920 50 Hz
  2. Khung này gọi setActiveConfig(display, config=1).

  3. Khi một thay đổi về cấu hình màn hình được xử lý, tập hợp mã nhận dạng cấu hình tiếp theo sẽ được chỉ định bắt đầu từ số nguyên chưa dùng tiếp theo, như sau:

    • id=3, 2160x3840 60 Hz

    • id=4, 2160x3840 50 Hz

    • id=5, 1080x1920 60 Hz

    • id=6, 1080x1920 50 Hz

  4. Composer HAL gửi một sự kiện onHotplug đến khung để thông báo rằng tập hợp các chế độ được hỗ trợ đã thay đổi.

  5. HAL của Composer nhận được setActiveConfig(display, config=1) (từ bước 2).

  6. HAL của Composer sẽ bỏ qua lệnh gọi vì mã nhận dạng không còn hợp lệ.

  7. Khung này nhận và xử lý sự kiện onHotplug từ bước 4. Thư viện này gọi vào Composer HAL bằng cách sử dụng các hàm getDisplayConfigsgetDisplayAttribute. Với những hàm này, khung sẽ xác định mã nhận dạng mới (5) cho độ phân giải và tốc độ làm mới mong muốn là 1080x1920 và 60 Hz.

  8. Khung này sẽ gửi một sự kiện setActiveConfig khác có mã đã cập nhật là 5.

  9. HAL Trình kết hợp nhận setActiveConfig(display, config=5) từ bước 5.

  10. HAL diễn giải chính xác rằng khung hình đã yêu cầu thay đổi cấu hình thành 1080x1920 60 Hz.

Như trong ví dụ trên, quy trình sử dụng việc chỉ định mã nhận dạng tuần tự đảm bảo rằng tình trạng tranh đua được ngăn chặn và thay đổi cấu hình hiển thị chính xác được cập nhật.