Repository: flutter
Issue: Android PlatformView in Hybrid mode stops rendering when rotating only on certain devices (Tablet)
Labels: e: device-specific,platform-android,engine,a: tablet,a: platform-views,c: rendering,a: layout,P2,team-android,triaged-android

In Japan we have a tablet ([d-02K](https://www.nttdocomo.co.jp/support/product/d02k/index.html)) that when you have a PlatformView in Hybrid mode rendering a video using ExoPlayer with DRM enabled on that content, and you rotate the device to change orientation, the rendering from that point on fails and a black screen is rendered instead.

This only happens on this device (so far that we know).
This also does **not** happen without flutter and just a standard kotlin android app.

Android Version: 8.0.0
CPU: Hisilicon Kirin 659

## Steps to Reproduce

1. Create an app with the below code
2. Run the app (probably only on that or similar device)
3. A Widevine DRM video will play
4. Rotate the device so as to cause an orientation change
5. Observe that rendering has failed (audio still plays)

<details>
<summary>Sample Code main.dart</summary>

```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({
    Key key,
    this.title,
  }) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const MethodChannel _channel =
      const MethodChannel('com.example/exoflutter');
  static dynamic get _createExoPlayer async {
    final dynamic result = await _channel.invokeMethod('createPlayer');
    return result;
  }

  Key _key;

  @override
  void initState() {
    super.initState();
    // Android Versionを表示する
    _createExoPlayer.then((value) => print(value));
    _key = GlobalKey();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: FutureBuilder(
        future: _createExoPlayer,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return PlatformViewLink(
              key: _key,
              viewType: 'com.exoplayer.playerview',
              surfaceFactory: (context, viewController) {
                return AndroidViewSurface(
                  controller: viewController,
                  hitTestBehavior: PlatformViewHitTestBehavior.transparent,
                  gestureRecognizers: const <
                      Factory<OneSequenceGestureRecognizer>>{},
                );
              },
              onCreatePlatformView: (params) {
                return PlatformViewsService.initSurfaceAndroidView(
                  id: params.id,
                  viewType: params.viewType,
                  layoutDirection: Directionality.of(context),
                  creationParams: const <String, dynamic>{},
                  creationParamsCodec: const StandardMessageCodec(),
                )
                  ..addOnPlatformViewCreatedListener(
                      params.onPlatformViewCreated)
                  ..create();
              },
            );
          } else {
            return Center(
              child: Text("Loading"),
            );
          }
        },
      ),
    );
  }
}
```
</details>

<details>
<summary>Sample Code build.gradle</summary>

```gradle
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 29

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.exoflutter"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }

    compileOptions {
        targetCompatibility = JavaVersion.VERSION_1_8
        sourceCompatibility = JavaVersion.VERSION_1_8
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.google.android.exoplayer:exoplayer:2.12.3'
}
```
</details>

<details>
<summary>MainActivity.kt</summary>

```kotlin
package com.example.exoflutter

import android.os.Bundle
import android.util.Log
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ui.PlayerView
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant


class MainActivity: FlutterActivity() {
    companion object {
        private const val CHANNEL_NAME = "com.example/exoflutter"
        private const val METHOD_GET_ANDROID_VERSION = "getPlatformVersion"
        private const val METHOD_CREATE_PLAYER = "createPlayer"
    }

    private lateinit var channel: MethodChannel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)

        channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME)

        channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result ->
            if (methodCall.method == METHOD_GET_ANDROID_VERSION) {
                result.success("Android ${android.os.Build.VERSION.RELEASE}")
            } else if (methodCall.method == METHOD_CREATE_PLAYER) {
                flutterEngine
                        .platformViewsController
                        .registry
                        .registerViewFactory("com.exoplayer.playerview", NativeViewFactory())
                result.success(true)
            }
            else
                result.notImplemented()
        }
    }

}
```
</details>

<details>
<summary>NativeViewFactory.kt</summary>

```kotlin
package com.example.exoflutter

import android.content.Context
import android.view.View
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory

class NativeViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        val creationParams = args as Map<String?, Any?>?
        return NativeView(context, viewId, creationParams)
    }
}
```
</details>

<details>
<summary>NativeView.kt</summary>

```kotlin
package com.example.exoflutter

import android.content.Context
import android.util.Log
import android.view.View
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ui.PlayerView
import io.flutter.plugin.platform.PlatformView


internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?) : PlatformView {
    private var simpleExoPlayer: SimpleExoPlayer? = null
    private lateinit var playerView: PlayerView

    override fun getView(): View {
        return playerView
    }

    override fun dispose() {}

    init {

        simpleExoPlayer = SimpleExoPlayer.Builder(context).build()
        playerView = PlayerView(context)
        playerView.player = simpleExoPlayer
        val mediaItem: MediaItem = MediaItem.Builder()
                .setUri("https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd")
                .setDrmUuid(C.WIDEVINE_UUID)
                .setDrmLicenseUri("https://proxy.uat.widevine.com/proxy?video_id=GTS_SW_SECURE_CRYPTO&provider=widevine_test")
                .setDrmMultiSession(true)
                .build()

        playerView.player?.setMediaItem(mediaItem)
        playerView.player?.prepare()
        playerView.player?.play()
    }
}
```
</details>

**Expected results:** The PlatformView area continues to show the video

**Actual results:** The PlatformView area goes black

<details>
  <summary>Logs</summary>

flutter run --verbose

```
[  +15 ms] E/BufferQueueProducer(19696): [ImageReader-1920x1117f1m3-19696-2] disconnect: not connected (req=1)
```
This above part is particularily suspicious. 

```
[+3316 ms] I/flutter (19696): true
[ +117 ms] W/Settings(19696): mValues not put! needsGenerationTracker: true currentGeneration: -1 name: accessibility_captioning_enabled value: null
[  +69 ms] I/HwCust  (19696): Constructor found for class android.net.HwCustConnectivityManagerImpl
[        ] D/HwCust  (19696): Create obj success use class android.net.HwCustConnectivityManagerImpl
[  +42 ms] I/ExoPlayerImpl(19696): Init 296f363 [ExoPlayerLib/2.12.3] [d-02K, d-02K, HUAWEI, 26]
[  +59 ms] D/HwGalleryCacheManagerImpl(19696): mIsEffect:false
[ +154 ms] I/zygote64(19696): Do partial code cache collection, code=27KB, data=28KB
[   +1 ms] I/zygote64(19696): After code cache collection, code=27KB, data=28KB
[        ] I/zygote64(19696): Increasing code cache capacity to 128KB
[ +258 ms] W/libEGL  (19696): EGLNativeWindowType 0x73d0f88010 disconnect failed
[        ] D/mali_winsys(19696): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000
[  +58 ms] D/mali_winsys(19696): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000
[ +938 ms] I/zygote64(19696): Do partial code cache collection, code=61KB, data=51KB
[   +1 ms] I/zygote64(19696): After code cache collection, code=61KB, data=51KB
[        ] I/zygote64(19696): Increasing code cache capacity to 256KB
[ +100 ms] W/VideoCapabilities(19696): Unrecognized profile/level 1/32 for video/mp4v-es
[        ] I/VideoCapabilities(19696): Unsupported profile 16384 for video/mp4v-es
[   +3 ms] I/VideoCapabilities(19696): Unsupported profile 16384 for video/mp4v-es
[  +13 ms] W/VideoCapabilities(19696): Unsupported mime video/x-pn-realvideo
[   +2 ms] W/VideoCapabilities(19696): Unsupported mime video/mpeg
[   +3 ms] W/VideoCapabilities(19696): Unrecognized profile/level 0/0 for video/mpeg2
[        ] W/VideoCapabilities(19696): Unrecognized profile/level 0/2 for video/mpeg2
[        ] W/VideoCapabilities(19696): Unrecognized profile/level 0/3 for video/mpeg2
[   +7 ms] W/VideoCapabilities(19696): Unrecognized profile/level 32768/2 for video/mp4v-es
[   +6 ms] W/VideoCapabilities(19696): Unsupported mime video/vc1
[   +9 ms] W/VideoCapabilities(19696): Unsupported mime video/x-flv
[  +55 ms] I/VideoCapabilities(19696): Unsupported profile 4 for video/mp4v-es
[+1854 ms] I/OMXClient(19696): Treble IOmx obtained
[ +134 ms] I/ACodec  (19696): In onAllocateComponent create compenent, codec name: OMX.google.aac.decoder
[   +5 ms] W/HwExtendedUtils(19696): hw configLocalPlayBack err = -2147483648
[  +14 ms] I/ACodec  (19696): codec does not support config priority (err -2147483648)
[   +1 ms] I/ACodec  (19696): onStart
[  +45 ms] D/ACodecBufferChannel(19696): setHeap returned mHeapSeqNum=0
[ +177 ms] I/OMXClient(19696): Treble IOmx obtained
[  +65 ms] I/ACodec  (19696): In onAllocateComponent create compenent, codec name: OMX.IMG.MSVDX.Decoder.AVC.secure
[   +2 ms] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason connectToSurface
[        ] I/MediaCodec(19696): [OMX.IMG.MSVDX.Decoder.AVC.secure] setting surface generation to 20168705
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason connectToSurface(reconnect)
[        ] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason connectToSurface(reconnect)
[   +1 ms] W/HwExtendedUtils(19696): hw configLocalPlayBack err = -1010
[        ] E/ACodec  (19696): [OMX.IMG.MSVDX.Decoder.AVC.secure] setPortMode on output to DynamicANWBuffer failed w/ err -1010
[   +1 ms] I/HwExtendedCodec(19696): mime is [video/avc] at setVideoFormat
[        ] I/ACodec  (19696): codec does not support config priority (err -1010)
[  +34 ms] I/ACodec  (19696): onStart
[ +111 ms] D/ACodecBufferChannel(19696): setHeap returned mHeapSeqNum=0
[        ] I/HwExtendedUtils(19696): error setConfig queuesToNativeWindow (err -1010)
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): set up nativeWindow 0x73c8ffb010 for 864x384, color 0x300, rotation 0, usage 0x24006900
[ +408 ms] D/AudioTrack(19696): OFFLOAD 0,mNotificationFrames 0,mStreamType =-1,mOriginalSampleRate 44100,mAfSampleRate 48000,mTransfer 3
[        ] D/AudioTrack(19696): Client defaulted notificationFrames to 3675 for frameCount 11025
[  +13 ms] I/AudioTrack(19696): audioTrack send start state to pg
[  +26 ms] I/zygote64(19696): Do full code cache collection, code=124KB, data=98KB
[        ] I/zygote64(19696): After code cache collection, code=98KB, data=57KB
[ +163 ms] I/HwExtendedUtils(19696): error setConfig queuesToNativeWindow (err -1010)
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): set up nativeWindow 0x73c8ffb010 for 864x384, color 0x300, rotation 0, usage 0x24006900
[ +170 ms] D/android.media.AudioTrack(19696): [HSM] AudioTrace play() uid: 10185, pid: 19696
[+2805 ms] I/zygote64(19696): Do partial code cache collection, code=121KB, data=87KB
[        ] I/zygote64(19696): After code cache collection, code=121KB, data=87KB
[        ] I/zygote64(19696): Increasing code cache capacity to 512KB
[+8130 ms] W/libEGL  (19696): EGLNativeWindowType 0x73d0f0c010 disconnect failed
[        ] D/mali_winsys(19696): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000
[  +40 ms] D/mali_winsys(19696): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000
[ +559 ms] E/BufferQueueProducer(19696): [ImageReader-1200x1836f1m3-19696-1] disconnect: not connected (req=1)
[        ] W/libEGL  (19696): EGLNativeWindowType 0x73cacdb010 disconnect failed
[  +29 ms] D/mali_winsys(19696): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000
[ +185 ms] I/zygote64(19696): NativeAllocBackground concurrent copying GC freed 3124(234KB) AllocSpace objects, 2(136KB) LOS objects, 49% free, 23MB/46MB, paused 2.096ms total 119.092ms
[ +337 ms] I/HwExtendedUtils(19696): error setConfig queuesToNativeWindow (err -1010)
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[   +6 ms] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason setNativeWindowSizeFormatAndUsage
[   +1 ms] D/SurfaceUtils(19696): set up nativeWindow 0x73c8ffb010 for 1280x576, color 0x300, rotation 0, usage 0x24006900
[+9297 ms] D/SurfaceUtils(19696): connecting to surface 0x73e9ead010, reason connectToSurface
[   +1 ms] I/MediaCodec(19696): [OMX.IMG.MSVDX.Decoder.AVC.secure] setting surface generation to 20168706
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73e9ead010, reason connectToSurface(reconnect)
[        ] D/SurfaceUtils(19696): connecting to surface 0x73e9ead010, reason connectToSurface(reconnect)
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73e9ead010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): connecting to surface 0x73e9ead010, reason setNativeWindowSizeFormatAndUsage
[        ] D/SurfaceUtils(19696): set up nativeWindow 0x73e9ead010 for 1280x576, color 0x300, rotation 0, usage 0x24006900
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason pushBlankBuffersToNativeWindow
[   +2 ms] D/SurfaceUtils(19696): set up nativeWindow 0x73c8ffb010 for 1x1, color 0x2, rotation 0, usage 0x930
[  +20 ms] D/SurfaceUtils(19696): connecting to surface 0x73c8ffb010, reason pushBlankBuffersToNativeWindow(err2)
[        ] D/SurfaceUtils(19696): disconnecting from surface 0x73c8ffb010, reason disconnectFromSurface
[  +41 ms] W/libEGL  (19696): EGLNativeWindowType 0x73d0f0c010 disconnect failed
[ +267 ms] W/IInputConnectionWrapper(19696): beginBatchEdit on inactive InputConnection
[        ] W/IInputConnectionWrapper(19696): endBatchEdit on inactive InputConnection
[        ] W/IInputConnectionWrapper(19696): beginBatchEdit on inactive InputConnection
[        ] W/IInputConnectionWrapper(19696): endBatchEdit on inactive InputConnection
[        ] W/IInputConnectionWrapper(19696): beginBatchEdit on inactive InputConnection
[   +1 ms] W/IInputConnectionWrapper(19696): endBatchEdit on inactive InputConnection
[+1171 ms] W/InputMethodManager(19696): startInputReason = 3
[        ] W/InputMethodManager(19696): reStartinput failed, need refresh!
[  +15 ms] E/BufferQueueProducer(19696): [ImageReader-1920x1117f1m3-19696-2] disconnect: not connected (req=1)
[        ] W/libEGL  (19696): EGLNativeWindowType 0x73d0963010 disconnect failed
[ +224 ms] Service protocol connection closed.
[   +1 ms] Lost connection to device.
[   +3 ms] executing: /Users/koji.yamada/Library/Android/sdk/platform-tools/adb -s VMT0118403000310 forward --list
[  +10 ms] Exit code 0 from: /Users/koji.yamada/Library/Android/sdk/platform-tools/adb -s VMT0118403000310 forward --list
[        ] VMT0118403000310 tcp:59108 tcp:41409
[   +1 ms] executing: /Users/koji.yamada/Library/Android/sdk/platform-tools/adb -s VMT0118403000310 forward --remove tcp:59108
[  +13 ms] DevFS: Deleting filesystem on the device (file:///data/user/0/com.example.exoflutter/code_cache/exoflutterRGTEHA/exoflutter/)
[ +261 ms] Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
[   +2 ms] executing: /Users/koji.yamada/Library/Android/sdk/platform-tools/adb -s VMT0118403000310 forward --list
[  +10 ms] Exit code 0 from: /Users/koji.yamada/Library/Android/sdk/platform-tools/adb -s VMT0118403000310 forward --list
[   +2 ms] "flutter run" took 69,578ms.
[   +3 ms] ensureAnalyticsSent: 0ms
[        ] Running shutdown hooks
[        ] Shutdown hook priority 4
[   +3 ms] Shutdown hooks complete
[        ] exiting with code 0
```

flutter doctor -v
```
[✓] Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H114 darwin-x64, locale en-CA)
    • Flutter version 1.22.4 at /Users/xxxx/source/flutter-1.22
    • Framework revision 1aafb3a8b9 (3 months ago), 2020-11-13 09:59:28 -0800
    • Engine revision 2c956a31c0
    • Dart version 2.10.4

 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/xxxx/source/android/sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = /Users/xxxxx/source/android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.
```

</details>