Xóa gói cho Người dùng hệ thống

Bài viết này mô tả cách cải thiện hiệu suất bằng cách xác định và xóa các gói không cần thiết cho Người dùng hệ thống.

Vô hiệu hóa các gói không cần thiết

Trong Ô tô, Người dùng hệ thống không có đầu , nghĩa là Người dùng hệ thống không nhằm mục đích để con người sử dụng hoặc truy cập trực tiếp. Do đó, nhiều ứng dụng và dịch vụ không cần chạy trong Người dùng hệ thống và có thể bị tắt để cải thiện hiệu suất. Do đó, một tùy chọn được cung cấp để xóa các ứng dụng không cần thiết cho Người dùng hệ thống (Người dùng 0).

Trên trang này, hai loại Người dùng được thảo luận:

  • HỆ THỐNG . Luôn là người dùng 0
  • ĐẦY . Người dùng dự kiến ​​sẽ được sử dụng bởi con người (Người dùng không thuộc hệ thống), Người dùng 10+

Android 11

Trong Android 11, bạn thay đổi cấu hình config_userTypePackageWhitelistMode . Cờ có thể được kết hợp. Trong trường hợp này, 5 tương đương với 1 cộng 4 (sự kết hợp của cờ 14 ).

Lá cờ Sự miêu tả
0 Tắt danh sách cho phép. Cài đặt tất cả các gói hệ thống; không đăng nhập.
1 Thi hành. Chỉ cài đặt các gói hệ thống khi chúng nằm trong danh sách cho phép.
2 Đăng nhập các gói không được phép.
4 Bất kỳ gói nào không được đề cập trong tệp danh sách cho phép đều được đưa vào danh sách cho phép hoàn toàn đối với tất cả người dùng.
8 Tương tự như 4 , dành cho người dùng Hệ thống.
16 Bỏ qua OTA. Không cài đặt các gói hệ thống trong thời gian OTA.
Hãy xem xét những tình huống phổ biến này.
  • Để bật một tính năng cho danh sách cho phép hoàn chỉnh, 1 ( thực thi đầy đủ )
  • Để bật một tính năng cho danh sách cho phép chưa hoàn chỉnh, 5
  • Để kích hoạt một tính năng cho người dùng SYSTEM nhằm dễ dàng phát triển cục bộ, 9 ( danh sách cho phép ngầm định )
  • Để tắt một tính năng như thể nó chưa từng được bật, 16
  • Để tắt một tính năng và hoàn tác tất cả các hiệu ứng trước đó, 0

Đảm bảo cài đặt tệp XML trong thư mục sysconfig cho thiết bị (đây chính là thư mục chứa tệp makefile (`.mk`) được sử dụng để xây dựng hình ảnh hệ thống cho thiết bị). Khi bạn đặt tên cho tệp XML, hãy bao gồm vị trí mà gói được xác định trong tệp build. Ví dụ: preinstalled-packages-product-car-CAR_PRODUCT_NAME.xml .

<!- this package will be installed for both FULL and SYSTEM user -->
    <install-in-user-type package="com.android.bluetooth"->
        <install-in user-type="FULL" /->
        <install-in user-type="SYSTEM" /->
    </install-in-user-type->

<!- this package will only be installed for both FULL user -->
    <install-in-user-type package="com.android.car.calendar"->
        <install-in user-type="FULL" >
    </install-in-user-type->

Android 9 và Android 10

Để định cấu hình tính năng này trong Android 9 và Android 10:

  1. Xếp chồng cấu hình config_systemUserPackagesBlacklistSupported từ frameworks/base/core/res/res/values/config.xml và đặt nó thành true . Theo mặc định, khi tính năng này được bật, tất cả các gói sẽ được cài đặt cho cả Người dùng Hệ thống và Người dùng ĐẦY ĐỦ.
  2. Tạo danh sách tệp config.xml những gói nào sẽ bị vô hiệu hóa đối với Người dùng Hệ thống. Ví dụ:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
    
  3. Thêm một dòng vào device.mk để sao chép tệp vào thư mục đích của thiết bị system/etc/sysconfig/ . Ví dụ:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml
    

Xác minh kết quả

Để xác minh kết quả, hãy chạy:

$ adb shell dumpsys user | grep PACKAGE_SUBSTRING
$ adb shell pm list packages --user USER_ID PACKAGE_SUBSTRING
$ adb shell cmd user report-system-user-package-whitelist-problems

tiền đề

Để xác định xem có nên cài đặt gói trong Người dùng hệ thống hay không, hãy kiểm tra tệp AndroidManifest.xml của gói nằm ở thư mục gốc của nguồn dự án, bao gồm các thuộc tính của ứng dụng và các thành phần của ứng dụng, bao gồm tất cả các hoạt động, dịch vụ, bộ thu quảng bá, và các nhà cung cấp nội dung. Để tìm hiểu thêm, hãy xem Tổng quan về bản kê khai ứng dụng .

Vô hiệu hóa quy trình làm việc của gói

