동작 변경사항: 모든 앱

Android Q 플랫폼에는 앱에 영향을 줄 수 있는 동작 변경이 포함되어 있습니다. 다음과 같은 동작 변경사항은 'targetSdkVersion'에 상관없이 Android Q에서 실행되는 모든 앱에 적용됩니다. 이러한 변경사항을 적절히 지원해야 하는 경우 앱을 테스트한 후 필요에 따라 수정해야 합니다.

또한 Android Q를 대상으로 하는 앱에만 영향을 미치는 동작 변경사항 목록을 검토해야 합니다.

비 SDK 인터페이스 제한 사항

앱 안정성과 호환성을 보장하기 위해 플랫폼에서는 Android 9(API 레벨 28)에서 앱이 사용할 수 있는 비 SDK 인터페이스를 제한하기 시작했습니다. Android Q에는 Android 개발자와의 공동작업 및 최신 내부 테스트를 기반으로 제한된 비 SDK 인터페이스의 업데이트된 목록이 포함되어 있습니다. Google의 목표는 비 SDK 인터페이스를 제한하기 전에 공개 대안을 사용할 수 있게 하는 것입니다.

Android Q를 타겟팅하지 않을 경우, 이러한 변경사항 중 일부는 즉시 영향을 미치지 않을 수 있습니다. 그러나 현재 앱의 타겟 API 레벨에 따라 그레이리스트에 속한 비 SDK 인터페이스를 사용할 수는 있지만, 비 SDK 메소드나 필드를 사용하면 앱이 중단될 위험성이 높아집니다.

앱에서 비 SDK 인터페이스를 사용하는지 확실히 알 수 없는 경우 앱을 테스트하여 확인할 수 있습니다. 앱에서 비 SDK 인터페이스를 사용해야 하는 경우 대체 SDK로 이전을 계획해야 합니다. 그럼에도 불구하고 어떤 앱의 경우 비 SDK 인터페이스 사용에 관한 유효한 사용 사례가 있음을 알고 있습니다. 앱 기능을 구현하기 위해 비 SDK 인터페이스 대신 어떤 것을 사용해야 할지 알 수 없다면 새 공개 API를 요청해야 합니다.

자세한 내용은 Android Q의 비 SDK 인터페이스 제한사항 업데이트비 SDK 인터페이스 제한사항을 참조하세요.

NDK

Android Q에는 다음과 같은 NDK 변경사항이 있습니다.

공유 객체에는 텍스트 재배치가 포함될 수 없습니다.

Android 6.0(API 레벨 23)에서는 공유 객체에서 텍스트 재배치를 사용하는 것을 허용하지 않았습니다. 코드를 있는 그대로 로드해야 하며 수정해서는 안 됩니다. 이러한 변경사항으로 인해 앱 로드 시간과 보안이 향상되었습니다.

Android Q 베타 1 및 2에서 SELinux는 Android 8.0(API 레벨 26) 이상을 타겟팅하는 앱에 이 제한을 적용합니다. 이러한 앱에서 텍스트 재배치가 포함된 공유 객체를 계속 사용하면 중단될 위험이 높아집니다.

실행 전용 메모리에 매핑된 시스템 바이너리/라이브러리

Android Q에서 시스템 바이너리 및 라이브러리의 실행 가능 세그먼트는 코드 재사용 공격에 대비한 강화 기술인 메모리 실행 전용(읽기 불가능)으로 매핑됩니다. 실행 전용으로 표시된 메모리 세그먼트에 대한 의도적 및 비의도적 읽기로 인해 버그, 취약점 또는 의도적인 메모리 검사에서 SIGSEGV가 발생합니다.

/data/tombstones/에 있는 관련 삭제 표시 파일을 검토하여 이 변경으로 인해 충돌이 발생했는지 여부를 파악할 수 있습니다. 실행 전용 관련 충돌에는 다음과 같은 중단 메시지가 포함됩니다.

    Cause: execute-only (no-read) memory access error; likely due to data in .text.
    

이 문제를 해결하기 위해 개발자는 메모리 검사 수행과 같이 mprotect()를 호출하여 실행 전용 세그먼트를 읽기+실행으로 표시할 수 있습니다. 그러나 이를 통해 앱과 사용자를 더 잘 보호할 수 있으므로 나중에 다시 실행 전용으로 설정할 것을 적극 권장합니다.

ptrace 호출이 영향을 받지 않으므로 ptrace 디버깅에는 영향이 없습니다.

보안

Android Q에는 다음과 같은 보안 변경사항이 포함되어 있습니다.

앱 홈 디렉토리의 실행 권한이 삭제됨

