• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.photopicker.features.preview
18 
19 import android.os.Bundle
20 import android.provider.ICloudMediaSurfaceController
21 import android.view.Surface
22 
23 /**
24  * A wrapper class around [ICloudMediaSurfaceController].
25  *
26  * This class just proxies all calls through to the wrapped controller.
27  * Additionally, this Controller provides methods for the UI for obtaining
28  * surfaceId's and manages calling the [onPlayerCreate] and [onPlayerRelease]
29  * based on the number of active surfaces.
30  *
31  * @property wrapped the [ICloudMediaSurfaceController] to wrap.
32  */
33 class RemoteSurfaceController(private val wrapped: ICloudMediaSurfaceController) :
34     ICloudMediaSurfaceController.Stub() {
35 
36     /** The next unique surface id for this controller */
37     private var nextSurfaceId: Int = 0
38 
39     /**
40      * The total number of active surfaces for this controller.
41      * This count is increased during [onSurfaceCreated] and decreased
42      * during [onSurfaceDestroyed].
43      */
44     private var activeSurfaceCount: Int = 0
45 
46     /** Get a new surfaceId for a new player surface */
getNextSurfaceIdnull47     fun getNextSurfaceId(): Int {
48         return ++nextSurfaceId
49     }
50 
51     /**
52      * Pass through of the Surface's [onSurfaceChanged] lifecycle.
53      *
54      * Additionally, this method manages creating the player if it is required.
55      */
onSurfaceCreatednull56     override fun onSurfaceCreated(surfaceId: Int, surface: Surface, mediaId: String) {
57 
58         if (activeSurfaceCount == 0) {
59             // If this is the first surface being created for this controller,
60             // the player needs to be initialized.
61             onPlayerCreate()
62         }
63 
64         activeSurfaceCount++
65         wrapped.onSurfaceCreated(surfaceId, surface, mediaId)
66     }
67 
68     /**
69      * Pass through of the Surface's [onSurfaceChanged] lifecycle.
70      */
onSurfaceChangednull71     override fun onSurfaceChanged(surfaceId: Int, format: Int, width: Int, height: Int) {
72         wrapped.onSurfaceChanged(surfaceId, format, width, height)
73     }
74 
75     /**
76      * Pass through of the Surface's [onSurfaceDestroyed] lifecycle.
77      */
onSurfaceDestroyednull78     override fun onSurfaceDestroyed(surfaceId: Int) {
79         wrapped.onSurfaceDestroyed(surfaceId)
80 
81         if (--activeSurfaceCount == 0) {
82             // If there are no active surfaces left, release the player.
83             onPlayerRelease()
84         }
85     }
86 
onMediaPlaynull87     override fun onMediaPlay(surfaceId: Int) {
88         wrapped.onMediaPlay(surfaceId)
89     }
90 
onMediaPausenull91     override fun onMediaPause(surfaceId: Int) {
92         wrapped.onMediaPause(surfaceId)
93     }
94 
onMediaSeekTonull95     override fun onMediaSeekTo(surfaceId: Int, timestampMillis: Long) {
96         wrapped.onMediaSeekTo(surfaceId, timestampMillis)
97     }
98 
onConfigChangenull99     override fun onConfigChange(bundle: Bundle) {
100         wrapped.onConfigChange(bundle)
101     }
102 
onDestroynull103     override fun onDestroy() {
104         wrapped.onDestroy()
105     }
106 
onPlayerCreatenull107     override fun onPlayerCreate() {
108         wrapped.onPlayerCreate()
109     }
onPlayerReleasenull110     override fun onPlayerRelease() {
111         wrapped.onPlayerRelease()
112     }
113 }
114