Hình 1. Vô hiệu hóa quy trình làm việc của gói

Cấp 1, cấp ứng dụng

1. Kiểm tra xem ứng dụng (hoặc thành phần ứng dụng) có được khai báo dưới dạng đơn lẻ không

Nếu ứng dụng là một ứng dụng đơn lẻ thì hệ thống sẽ chỉ khởi tạo ứng dụng trong Người dùng hệ thống. Có khả năng ứng dụng này được dự định trở thành một ứng dụng nhận biết được nhiều người dùng. Để tìm hiểu thêm về các ứng dụng nhận biết nhiều người dùng, hãy xem Xây dựng ứng dụng nhận biết nhiều người dùng .

  1. Kiểm tra tệp kê khai Android để biết android:singleUser="true" .
  2. Nếu đúng , hãy đưa vào danh sách cho phép. Cần thiết cho người dùng hệ thống.
  3. Nếu sai , hãy tiếp tục. Kiểm tra các tiêu chí khác trước khi loại bỏ.

2. Kiểm tra xem ứng dụng có yêu cầu quyền truy cập vào bộ nhớ được bảo vệ hay không

Nhiều dịch vụ khởi động hệ thống thường dựa vào bộ lưu trữ được mã hóa thiết bị (DE) thay vì bộ lưu trữ được mã hóa thông tin xác thực (CE). Ngoài ra, các ứng dụng hệ thống có khả năng khởi động trực tiếp cũng dựa vào bộ lưu trữ được mã hóa của thiết bị. Để tìm hiểu thêm về các ứng dụng nhận biết khởi động trực tiếp, hãy xem Hỗ trợ khởi động trực tiếp trong ứng dụng hệ thống .

  1. Kiểm tra tệp kê khai Android để biết android:defaultToDeviceProtectedStorage="true" , ​​tệp này cần thiết cho nhiều dịch vụ khởi động hệ thống.
  2. Nếu đúng , hãy đưa vào danh sách cho phép.
  3. Nếu sai , hãy tiếp tục.

Cấp 2, thành phần ứng dụng

Các hoạt động

Để tìm hiểu thêm về các hoạt động, hãy xem Giới thiệu về Hoạt động .

Một. Kiểm tra xem ứng dụng chỉ chứa các hoạt động

Các hoạt động hướng tới giao diện người dùng. Vì Người dùng hệ thống không có đầu trong Ô tô nên không có con người nào được phép tương tác với Người dùng hệ thống. Do đó, nếu ứng dụng chỉ chứa Hoạt động thì rất có thể ứng dụng đó không liên quan đến Người dùng hệ thống.

Kiểm tra mức độ ưu tiên và đặc quyền.

  1. Nếu , có lẽ cần thiết đối với Người dùng Hệ thống.
  2. Nếu Không , không đưa vào danh sách cho phép đối với Người dùng hệ thống.

Ví dụ: Bộ kiểm tra khả năng tương thích (CTS) ( com.android.cts.priv.ctsshim ) chỉ chứa Hoạt động và Hoạt động được xác định để kiểm tra các bộ lọc ý định. Tuy nhiên, vì nó có đặc quyền cao nên nó cần được cài đặt cho Người dùng Hệ thống nhằm mục đích thử nghiệm.

Dịch vụ

Để tìm hiểu thêm về dịch vụ, hãy xem Tổng quan về dịch vụ .

b. Kiểm tra xem dịch vụ có được khai báo là riêng tư và không thể truy cập được từ các ứng dụng khác không

Nếu dịch vụ được khai báo là riêng tư thì các gói khác sẽ không sử dụng dịch vụ. Hãy tìm android:exported="false" . Nếu dịch vụ được khai báo là riêng tư hoặc không thể truy cập được từ các ứng dụng khác thì dịch vụ đó không thể bị ràng buộc bởi các ứng dụng khác. Do đó, Bước C và Bước D dưới đây không liên quan. Do đó, thành phần này sẽ không cung cấp thêm gợi ý về việc liệu Người dùng hệ thống có cần dịch vụ này hay không.

  1. Nếu , hãy kiểm tra thành phần tiếp theo.
  2. Nếu Không , tiếp tục kiểm tra thành phần này.

c. Kiểm tra xem các ứng dụng được cài đặt trong Người dùng hệ thống có thể liên kết với dịch vụ này không

Kiểm tra các gói có trong danh sách cho phép ở Cấp 1 và xác định các dịch vụ mà gói đó bị ràng buộc. Theo dõi từ bộ lọc ý định trong dịch vụ này và startService trong các gói khác.

Nếu dịch vụ này được liên kết với các ứng dụng được cài đặt trong Người dùng hệ thống (ví dụ: com.android.car.companiondevicesupport được đưa vào danh sách cho phép chạy trong Người dùng hệ thống), thì hãy đưa dịch vụ đó vào danh sách cho phép.

  1. Nếu , danh sách cho phép.
  2. Nếu Không , tiếp tục kiểm tra thành phần này.

d. Kiểm tra xem dịch vụ có bị ràng buộc với các ứng dụng khác và được khai báo là chạy ở nền trước không

