Tiện ích mở rộng WindowManager

Thư viện Jetpack WindowManager cho phép các nhà phát triển ứng dụng hỗ trợ các kiểu dáng thiết bị mới và môi trường nhiều cửa sổ.

Tiện ích mở rộng WindowManager (Tiện ích mở rộng) là một mô-đun nền tảng Android tùy chọn cho phép nhiều tính năng Jetpack WindowManager. Mô-đun này được triển khai trong AOSP trong frameworks/base/libs/WindowManager/Jetpack và được cung cấp trên các thiết bị hỗ trợ các tính năng của WindowManager.

Phân phối mô-đun mở rộng

Tiện ích mở rộng được biên dịch thành thư viện .jar và được đặt trong phân vùng system_ext trên thiết bị nếu Tiện ích mở rộng được bật trong tệp tạo tệp của thiết bị.

Để bật Tiện ích mở rộng trên thiết bị, hãy thêm phần sau vào tệp tạo tệp thiết bị của sản phẩm:

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

Điều này kích hoạt các gói androidx.window.extensionsandroidx.window.sidecar trên thiết bị và đặt thuộc tính persist.wm.extensions.enabled . Việc bao gồm các gói này trong tệp thực hiện cũng đặt các khai báo trong etc/permissions/ , làm cho chúng có sẵn cho các quy trình ứng dụng. Thông thường, các mô-đun được tải vào và thực thi như một phần của quy trình ứng dụng trong thời gian chạy khi được thư viện Jetpack WindowManager sử dụng, điều này làm cho hoạt động của nó tương tự như mã khung phía máy khách, như minh họa trong hình sau:

Hình 1. Các tiện ích mở rộng WindowManager được tải vào quy trình ứng dụng tương tự như mã nền tảng.

Mô-đun androidx.window.extensions là mô-đun Tiện ích mở rộng hiện đang được phát triển tích cực. Mô-đun androidx.window.sidecar là mô-đun cũ được đưa vào để tương thích với các phiên bản đầu tiên của Jetpack WindowManager, nhưng sidecar không còn được duy trì tích cực nữa.

Hình dưới đây cho thấy logic để xác định việc sử dụng androidx.window.extensions hoặc androidx.window.sidecar .

Hình 2. Cây quyết định truy cập androidx.window.extensions hoặc androidx.window.sidecar .

Mô-đun mở rộng

Tiện ích mở rộng cung cấp tính năng tạo cửa sổ cho các thiết bị màn hình lớn có thể gập lại và các thiết bị hỗ trợ tạo cửa sổ trên màn hình bên ngoài. Các khu vực đặc trưng bao gồm:

Việc triển khai Tiện ích mở rộng OEM có thể cung cấp các thành phần hoặc thành phần rỗng với cách triển khai mặc định hoặc sơ khai của các phương thức trong giao diện WindowExtensions nếu phần cứng thiết bị không hỗ trợ các tính năng tương ứng, trừ khi tính năng này được yêu cầu cụ thể trong Tài liệu Định nghĩa Tương thích (CDD) 7.1.1.1 .

Tiện ích mở rộng và API Jetpack

Mô-đun Tiện ích mở rộng WindowManager cung cấp bề mặt API riêng bên cạnh các API nền tảng công cộng. Mô-đun Tiện ích mở rộng được phát triển công khai trong thư viện Jetpack androidx.window.extensions dành cho người không dành cho nhà phát triển, để Jetpack WindowManager ( androidx.window ) có thể liên kết với nó tại thời điểm biên dịch. Bề mặt API tiện ích mở rộng thường cung cấp các API cấp thấp hơn.

Các API mà Tiện ích mở rộng cung cấp chỉ dành cho thư viện Jetpack WindowManager sử dụng. API tiện ích mở rộng không được các nhà phát triển ứng dụng gọi trực tiếp. Không được thêm thư viện Tiện ích mở rộng làm phần phụ thuộc cho ứng dụng trong tệp bản dựng Gradle để đảm bảo chức năng chính xác. Tránh biên dịch trực tiếp thư viện Tiện ích mở rộng vào ứng dụng; thay vào đó, hãy dựa vào quá trình tải trong thời gian chạy để ngăn trường hợp tải kết hợp các lớp Tiện ích mở rộng được biên dịch trước và do thời gian chạy cung cấp.

