···5555 * Destroy the native handle for the custom surface.
5656 *
5757 * Depending on the state, this may not necessarily destroy the underlying
5858- * surface, if other references exist.
5858+ * surface, if other references exist. However, a flag will be set to indicate
5959+ * that native code is done using it.
5960 *
6061 * @param ptr_custom_surface Pointer to the opaque pointer: will be set to NULL.
6162 *
···43434444 /// Guards currentSurfaceHolder
4545 private final Object currentSurfaceHolderSync = new Object();
4646+ /// Guards the usedByNativeCode flag
4747+ private final Object usedByNativeCodeSync = new Object();
4648 private final Method viewSetSysUiVis;
4949+4750 public int width = -1;
4851 public int height = -1;
4952 public int format = -1;
50535154 /// Guarded by currentSurfaceHolderSync
5255 private SurfaceHolder currentSurfaceHolder = null;
5656+ /// Guarded by usedByNativeCodeSync
5757+ private boolean usedByNativeCode = false;
53585459 private MonadoView(Activity activity) {
5560 super(activity);
···124129 }
125130 }
126131 }
132132+ if (ret != null) {
133133+ synchronized (usedByNativeCodeSync) {
134134+ usedByNativeCode = true;
135135+ usedByNativeCodeSync.notifyAll();
136136+ }
137137+ }
127138 return ret;
128139 }
129140141141+ /**
142142+ * Change the flag and notify those waiting on it, to indicate that native code is done with
143143+ * this object.
144144+ * <p>
145145+ * Called by native code!
146146+ */
147147+ @Keep
148148+ public void markAsDiscardedByNative() {
149149+150150+ synchronized (usedByNativeCodeSync) {
151151+ if (!usedByNativeCode) {
152152+ Log.w(TAG, "This should not have happened: Discarding by native code, but not marked as used!");
153153+ }
154154+ usedByNativeCode = false;
155155+ usedByNativeCodeSync.notifyAll();
156156+ }
157157+158158+ }
159159+130160 private boolean makeFullscreen() {
131161 if (activity == null) {
132162 return false;
···190220191221 @Override
192222 public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
193193- //! @todo this function should block until the surface is no longer used in the native code.
194223 Log.i(TAG, "surfaceDestroyed: Lost our surface.");
224224+ boolean lost = false;
195225 synchronized (currentSurfaceHolderSync) {
196226 if (surfaceHolder == currentSurfaceHolder) {
197227 currentSurfaceHolder = null;
228228+ lost = true;
229229+ }
230230+ }
231231+ if (lost) {
232232+ //! @todo this function should notify native code that the surface is gone.
233233+ try {
234234+ synchronized (usedByNativeCodeSync) {
235235+ while (usedByNativeCode) {
236236+ usedByNativeCodeSync.wait();
237237+ }
238238+ }
239239+ } catch (InterruptedException e) {
240240+ e.printStackTrace();
241241+ Log.i(TAG,
242242+ "Interrupted in surfaceDestroyed while waiting for native code to finish up: " + e.toString());
198243 }
199244 }
200245 }