Android Q를 대상으로 하는 신뢰할 수 없는 앱은 더 이상 앱의 홈 디렉토리에 있는 파일에서 exec()를 호출할 수 없습니다. 이처럼 쓰기 가능한 앱 홈 디렉토리에서 파일을 실행하는 것은 W^X 위반입니다. 앱에서는 앱의 APK 파일에 삽입된 바이너리 코드만 로드해야 합니다.

또한 Android Q를 타겟팅하는 앱은 dlopen()된 파일의 실행 코드를 메모리에서 수정할 수 없습니다. 여기에는 텍스트가 재배치된 모든 공유 객체(.so) 파일이 포함됩니다.

Wi-Fi Direct 브로드캐스트

Android Q에서 Wi-Fi Direct와 관련된 다음 브로드캐스트는 더 이상 고정되지 않습니다.

브로드캐스트가 고정되었기 때문에 등록 시 앱에서 이러한 브로드캐스트를 수신하는 데 의존한 경우 대신에 초기화 시 적절한 get() 메소드를 사용하여 정보를 얻습니다.

Wi-Fi Aware 기능

Android Q에는 Wi-Fi Aware 데이터 경로를 사용해 TCP/UDP 소켓을 간편하게 만드는 지원이 추가되었습니다. ServerSocket에 연결하는 TCP/UDP 소켓을 만들려면 클라이언트 기기에서 서버의 IPv6 주소와 포트를 알아야 합니다. 이전에는 BT 또는 Wi-Fi Aware 레이어 2 메시지 사용 등 대역 외 커뮤니케이션 또는 mDNS와 같은 다른 프로토콜을 사용하는 대역 내 검색에 필요했습니다. Android Q에서는 네트워크 설정의 일부로 정보가 전달될 수 있습니다.

서버는 다음 중 하나를 할 수 있습니다.

  • ServerSocket을 초기화하고 사용될 포트를 설정하거나 가져옵니다.
  • Wi-Fi Aware 네트워크 요청의 일부로 포트 정보를 지정합니다.

다음 코드 샘플은 네트워크 요청의 일부로 포트 정보를 지정하는 방법을 보여줍니다.

Kotlin

    val ss = ServerSocket()
    val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
      .setPskPassphrase("some-password")
      .setPort(ss.localPort)
      .build()

    val myNetworkRequest = NetworkRequest.Builder()
      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
      .setNetworkSpecifier(ns)
      .build()
    

자바

    ServerSocket ss = new ServerSocket();
    WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
      .Builder(discoverySession, peerHandle)
      .setPskPassphrase(“some-password”)
      .setPort(ss.getLocalPort())
      .build();

    NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
      .setNetworkSpecifier(ns)
      .build();
    

그런 다음 클라이언트에서 Wi-Fi Aware 네트워크 요청을 수행하여 서버에서 제공하는 IPv6 및 포트를 가져옵니다.

Kotlin


    val callback = object : ConnectivityManager.NetworkCallback() {
      override fun onAvailable(network: Network) {
        ...
      }

      override fun onLinkPropertiesChanged(network: Network,
          linkProperties: LinkProperties) {
        ...
      }

      override fun onCapabilitiesChanged(network: Network,
          networkCapabilities: NetworkCapabilities) {
        ...
        val ti = networkCapabilities.transportInfo
        if (ti is WifiAwareNetworkInfo) {
           val peerAddress = ti.peerIpv6Addr
           val peerPort = ti.port
        }
      }
      override fun onLost(network: Network) {
        ...
      }
    };

    connMgr.requestNetwork(networkRequest, callback)
    

자바

    callback = new ConnectivityManager.NetworkCallback() {
      @Override
      public void onAvailable(Network network) {
        ...
      }
      @Override
      public void onLinkPropertiesChanged(Network network,
          LinkProperties linkProperties) {
        ...
      }
      @Override
      Public void onCapabilitiesChanged(Network network,
          NetworkCapabilities networkCapabilities) {
        ...
        TransportInfo ti = networkCapabilities.getTransportInfo();
        if (ti instanceof WifiAwareNetworkInfo) {
           WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
           Inet6Address peerAddress = info.getPeerIpv6Addr();
           int peerPort = info.getPort();
        }
      }
      @Override
      public void onLost(Network network) {
        ...
      }
    };

    connMgr.requestNetwork(networkRequest, callback);
    

Go 기기의 SYSTEM_ALERT_WINDOW

Android Q(Go 버전) 기기에서 실행 중인 앱에서는 SYSTEM_ALERT_WINDOW 권한을 받을 수 없습니다. 이는 드로잉 오버레이 창에서 과도한 메모리가 사용되고, 특히 메모리가 부족한 Android 기기의 성능에 영향을 줄 수 있기 때문입니다.

Android 9 이하를 실행하는 Go 버전 기기에서 실행되는 앱에서 SYSTEM_ALERT_WINDOW 권한을 받는 경우에는 기기가 Android Q로 업그레이드되어도 앱이 권한을 유지합니다. 그러나 해당 권한이 아직 없는 앱의 경우 기기를 업그레이드한 후에는 이 권한을 부여받을 수 없습니다.