Jetpack WindowManager ( androidx.window ) được thêm vào dưới dạng phần phụ thuộc ứng dụng và cung cấp các API công khai dành cho nhà phát triển, bao gồm cả các API dành cho các tính năng Tiện ích mở rộng của WindowManager. Thư viện WindowManager tự động tải Tiện ích mở rộng vào quy trình ứng dụng và gói các API Tiện ích mở rộng cấp thấp hơn thành các phần tóm tắt cấp cao hơn và các giao diện tập trung hơn. API WindowManager Jetpack tuân theo các tiêu chuẩn phát triển ứng dụng Android hiện đại và nhằm mang lại khả năng tương tác thuận tiện bằng cách tích hợp tốt với các cơ sở mã sử dụng các thư viện AndroidX khác.

Các phiên bản và bản cập nhật tiện ích mở rộng

Mô-đun Tiện ích mở rộng có thể được cập nhật cùng với các bản cập nhật hàng năm hoặc hàng quý của nền tảng Android. Các bản cập nhật hàng quý cho phép tăng cấp API tiện ích mở rộng giữa các bản cập nhật API nền tảng Android, cho phép lặp lại nhanh hơn và mang đến cho các OEM cơ hội bổ sung quyền truy cập API chính thức vào các tính năng mới gần thời điểm ra mắt phần cứng.

Bảng sau liệt kê các phiên bản API androidx.window.extensions cho các bản phát hành Android khác nhau.

Phiên bản nền tảng Android Cấp API tiện ích mở rộng WindowManager Phiên bản API androidx.window.extensions
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

Cấp độ API tiện ích mở rộng (cột giữa) được tăng lên mỗi khi có phần bổ sung cho bề mặt API ổn định hiện có (cột bên phải).

Khả năng tương thích ngược và xuôi

Jetpack WindowManager xử lý sự phức tạp của việc xử lý các bản cập nhật cấp độ API thường xuyên, phát triển API nhanh và khả năng tương thích ngược. Khi mã thư viện được thực thi trong quá trình ứng dụng, thư viện sẽ kiểm tra cấp API Tiện ích mở rộng đã khai báo và cung cấp quyền truy cập vào các tính năng theo cấp độ đã khai báo.

Để bảo vệ ứng dụng khỏi gặp sự cố trong thời gian chạy, WindowManager cũng thực hiện kiểm tra phản ánh Java trong thời gian chạy của các API Tiện ích mở rộng có sẵn theo cấp API Tiện ích mở rộng đã khai báo. Nếu có sự không khớp, WindowManager có thể vô hiệu hóa việc sử dụng Tiện ích mở rộng (một phần hoặc toàn bộ) và báo cáo các tính năng liên quan là không có sẵn cho ứng dụng.

Tiện ích mở rộng WindowManager được triển khai dưới dạng mô-đun system_ext sử dụng API nền tảng riêng để gọi vào lõi WindowManager, DeviceStateManager và các dịch vụ hệ thống khác trong quá trình triển khai các tính năng Tiện ích mở rộng.

Khả năng tương thích có thể không được duy trì với các phiên bản Tiện ích mở rộng trước khi phát hành nền tảng Android hàng quý hoặc hàng năm tương ứng mà các phiên bản được hoàn thiện. Bạn có thể tìm thấy lịch sử đầy đủ của API tiện ích mở rộng trong nhánh phát hành window:extensions:extensions API text files .

Các phiên bản Tiện ích mở rộng mới hơn phải tiếp tục hoạt động với các phiên bản WindowManager cũ hơn được biên dịch thành các ứng dụng để duy trì khả năng tương thích về sau. Để đảm bảo điều này, mọi phiên bản mới của API tiện ích mở rộng chỉ thêm các API mới và không xóa các API cũ hơn. Do đó, các ứng dụng có phiên bản WindowManager cũ hơn có thể tiếp tục sử dụng API tiện ích mở rộng cũ hơn mà ứng dụng được biên dịch dựa trên đó.

Xác minh CTS đảm bảo rằng đối với mọi phiên bản API tiện ích mở rộng được khai báo trên thiết bị, tất cả API cho phiên bản đó và các phiên bản trước đó đều hiện diện và hoạt động.

Hiệu suất

