Tiện ích WindowManager

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 WindowManager (Tiện ích) là mô-đun nền tảng Android chọn tham gia hỗ trợ nhiều tính năng của Jetpack WindowManager. Mô-đun đã được triển khai trong AOSP (Dự án nguồn mở Android) bằng frameworks/base/libs/WindowManager/Jetpack và được vận chuyển trên các thiết bị hỗ trợ các tính năng WindowManager.

Phân phối mô-đun tiện ích

Các tiện ích được biên dịch vào thư viện .jar và đặt trong system_ext phân vùng trên thiết bị nếu Tiện ích được bật trong tệp makefile của thiết bị.

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

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

Thao tác này sẽ bật androidx.window.extensionsandroidx.window.sidecar trên thiết bị và đặt thuộc tính persist.wm.extensions.enabled. Việc đưa các gói này vào tệp makefile cũng giúp đặt nội dung khai báo trong etc/permissions/, cung cấp chúng cho các quy trình đăng ký. 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 ký tại thời gian chạy được thư viện Jetpack WindowManager sử dụng, giúp ứng dụng tương tự như mã khung phía máy khách, như được thể hiện trong các hình:

Hình 1. Tiện ích WindowManager được tải vào ứng dụng tương tự như mã nền tảng.

Mô-đun androidx.window.extensions là mô-đun Tiện ích hiện tại trong phát triển tích cực. Mô-đun androidx.window.sidecar là mô-đun cũ đi kèm để tương thích với các phiên bản Jetpack WindowManager cũ nhất, nhưng tệp trợ giúp không còn được duy trì tích cực.

Hình dưới đây trình bà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 tiện ích

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

Việc triển khai OEM của Tiện ích có thể cung cấp các thành phần hoặc thành phần rỗng cùng với những cách triển khai mặc định hoặc triển khai mã giả lập của các phương thức trong WindowExtensions nếu phần cứng của 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 về tính tương thích (CDD) 7.1.1.1.

Tiện ích và API Jetpack

Mô-đun Tiện ích WindowManager cung cấp giao diện API riêng ngoài các API nền tảng công khai. Mô-đun Tiện ích được phát triển công khai trong một androidx.window.extensions không dành cho nhà phát triển Thư viện Jetpack để Jetpack WindowManager (androidx.window) có thể liên kết dựa trên dữ liệu này tại thời điểm biên dịch. API Extensions thường hiển thị cung cấp các API cấp thấp hơn.

Các API mà Tiện ích cung cấp dành cho Jetpack sử dụng Chỉ dành cho thư viện WindowManager. API Tiện ích không được gọi bằng trực tiếp nhà phát triển ứng dụng. Bạn không được thêm Thư viện tiện ích làm cho một ứng dụng trong tệp bản dựng Gradle nhằm đảm bảo của Google. Tránh biên dịch trước thư viện Tiện ích vào một ứng dụng directly; thay vào đó, hãy dựa vào tính năng tải trong thời gian chạy để ngăn trường hợp tải danh sách kết hợp các lớp Tiện ích đượ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 một ứng dụng và cung cấp các API công khai dành cho nhà phát triển, bao gồm cho các tính năng của Tiện ích WindowManager. Thư viện WindowManager tự động tải Tiện ích vào quy trình đăng ký và gói cấp thấp hơn API tiện ích thành các mô hình trừu tượng cấp cao hơn và có trọng tâm hơn giao diện. API Jetpack WindowManager tuân theo các tiêu chuẩn của công nghệ hiện đại Phát triển ứng dụng Android nhằm cung cấp khả năng tương tác bằng cách tích hợp tốt với cơ sở mã sử dụng AndroidX thư viện.

Các phiên bản và bản cập nhật của tiện ích

Mô-đun Tiện ích có thể được cập nhật cùng với nền tảng Android hằng năm hoặc bản cập nhật hằng quý. Thông tin cập nhật hằng quý giúp bạn bổ sung cấp độ API Extensions tăng giữa các lần cập nhật API trên nền tảng Android, cho phép lặp lại nhanh hơn và mang đến cho nhà sản xuất thiết bị gốc (OEM) cơ hội thêm quyền truy cập API chính thức vào các tính năng mới gần với thời điểm ra mắt phần cứng.

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

Phiên bản của Nền tảng Android Cấp độ API Tiện ích WindowManager Phiên bản API androidx.window.extensions
Android 15 6 1.5.0 (sắp ra mắt)
Android 14 QPR3 5 1.4.0 (sắp ra mắt)
Android 14 QPR1 4 1.3.0
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 Extensions (cột trung tâm) được tăng lên mỗi khi có ngoài giao diện API ổn định hiện có (cột bên phải).

