Android 11은 product
파티션을 번들 해제하여 system
및 vendor
파티션과 독립적으로 만듭니다. 이러한 변경의 일환으로 이제 product
파티션의 네이티브 및 자바 인터페이스 액세스를 제어할 수 있습니다. 이는 인터페이스 적용이 vendor
파티션에 작동하는 방식과 유사합니다.
네이티브 인터페이스 적용
네이티브 인터페이스 적용을 사용 설정하려면 PRODUCT_PRODUCT_VNDK_VERSION
을 current
로 설정합니다. 버전은 타겟의 배송 API 수준이 29보다 클 때 current
로 자동 설정됩니다. 적용에서는 다음이 허용됩니다.
product
파티션의 네이티브 모듈이 다음에 연결할 수 있습니다.- 정적, 공유 또는 헤더 라이브러리가 포함된
product
파티션의 다른 모듈에 정적 또는 동적으로 연결할 수 있습니다. system
파티션의 VNDK 라이브러리에 동적으로 연결할 수 있습니다.
- 정적, 공유 또는 헤더 라이브러리가 포함된
product
파티션에 있는 번들 해제된 APK의 JNI 라이브러리가/product/lib
또는/product/lib64
의 라이브러리에 연결할 수 있습니다(NDK 라이브러리에 추가됨).
적용에서는 product
파티션 외에 다른 파티션 링크를 허용하지 않습니다.
빌드 시간 적용(Android.bp)
Android 11에서는 시스템 모듈이 코어 및 공급업체 이미지 변형 외에도 제품 이미지 변형을 만들 수 있습니다. 네이티브 인터페이스 적용이 사용 설정될 때(PRODUCT_PRODUCT_VNDK_VERSION
이 current
로 설정됨):
product
파티션의 네이티브 모듈은 코어 변형이 아닌 제품 변형에 있습니다.Android.bp
파일의vendor_available: true
가 있는 모듈은 제품 변형과 공급업체 변형에서 사용할 수 있습니다.product_specific: true
를 지정하는 라이브러리나 바이너리는Android.bp
파일에서product_specific: true
나vendor_available: true
를 지정하는 다른 라이브러리에 연결할 수 있습니다.product
바이너리가 VNDK 라이브러리에 연결할 수 있도록 VNDK 라이브러리는Android.bp
파일에vendor_available: true
가 있어야 합니다.
다음 표에는 이미지 변형을 만드는 데 사용되는 Android.bp
속성이 요약되어 있습니다.
Android.bp의 속성 | 생성된 변형 | |
---|---|---|
적용 전 | 적용 후 | |
기본값(없음) | 코어
( |
코어
( |
system_ext_specific: true |
코어 | 코어 |
product_specific: true |
코어 | 제품 |
vendor: true |
공급업체 | 공급업체 |
vendor_available: true |
코어, 공급업체 | 코어, 제품, 공급업체 |
system_ext_specific: true 및 vendor_available:
true |
코어, 공급업체 | 코어, 제품, 공급업체 |
product_specific: true 및 vendor_available:
true |
코어, 공급업체 | 제품, 공급업체 |
빌드 시간 적용(Android.mk)
네이티브 인터페이스 적용이 사용 설정된 경우 product
파티션에 설치된 네이티브 모듈에는 다른 native:product
나 native:vndk
모듈에만 연결할 수 있는 native:product
링크 유형이 있습니다. 이러한 모듈 외 다른 모듈에 연결하려고 하면 빌드 시스템에서 링크 유형 확인 오류가 발생합니다.
런타임 적용
네이티브 인터페이스 적용이 사용 설정되면 Bionic 링커의 링커 구성이 시스템 프로세스가 product
라이브러리를 사용하도록 허용하지 않으므로 product
파티션 외부의 라이브러리에 연결할 수 없는 product
프로세스의 product
섹션을 만듭니다(그러나 이러한 프로세스는 VNDK 라이브러리에는 연결할 수 있음). 런타임 링크 구성을 위반하려고 하면 프로세스가 실패하고 CANNOT LINK EXECUTABLE
오류 메시지가 생성됩니다.
자바 인터페이스 적용
자바 인터페이스 적용을 사용 설정하려면 PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
를 true
로 설정합니다. 값은 타겟의 배송 API 수준이 29보다 클 때 true
로 자동 설정됩니다. 사용 설정되면 적용은 다음 액세스를 허용하거나 허용하지 않습니다.
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
공개 API | |||||
@SystemApi | |||||
@hide API |
vendor
파티션에서와 같이 product
파티션의 앱이나 자바 라이브러리는 공개 및 시스템 API만 사용할 수 있습니다. 숨겨진 API를 사용하는 라이브러리에 연결하는 것은 허용되지 않습니다. 이러한 제한에는 빌드 시간에 연결과 런타임에 리플렉션이 포함됩니다.
빌드 시간 적용
빌드 시간에 Make와 Soong은 platform_apis
및 sdk_version
필드를 확인하여 product
파티션의 자바 모듈이 숨겨진 API를 사용하지 않는지 확인합니다. product
파티션에 있는 앱의 sdk_version
은 API의 current
, system_current
또는 숫자 버전으로 채워져야 하고 platform_apis
필드는 비어 있어야 합니다.
런타임 적용
Android 런타임은 product
파티션의 앱이 리플렉션 등 숨겨진 API를 사용하지 않는지 확인합니다. 자세한 내용은 비 SDK 인터페이스 제한사항을 참고하세요.
제품 인터페이스 적용 사용 설정
이 섹션의 단계를 따라 제품 인터페이스 적용을 사용 설정하세요.
단계 | 작업 | 필수 |
---|---|---|
1 | system 파티션의 패키지를 지정하는 자체 시스템 makefile을 정의하고 device.mk 에서 아티팩트 경로 요구사항 확인을 설정합니다(system 파티션에 시스템이 아닌 모듈이 설치되는 것을 방지하기 위함). |
아니요 |
2 | 허용 목록을 정리합니다. | 아니요 |
3 | 네이티브 인터페이스를 적용하고 런타임 링크 실패를 식별합니다(자바 적용과 동시에 실행할 수 있음). | 예 |
4 | 자바 인터페이스를 적용하고 런타임 동작을 확인합니다(네이티브 적용과 동시에 실행할 수 있음). | 예 |
5 | 런타임 동작을 확인합니다. | 예 |
6 | 제품 인터페이스 적용으로 device.mk 를 업데이트합니다. |
예 |
1단계: makefile 만들기 및 아티팩트 경로 확인 사용 설정
이 단계에서는 system
makefile을 정의합니다.
system
파티션의 패키지를 정의하는 makefile을 만듭니다. 예를 들어 다음을 사용하여oem_system.mk
파일을 만듭니다.$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk) # Applications PRODUCT_PACKAGES += \ CommonSystemApp1 \ CommonSystemApp2 \ CommonSystemApp3 \ # Binaries PRODUCT_PACKAGES += \ CommonSystemBin1 \ CommonSystemBin2 \ CommonSystemBin3 \ # Libraries PRODUCT_PACKAGES += \ CommonSystemLib1 \ CommonSystemLib2 \ CommonSystemLib3 \ PRODUCT_SYSTEM_NAME := oem_system PRODUCT_SYSTEM_BRAND := Android PRODUCT_SYSTEM_MANUFACTURER := Android PRODUCT_SYSTEM_MODEL := oem_system PRODUCT_SYSTEM_DEVICE := generic # For system-as-root devices, system.img should be mounted at /, so we # include ROOT here. _my_paths := \ $(TARGET_COPY_OUT_ROOT)/ \ $(TARGET_COPY_OUT_SYSTEM)/ \ $(call require-artifacts-in-path, $(_my_paths),)
device.mk
파일에서system
파티션의 공통 makefile을 상속하고 아티팩트 경로 요구사항 확인을 사용 설정합니다. 예:$(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk) # Enable artifact path requirements checking PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
아티팩트 경로 요구사항 정보
PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
가 true
나 strict
로 설정되면 빌드 시스템은 다른 makefile에서 정의된 패키지가 require-artifacts-in-path
에서 정의된 경로에 설치되는 것을 방지하고 또한 현재 makefile에서 정의된 패키지가 require-artifacts-in-path
에서 정의된 경로 외부에 아티팩트를 설치하는 것을 방지합니다.
위의 예에서 PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
가 strict
로 설정되면 oem_system.mk
외부의 makefile에는 root
또는system
파티션에 설치된 모듈이 포함될 수 없습니다. 이러한 모듈을 포함하려면 oem_system.mk
파일 자체 또는 포함된 makefile에서 모듈을 정의해야 합니다.
허용되지 않은 경로에 모듈을 설치하려고 하면 빌드가 중단됩니다. 중단 문제를 해결하려면 다음 중 하나를 실행하세요.
옵션 1:
oem_system.mk
에 포함된 makefile에 시스템 모듈을 포함합니다. 이렇게 하면 아티팩트 경로 요구사항이 충족되어(모듈이 이제 포함된 makefile에 있으므로) `require-artifacts-in-path의 경로 집합에 설치할 수 있습니다.옵션 2:
system_ext
또는product
파티션에 모듈을 설치합니다.system
파티션에는 모듈을 설치하지 않습니다.옵션 3:
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
에 모듈을 추가합니다. 여기에는 설치가 허용된 모듈이 나열되어 있습니다.
2단계: 허용 목록 비우기
이 단계에서는 oem_system.mk
를 공유하는 모든 기기가 단일 system
이미지도 공유할 수 있도록 PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
를 비웁니다. 허용 목록을 비우려면 목록의 모듈을 system_ext
또는 product
파티션으로 이동하거나 system
makefile에 추가합니다. 이 단계는 선택사항입니다. 공통 system
이미지를 정의하는 것은 제품 인터페이스 적용을 사용 설정하는 데 필요하지 않기 때문입니다. 그러나 허용 목록을 비우는 것은 system_ext
로 system
경계를 정의하는 데 도움이 됩니다.
3단계: 네이티브 인터페이스 적용
이 단계에서는 PRODUCT_PRODUCT_VNDK_VERSION := current
를 설정하고 빌드 및 런타임 오류를 찾아 해결합니다. 기기 부팅 및 로그를 확인하고 런타임 링크 실패를 찾아 해결하려면 다음을 실행하세요.
PRODUCT_PRODUCT_VNDK_VERSION := current
를 설정합니다.기기를 빌드하고 빌드 오류를 찾습니다. 누락된 제품 변형이나 코어 변형의 몇 가지 빌드 중단이 발생할 수 있습니다. 일반적인 중단은 다음과 같습니다.
product_specific: true
가 있는 모든hidl_interface
모듈은 시스템 모듈에서 사용할 수 없습니다. 이 오류를 해결하려면product_specific: true
를system_ext_specfic: true
로 바꿉니다.- 모듈에는 제품 모듈에 필요한 제품 변형이 누락되어 있을 수 있습니다. 이 오류를 해결하려면
vendor_available: true
를 설정하여 이 모듈을product
파티션에서 사용할 수 있도록 하거나product_specific: true
를 설정하여 모듈을product
파티션으로 이동합니다.
빌드 오류를 해결하고 기기가 성공적으로 빌드되는지 확인합니다.
이미지를 플래시하고 기기 부팅 및 로그에서 런타임 오류를 찾습니다.
- 테스트 사례 로그의
linker
태그에CANNOT LINK EXECUTABLE
메시지가 표시되면 makefile에 종속 항목이 누락되어 있습니다(빌드 시간에 캡처되지 않았음). - 빌드 시스템에서 이를 확인하려면 필수 라이브러리를
shared_libs:
또는required:
필드에 추가합니다.
- 테스트 사례 로그의
위의 안내에 따라 누락된 종속 항목 문제를 해결합니다.
4단계: 자바 인터페이스 적용
이 단계에서는 PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
를 설정하고 결과로 생긴 빌드 오류를 찾아 해결합니다. 다음 두 가지 특정 유형의 오류를 찾으세요.
링크 유형 오류. 이 오류는 앱이 더 광범위한
sdk_version
이 있는 자바 모듈에 연결된다고 나타냅니다. 오류를 해결하려면 앱의sdk_version
을 확장하거나 라이브러리의sdk_version
을 제한하면 됩니다. 오류 예:error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
기호 오류. 이 오류는 기호가 숨겨진 API에 있어서 찾을 수 없다고 나타냅니다. 오류를 해결하려면 표시되는(숨겨지지 않음) API를 사용하거나 대안을 찾습니다. 오류 예:
frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader( ^ symbol: class ProxyAuthenticate location: class SipSessionGroup.SipSessionImpl
5단계: 런타임 동작 확인
이 단계에서는 런타임 동작이 예상대로 작동하는지 확인합니다. 디버그 가능한 앱의 경우 앱이 숨겨진 API를 사용할 때 로그를 생성하는 StrictMode.detectNonSdkApiUsage
를 사용하여 로그를 통해 숨겨진 API 사용을 모니터링할 수 있습니다. 또는 veridex 정적 분석 도구를 사용하여 사용 유형(연결 또는 리플렉션), 제한 수준, 호출 스택을 가져올 수 있습니다.
veridex 구문:
./art/tools/veridex/appcompat.sh --dex-file={apk file}
veridex 결과 예:
#1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s): Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s): Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
veridex 사용에 관한 자세한 내용은 veridex 도구를 사용하여 테스트를 참고하세요.
6단계: device.mk 업데이트
빌드 및 런타임 실패를 모두 해결하고 런타임 동작이 예상대로 작동하는지 확인한 후 device.mk
에서 다음을 설정합니다.
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true