Theo mặc định, mô-đun Tiện ích mở rộng được lưu vào bộ nhớ đệm trong các trình tải lớp hệ thống không phải bootclasspath bắt đầu từ Android 14 (API cấp 34), do đó, không có tác động nào đến hiệu suất do tải mô-đun vào bộ nhớ khi khởi động ứng dụng. Việc sử dụng các tính năng mô-đun riêng lẻ có thể ảnh hưởng đôi chút đến đặc tính hiệu suất của ứng dụng khi các lệnh gọi IPC bổ sung được thực hiện giữa máy khách và máy chủ.

Mô-đun

Nhúng hoạt động

Thành phần nhúng Hoạt động cung cấp một tập hợp các tính năng cho phép ứng dụng tổ chức trình bày cửa sổ hoạt động trong giới hạn của ứng dụng gốc. Điều này bao gồm việc hiển thị đồng thời hai hoạt động cạnh nhau trong bố cục nhiều ngăn, hỗ trợ tối ưu hóa màn hình lớn cho các ứng dụng cũ.

Thành phần nhúng hoạt động phải có sẵn trên tất cả các thiết bị có màn hình tích hợp có kích thước bằng hoặc lớn hơn sw600 dp . Tính năng nhúng hoạt động cũng phải được bật trên các thiết bị hỗ trợ kết nối màn hình bên ngoài vì ứng dụng có thể được hiển thị ở kích thước lớn hơn khi màn hình bên ngoài được kết nối trong thời gian chạy.

Cấu hình thiết bị

Không cần cấu hình thiết bị cụ thể nào ngoài việc bật mô-đun Tiện ích mở rộng như được mô tả trong phần phân phối mô-đun Tiện ích mở rộng . Việc bật Tiện ích mở rộng trên tất cả các thiết bị hỗ trợ chế độ nhiều cửa sổ là điều hợp lý. Các phiên bản Android trong tương lai có thể sẽ yêu cầu Tiện ích mở rộng trên các cấu hình thiết bị cầm tay và màn hình lớn phổ biến.

Thông tin bố cục cửa sổ

Thành phần thông tin bố cục cửa sổ xác định vị trí và trạng thái của bản lề trên thiết bị có thể gập lại khi bản lề đi qua cửa sổ ứng dụng. Thông tin bố cục cửa sổ cho phép các ứng dụng phản hồi và hiển thị bố cục được tối ưu hóa ở chế độ để bàn trên các thiết bị có thể gập lại. Xem Làm cho ứng dụng của bạn nhận biết được thông tin chi tiết về cách sử dụng.

Các thiết bị Android có thể gập lại bao gồm một bản lề kết nối các khu vực bảng hiển thị riêng biệt hoặc liên tục phải cung cấp thông tin về bản lề cho các ứng dụng thông qua WindowLayoutComponent .

Vị trí bản lề và giới hạn phải được báo cáo liên quan đến cửa sổ ứng dụng được xác định bởi Context được chuyển vào API. Nếu giới hạn cửa sổ ứng dụng không giao nhau với giới hạn bản lề thì không được báo cáo DisplayFeature bản lề. Bạn cũng có thể chấp nhận không báo cáo các tính năng hiển thị khi vị trí của chúng có thể không được báo cáo một cách đáng tin cậy, chẳng hạn như khi người dùng có thể di chuyển tự do một cửa sổ ứng dụng ở chế độ nhiều cửa sổ hoặc chế độ hộp thư tương thích.

Đối với tính năng gập , các cập nhật trạng thái phải được báo cáo khi vị trí bản lề thay đổi giữa các trạng thái ổn định. Theo mặc định ở trạng thái hiển thị phẳng, API phải báo cáo FoldingFeature.State.FLAT . Nếu phần cứng thiết bị có thể được để ở chế độ gập một nửa ở trạng thái ổn định thì API phải báo cáo FoldingFeature.State.HALF_OPENED . Không có trạng thái đóng trong API, vì trong trường hợp như vậy, cửa sổ ứng dụng sẽ không hiển thị hoặc sẽ không vượt qua giới hạn bản lề.

Cấu hình thiết bị