Hãy tìm startForeground . Điều này có nghĩa là mọi người sẽ tương tác với ứng dụng ở nền trước. Rất có thể, Người dùng hệ thống sẽ không cần đến dịch vụ này và không cần đưa vào danh sách cho phép.

  1. Nếu , không đưa vào danh sách cho phép.
  2. Nếu Không , tiếp tục kiểm tra thành phần tiếp theo.

đ. Kiểm tra xem dịch vụ có được xác định để chạy trong quy trình hệ thống không

Trong AndroidManifest, hãy tìm android:process="system" .
Nếu dịch vụ được cố ý xác định để chạy trong quy trình hệ thống thì điều đó có nghĩa là dịch vụ đó rõ ràng sẽ chạy trong cùng quy trình với dịch vụ hệ thống và phải được đưa vào danh sách cho phép để chạy trong Người dùng hệ thống. Là một phần trong thiết kế phân bổ bộ nhớ của Android, các dịch vụ hệ thống là một số quy trình cuối cùng bị loại bỏ, điều này ngụ ý tầm quan trọng của các dịch vụ được xác định bằng thuộc tính như vậy. Để tìm hiểu thêm về thiết kế phân bổ bộ nhớ của Android, hãy xem Giải pháp tiêu diệt bộ nhớ thấp .

  1. Nếu , không đưa vào danh sách cho phép.
  2. Nếu Không , tiếp tục kiểm tra các thành phần khác.

Ví dụ: gói com.android.networkstack.inprocess phải được đưa vào danh sách cho phép vì gói này chứa RegularMaintenanceJobService , có thẻ android:process="system" .

Nhà cung cấp nội dung

Để tìm hiểu thêm về nhà cung cấp nội dung, hãy xem Nhà cung cấp nội dung .

f. Kiểm tra xem ứng dụng được cài đặt trong Người dùng hệ thống có phụ thuộc vào nhà cung cấp này không

Kiểm tra các gói có trong danh sách cho phép ở Cấp độ 1 và kiểm tra xem chúng phụ thuộc vào nhà cung cấp nào. Nếu một ứng dụng chạy trong Người dùng hệ thống (ví dụ: com.android.car.companiondevicesupport được đưa vào danh sách cho phép chạy trong Người dùng hệ thống) và phụ thuộc vào nhà cung cấp nội dung này, thì hãy đảm bảo rằng nhà cung cấp nội dung này cũng nằm trong danh sách cho phép.

  1. Nếu , danh sách cho phép.
  2. Nếu Không , không đưa vào danh sách cho phép.

Ví dụ: nếu com.android.car.EXAMPLE chứa các nhà cung cấp đơn lẻ ( SystemActionsContentProviderManagedProvisioningActionsContentProvider ), thì nó phải được đưa vào danh sách cho phép đối với Người dùng hệ thống. Sau đó, nếu com.android.car.EXAMPLE phụ thuộc vào android.webkit cho WebViewFactoryProvider thì com.android.webview phải được đưa vào danh sách cho phép đối với Người dùng hệ thống vì nó tải android.webkit .

Hướng dẫn gói mẫu

Ví dụ sau đây cho thấy cách đánh giá AndroidManifest.xml của một gói:

<?xml version="1.0" encoding="utf-8"?>
<!-- 1. Search in the entire manifest for singleUser attribute.
No. Move to step 2 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.providers.calendar"
        android:sharedUserId="android.uid.calendar">
    We can ignore the entire permission section
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    ...
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<!-- 2. Look for defaultToDeviceProtectedStorage in application's attribute.
No. Continue evaluating app components. -->
    <application android:label="@string/calendar_storage"
                 android:allowBackup="false"
                 android:icon="@drawable/app_icon"
                 android:usesCleartextTraffic="false">
<!-- a. Contain only activities?
No. Continue to evaluate components other than activities. -->
        <provider android:name="CalendarProvider2" android:authorities="com.android.calendar"
                <!-- b. Is this component exported?
                Yes. Continue evaluating this component.
                f. App on u0 might depend on this? Search for CalendarProvider2 in dumpsys, shows ContentProviderRecord{b710923 u0 com.android.providers.calendar/.CalendarProvider2}
                Yes. Whitelist for system user. -->
                android:label="@string/provider_label"
                android:multiprocess="false"
                android:exported="true"
                android:readPermission="android.permission.READ_CALENDAR"
                android:writePermission="android.permission.WRITE_CALENDAR" />

<activity android:name="CalendarContentProviderTests" android:label="Calendar Content Provider" android:exported="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.UNIT_TEST" /> </intent-filter> </activity> <!-- Not service/content provider. Ignore. --> <receiver android:name="CalendarProviderBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.android.providers.calendar.intent.CalendarProvider2"/> <category android:name="com.android.providers.calendar"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.EVENT_REMINDER"/> <data android:scheme="content" /> </intent-filter> </receiver> <service android:name="CalendarProviderIntentService"/> </application> </manifest>