Go 기기의 앱에서 ACTION_MANAGE_OVERLAY_PERMISSION 작업과 함께 인텐트를 전송하는 경우 시스템에서는 요청을 자동으로 거부하고, 기기가 느려지므로 권한이 허용되지 않는다고 표시된 설정 화면으로 사용자를 이동합니다. Go 기기의 앱에서 Settings.canDrawOverlays()를 호출하는 경우 이 메소드에서는 항상 false를 반환합니다. 다시 말해 이 제한사항은 기기를 Q로 업그레이드하기 전에 SYSTEM_ALERT_WINDOW 권한을 받은 앱에는 적용되지 않습니다.

이전 Android 버전을 대상으로 하는 앱에 대한 경고

Android Q에서는 사용자가 Android 6.0(API 레벨 23) 이전 버전의 플랫폼을 대상으로 하는 앱을 처음으로 실행할 때 경고가 표시됩니다. 앱에서 사용자에게 권한을 허용하도록 요청하는 경우 사용자는 앱을 처음으로 실행하도록 허용하기 전에 앱의 권한을 조정할 수 있습니다.

Google Play의 대상 API 요구 사항으로 인해 사용자가 최근에 업데이트되지 않은 앱을 실행하는 경우에만 이러한 경고가 표시됩니다. 다른 스토어를 통해 배포되는 앱의 경우 2019년에 비슷한 대상 API 요구 사항을 도입할 예정입니다. 이러한 요구 사항에 대한 자세한 내용은 2019년의 대상 API 레벨 요구 사항 확장을 참조하세요.

SHA-2 CBC 암호화 제품군 제거

다음 SHA-2 CBC 암호화 제품군이 플랫폼에서 제거되었습니다.

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

이 암호화 제품군은 GCM을 사용하는 유사한 암호화 제품군보다 덜 안전하며 대부분의 서버에서는 이러한 암호화 제품군의 GCM 및 CBC 변형을 모두 지원하거나 둘 중 어느 것도 지원하지 않습니다.

앱 사용

Android Q에서는 앱 사용과 관련하여 다음과 같은 동작 변경 사항을 도입했습니다.

  • UsageStats 앱 사용량 향상 -- 이제 Android Q에서는 앱이 화면 분할 또는 PIP 모드에서 사용될 때 UsageStats로 앱 사용량을 정확하게 추적합니다. 또한 Android Q에서는 이제 인스턴트 앱 사용량을 추적할 수 있습니다.

  • 앱별 그레이 스케일 - Android Q에서는 이제 앱을 그레이 스케일 표시 모드로 설정할 수 있습니다.

  • 앱별 주의 분산 상태 - 이제 Android Q에서는 앱에 알림이 표시되지 않고 앱이 추천 앱으로 표시되지 않는 '주의 분산 상태'로 앱을 선택적으로 설정할 수 있습니다.

  • 정지 및 재생 -- Android Q에서 정지된 앱은 더 이상 오디오를 재생할 수 없습니다.

android.preference 라이브러리 지원 중단됨

android.preference 라이브러리는 이제 지원 중단되었습니다. 개발자는 Android Jetpack의 일부인 AndroidX preference 라이브러리를 대신 사용해야 합니다. 이전 및 개발 지원용 추가 리소스는 업데이트된 설정 가이드와 함께 공개 샘플 앱참조 문서를 확인하세요.

카메라 변경사항

카메라를 사용하는 많은 앱에서는 기기가 세로 모드로 구성된 경우 카메라 방향에 설명된 대로 실제 기기도 세로 방향이라고 가정합니다. 이전에는 이것이 안전한 가정이었지만 폴더블과 같은 새로운 폼 팩터가 도입됨에 따라 달라졌습니다. 기기에서는 이러한 가정으로 인해 카메라 뷰 파인더의 디스플레이가 잘못 회전하거나 확장될 수 있으며 둘 다 잘못될 수도 있습니다.

API 레벨 24 이상을 타겟팅하는 애플리케이션은 android:resizeableActivity를 명시적으로 설정하고 멀티 윈도우 작업을 처리하는 데 필요한 기능을 제공해야 합니다.

배터리 사용량 추적

Android Q부터는 주요 충전 이벤트 후 기기가 전원에서 분리될 때마다 SystemHealthManager에서 배터리 사용량 통계를 재설정합니다. 일반적으로 주요 충전 이벤트란 기기가 완전히 충전되었거나 기기의 배터리가 거의 소모된 상태에서 대부분 충전된 상태가 된 것을 말합니다.

Android Q 이전에는 배터리 수준에 거의 변화가 없어도 기기가 전원에서 분리될 때마다 배터리 사용량 통계가 재설정되었습니다.