Để hỗ trợ triển khai tính năng gập, OEM phải thực hiện những việc sau:

  • Định cấu hình trạng thái thiết bị trong device_state_configuration.xml để DeviceStateManagerService sử dụng. Xem DeviceStateProviderImpl.java để tham khảo.

    Nếu cách triển khai mặc định của DeviceStateProvider hoặc DeviceStatePolicy không phù hợp với thiết bị thì bạn có thể sử dụng cách triển khai tùy chỉnh.

  • Kích hoạt mô-đun Tiện ích mở rộng như được mô tả trong phần phân phối mô-đun Tiện ích mở rộng .

  • Chỉ định vị trí của các tính năng hiển thị trong tài nguyên chuỗi com.android.internal.R.string.config_display_features (thường là trong frameworks/base/core/res/res/values/config.xml trong lớp phủ thiết bị).

    Định dạng dự kiến ​​cho chuỗi là:

    <type>-[<left>,<top>,<right>,<bottom>]

    type có thể fold hoặc hinge . Các giá trị cho left , top , rightbottom là tọa độ pixel nguyên trong không gian tọa độ hiển thị theo hướng hiển thị tự nhiên. Chuỗi cấu hình có thể chứa nhiều tính năng hiển thị được phân tách bằng dấu chấm phẩy.

    Ví dụ:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Xác định ánh xạ giữa giá trị nhận dạng trạng thái thiết bị nội bộ được sử dụng trong DeviceStateManager và hằng số trạng thái công khai được gửi tới nhà phát triển trong com.android.internal.R.array.config_device_state_postures .

    Định dạng dự kiến ​​cho mỗi mục là:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Các mã định danh trạng thái được hỗ trợ là:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1 : Trạng thái không có tính năng gấp nào để báo cáo. Ví dụ: nó có thể là trạng thái đóng của thiết bị gập thông thường với màn hình chính ở mặt trong.
    • COMMON_STATE_HALF_OPENED = 2 : Tính năng gập được mở một nửa.
    • COMMON_STATE_FLAT = 3 : Tính năng gập phẳng. Ví dụ: nó có thể là trạng thái mở của thiết bị gập thông thường với màn hình chính ở mặt trong.
    • COMMON_STATE_USE_BASE_STATE = 1000 : Trong Android 14, một giá trị có thể được sử dụng cho các trạng thái mô phỏng trong đó trạng thái bản lề được bắt nguồn bằng trạng thái cơ sở, như được xác định trong CommonFoldingFeature.java

    Xem DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int) để biết thêm thông tin.

    Ví dụ:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

Khu vực cửa sổ

Thành phần khu vực cửa sổ cung cấp một tập hợp các tính năng cho phép ứng dụng truy cập vào các màn hình và khu vực hiển thị bổ sung trên một số thiết bị có thể gập lại và nhiều màn hình.

Chế độ hiển thị phía sau cho phép ứng dụng hiển thị giao diện người dùng xem trước camera trên màn hình ngoài của thiết bị có thể gập lại để cho phép sử dụng camera của thiết bị chính để chụp ảnh selfie và quay video. Các thiết bị có màn hình bao gồm tương thích với Android (như được CDD Android xác định về các thuộc tính như kích thước, mật độ và khả năng điều hướng có sẵn) phù hợp với camera của thiết bị phía sau phải cung cấp quyền truy cập vào chế độ hiển thị phía sau.

Trên Android 14, chế độ hiển thị kép cho phép các ứng dụng chạy trên màn hình bên trong của thiết bị có thể gập lại hiển thị nội dung bổ sung trên màn hình ngoài đối diện với người dùng khác; ví dụ: màn hình bìa có thể hiển thị bản xem trước của máy ảnh cho người được chụp ảnh hoặc ghi lại.

Cấu hình thiết bị