Khả năng tương thích ngược và tiến

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

Để ứng dụng không 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 có sẵn theo cấp độ API Extensions đã khai báo. Nếu thông tin không khớp, WindowManager có thể vô hiệu hóa việc sử dụng Tiện ích (một phần hoặc toàn bộ) và báo cáo các các tính năng không có sẵn đối với ứng dụng.

Tiện ích WindowManager được triển khai dưới dạng mô-đun system_ext sử dụng API nền tảng riêng tư để 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 của Tiện ích.

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

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

Quy trình xác minh CTS đảm bảo rằng đối với mọi phiên bản đã khai báo của API Extensions trên thiết bị, tất cả API cho phiên bản đó và phiên bản trước đó đều hiện diện và hoạt động được.

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 trình tải lớp hệ thống không phải-bootclasspath kể từ Android 14 (API cấp 34). Do đó, việc tải mô-đun vào bộ nhớ khi khởi động ứng dụng sẽ không ảnh hưởng đến hiệu suất. Việc sử dụng các tính năng riêng lẻ của mô-đun có thể ảnh hưởng đôi chút đến đặc điểm hiệu suất của ứng dụng khi thực hiện các lệnh gọi IPC khác giữa ứng dụng và máy chủ.

Mô-đun

Nhúng hoạt động

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

Thành phần nhúng hoạt động phải có trên tất 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. Bạn cũng phải bật tính năng nhúng hoạt động trên các thiết bị hỗ trợ màn hình bên ngoài các kết nối, vì ứng dụng có thể hiển thị ở kích thước lớn hơn khi được màn hình đượ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 Tiện ích mô-đun như mô tả trong Phân phối mô-đun tiện ích . Việc bật Tiện ích trên tất cả thiết bị hỗ trợ là hợp lý chế độ nhiều cửa sổ. Các phiên bản Android trong tương lai có thể sẽ tạo Tiện ích bắt buộc trên các cấu hình thiết bị cầm tay và thiết bị có màn hình lớn phổ biến.

Thông tin về 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ề vượt 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ị những thông tin được tối ưu hoá bố cục ở chế độ mặt bàn trên thiết bị có thể gập lại. Xem Giúp ứng dụng nhận biết chế độ gập để biết thông tin chi tiết về quyền sử dụng.

Thiết bị Android có thể gập lại có bản lề kết nối riêng biệt hoặc khu vực bảng điều khiển hiển thị liên tục phải cung cấp thông tin về bản lề dành cho ứng dụng thông qua WindowLayoutComponent.

Vị trí bản lề và giới hạn phải được báo cáo tương ứng với ứng dụng cửa sổ do Context truyền vào API xác định. Nếu cửa sổ ứng dụng ranh giới không giao nhau với ranh giới bản lề, bản lề DisplayFeature không được báo cáo. Bạn cũng có thể 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 một ứng dụng người dùng có thể tự do di chuyển cửa sổ ở chế độ nhiều cửa sổ hoặc chế độ hiệu ứng hòm thư tương thích.

Đối với tính năng gập, thông tin cập nhật về 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, 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 không xuất hiện hoặc không vượt quá 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 (Nhà sản xuất thiết bị gốc) phải làm những việc sau:

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

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

  • Bật mô-đun Tiện ích như được mô tả trong Mục Phân phối mô-đun tiện ích.

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

    Định dạng đúng của chuỗi là:

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

    type có thể là fold hoặc hinge. Giá trị của left, top, rightbottom là toạ độ pixel số nguyên trong không gian toạ độ hiển thị ở hướng hiển thị tự nhiên. Chuỗi cấu hình có thể chứa nhiều các 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 mối liên kết giữa các giá trị nhận dạng trạng thái thiết bị nội bộ được dùng trong DeviceStateManager và các hằng số trạng thái công khai được gửi cho nhà phát triển trong com.android.internal.R.array.config_device_state_postures.

    Định dạng hợp lệ của mỗi mục nhập là:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Sau đây là các giá trị nhận dạng trạng thái được hỗ trợ:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: Trạng thái không có tính năng gập để báo cáo. Ví dụ: đó có thể là trạng thái đóng của quảng cáo trong 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 đã mở một nửa.
    • COMMON_STATE_FLAT = 3: Tính năng gập có dạng phẳng. Ví dụ: đó 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ể dùng để mô phỏng các trạng thái mà trạng thái bản lề bắt nguồn bằng cách sử dụ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 giúp các ứng dụng quyền 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à thiết bị có nhiều màn hình.

Chế độ màn hình sau cho phép ứng dụng hiển thị giao diện người dùng của bản xem trước của máy ảnh trên màn hình che phủ của một thiết bị có thể gập lại để cho phép dùng máy ảnh chính của thiết bị cho ảnh chân dung tự chụp và video. Các thiết bị có phiên bản Android tương thích (như được xác định trong Android CDD về các thuộc tính như kích thước, mật độ và các thành phần điều hướng có sẵn) che màn hình điều chỉnh vừa với thiết bị sau camera phải cấp quyền truy cập vào chế độ màn hình sau.

Trên Android 14, chế độ màn hình kép cho phép các ứng dụng chạy trên màn hình trong của thiết bị có thể gập lại hiện thêm nội dung trên màn hình ngoài đối với những 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 quay video.

Cấu hình thiết bị

Để hỗ trợ triển khai tính năng gập, OEM (Nhà sản xuất thiết bị gốc) phải làm những việc sau:

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

    Nếu việc triển khai mặc định của DeviceStateProvider hoặc DeviceStatePolicy không phù hợp với thiết bị, thì có thể sử dụng phương thức triển khai tuỳ 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 thuộc tính tương ứng giá trị nhận dạng trạng thái trong com.android.internal.R.array.config_openDeviceStates.

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

  • Đối với các thiết bị gập hỗ trợ trạng thái gập một nửa (bản lề mở một nửa) chẳng hạn 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ế độ màn hình sau:

    • Liệt kê các trạng thái tương ứng trong com.android.internal.R.array.config_rearDisplayDeviceStates cho DeviceStateManager.
    • Hãy chỉ định địa chỉ màn hình thực tế của màn hình sau trong com.android.internal.R.string.config_rearDisplayPhysicalAddress.
    • Chỉ định giá trị nhận dạng trạng thái trong com.android.internal.R.integer.config_deviceStateRearDisplay để Tiện ích sử dụng.
    • Thêm giá trị nhận dạng trạng thái trong com.android.internal.R.array.config_deviceStatesAvailableForAppRequests để cung cấp cho ứ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.
    • Hãy chỉ định địa chỉ màn hình thực tế của màn hình sau trong com.android.internal.R.config_deviceStateConcurrentRearDisplay.
    • Chỉ định giá trị nhận dạng trạng thái trong com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay để Tiện ích sử dụng nếu giá trị nhận dạng được cung cấp cho các ứng dụng.
    • Thêm giá trị nhận dạng trạng thái trong com.android.internal.R.array.config_deviceStatesAvailableForAppRequests để cung cấp cho ứng dụng.

Xác minh

OEM phải xác minh cách triển khai để đảm bảo hành vi dự kiến chung trong trường hợp cụ thể. OEM (Nhà sản xuất thiết bị gốc) có thể kiểm thử và kiểm thử CTS bằng Jetpack WindowManager để kiểm thử việc triển khai.

Bài kiểm thử CTS

Để chạy thử nghiệm CTS, hãy xem nội dung Chạy thử nghiệm CTS. CTS (Bộ kiểm tra tính tương thích) các bài kiểm thử liên quan đến Jetpack WindowManager nằm trong cts/tests/framework/base/windowmanager/jetpack/. Tên mô-đun kiểm thử là CtsWindowManagerJetpackTestCases.

Kiểm thử WindowManager

Để tải các bài kiểm thử Jetpack WindowManager xuống, hãy làm theo Hướng dẫn về Android Jetpack. Các chương trình kiểm thử này nằm ở thư viện cửa sổ trong mô-đun window:window: window/window/src/androidTest/.

Để chạy kiểm thử thiết bị cho mô-đun window:window từ dòng lệnh, hãy thực hiện như sau:

  1. Cắm một thiết bị đã bật các tuỳ chọn cho nhà phát triển và tính năng gỡ lỗi qua USB.
  2. Cho phép máy tính gỡ lỗi thiết bị.
  3. Mở một 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 các bài kiểm thử trong Android Studio, hãy làm như sau:

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

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

Kết quả có thể được phân tích theo cách thủ công bằng cách xem xét kết quả của shell. Hơi nhiều sẽ bị bỏ qua nếu thiết bị không đáp ứng các giả định nhất định. Kết quả là được lưu ở một vị trí chuẩn và nhà phân tích có thể viết một tập lệnh để tự động hoá bản phân tích kết quả.