Để hỗ trợ triển khai tính năng gập, OEM phải thực hiện những việc sau:

  • Định cấu hình trạng thái thiết bị trong device_state_configuration.xml để DeviceStateManagerService sử dụng. Xem DeviceStateProviderImpl.java để biết thêm thông tin.

    Nếu cách triển khai mặc định của DeviceStateProvider hoặc DeviceStatePolicy không phù hợp với thiết bị thì bạn có thể sử dụng cách triển khai tùy chỉnh.

  • Đối với các thiết bị có thể gập lại hỗ trợ chế độ mở hoặc phẳng, hãy chỉ định giá trị nhận dạng trạng thái tương ứng trong com.android.internal.R.array.config_openDeviceStates .

  • Đối với các thiết bị dạng gập hỗ trợ trạng thái gập, hãy liệt kê các mã nhận dạng trạng thái tương ứng trong com.android.internal.R.array.config_foldedDeviceStates .

  • Đối với các thiết bị dạng gập hỗ trợ trạng thái gập một nửa (bản lề mở một nửa giống như máy tính xách tay), hãy liệt kê các trạng thái tương ứng trong com.android.internal.R.array.config_halfFoldedDeviceStates .

  • Đối với các thiết bị hỗ trợ chế độ hiển thị phía sau:

    • Liệt kê các trạng thái tương ứng trong com.android.internal.R.array.config_rearDisplayDeviceStates cho DeviceStateManager .
    • Chỉ định địa chỉ hiển thị vật lý của màn hình phía sau trong com.android.internal.R.string.config_rearDisplayPhysicalAddress .
    • Chỉ định mã nhận dạng trạng thái trong com.android.internal.R.integer.config_deviceStateRearDisplay để Tiện ích mở rộng sử dụng.
    • Thêm mã nhận dạng trạng thái trong com.android.internal.R.array.config_deviceStatesAvailableForAppRequests để cung cấp mã này cho các ứng dụng.
  • Trên Android 14, đối với các thiết bị hỗ trợ chế độ hiển thị kép (đồng thời):

    • Đặt com.android.internal.R.bool.config_supportsConcurrentInternalDisplays thành true .
    • Chỉ định địa chỉ hiển thị vật lý của màn hình phía sau trong com.android.internal.R.config_deviceStateConcurrentRearDisplay .
    • Chỉ định mã định danh trạng thái trong com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay để Tiện ích mở rộng sử dụng nếu mã định danh này được cung cấp cho các ứng dụng.
    • Thêm mã nhận dạng trạng thái trong com.android.internal.R.array.config_deviceStatesAvailableForAppRequests để cung cấp mã này cho các ứng dụng.

xác minh

OEM phải xác minh việc triển khai của mình để đảm bảo hoạt động mong đợi trong các tình huống phổ biến. Các thử nghiệm CTS và thử nghiệm sử dụng Jetpack WindowManager có sẵn cho các OEM để triển khai thử nghiệm.

xét nghiệm CTS

Để chạy thử nghiệm CTS, hãy xem Chạy thử nghiệm CTS . Các bài kiểm tra CTS liên quan đến Jetpack WindowManager nằm trong cts/tests/framework/base/windowmanager/jetpack/ . Tên mô-đun thử nghiệm là CtsWindowManagerJetpackTestCases .

Kiểm tra WindowManager

Để tải xuống bản kiểm tra Jetpack WindowManager, hãy làm theo Hướng dẫn về Jetpack của Android . Các bài kiểm tra được đặt trong thư viện window bên dưới mô-đun window:window window: window/window/src/androidTest/ .

Để chạy kiểm tra thiết bị cho mô-đun window:window từ dòng lệnh, hãy làm như sau:

  1. Cắm thiết bị có tùy chọn nhà phát triển và bật gỡ lỗi USB.
  2. Cho phép máy tính gỡ lỗi thiết bị.
  3. Mở shell trong thư mục gốc của kho lưu trữ androidx.
  4. Thay đổi thư mục thành framework/support .
  5. Chạy lệnh sau: ./gradlew window:window:connectedAndroidTest .
  6. Phân tích kết quả.

Để chạy thử nghiệm từ Android Studio, hãy làm như sau:

  1. Mở Android Studio.
  2. Cắm thiết bị có tùy chọn nhà phát triển và bật gỡ lỗi USB.
  3. Cho phép máy tính gỡ lỗi thiết bị.
  4. Điều hướng đến bài kiểm tra trong thư viện cửa sổ của mô-đun cửa sổ.
  5. Mở một lớp kiểm tra và chạy bằng cách sử dụng các mũi tên màu xanh lá cây ở bên phải trình chỉnh sửa.

Ngoài ra, bạn có thể tạo cấu hình trong Android Studio để chạy một phương thức thử nghiệm, một lớp thử nghiệm hoặc tất cả các thử nghiệm trong một mô-đun.

Kết quả có thể được phân tích thủ công bằng cách xem kết quả đầu ra của shell. Một số thử nghiệm sẽ bị bỏ qua nếu thiết bị không đáp ứng được một số giả định nhất định. Kết quả được lưu ở vị trí tiêu chuẩn và nhà phân tích có thể viết tập lệnh để tự động phân tích kết quả.