[Android] Implement DefaultHardwareBackBtnHandler
* Regardless of whether the SDK client/consumer employs JitsiMeetActivity or JitsiMeetView, default to finishing the associated Activity upon invoking the back button (which is what Activity#onBackPressed() is documented to do). * Do not break the public API of JitsiMeetView and, thus, Jitsi Meet SDK for Android.
This commit is contained in:
parent
35dab19b30
commit
ec58aa9959
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the default behavior of <tt>JitsiMeetActivity</tt> and
|
||||||
|
* <tt>JitsiMeetView</tt> upon invoking the back button if no
|
||||||
|
* <tt>JitsiMeetView</tt> handles the invocation. For example, a
|
||||||
|
* <tt>JitsiMeetView</tt> may (1) handle the invocation of the back button
|
||||||
|
* during a conference by leaving the conference and (2) not handle the
|
||||||
|
* invocation when not in a conference.
|
||||||
|
*/
|
||||||
|
public class DefaultHardwareBackBtnHandlerImpl
|
||||||
|
implements DefaultHardwareBackBtnHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <tt>Activity</tt> to which the default handling of the back button
|
||||||
|
* is being provided by this instance.
|
||||||
|
*/
|
||||||
|
private final Activity activity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new <tt>DefaultHardwareBackBtnHandlerImpl</tt> instance to
|
||||||
|
* provide the default handling of the back button to a specific
|
||||||
|
* <tt>Activity</tt>.
|
||||||
|
*
|
||||||
|
* @param activity - the <tt>Activity</tt> to which the new instance is to
|
||||||
|
* provide the default behavior of the back button
|
||||||
|
*/
|
||||||
|
public DefaultHardwareBackBtnHandlerImpl(Activity activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* Finishes the associated <tt>Activity</tt>.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void invokeDefaultOnBackPressed() {
|
||||||
|
// Technically, we'd like to invoke Activity#onBackPressed().
|
||||||
|
// Practically, it's not possible. Fortunately, the documentation of
|
||||||
|
// Activity#onBackPressed() specifies that "[t]he default implementation
|
||||||
|
// simply finishes the current activity,"
|
||||||
|
activity.finish();
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,8 +40,7 @@ import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||||
* <tt>JKConferenceView</tt> static methods.
|
* <tt>JKConferenceView</tt> static methods.
|
||||||
*/
|
*/
|
||||||
public class JitsiMeetActivity
|
public class JitsiMeetActivity
|
||||||
extends AppCompatActivity
|
extends AppCompatActivity {
|
||||||
implements DefaultHardwareBackBtnHandler {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The request code identifying requests for the permission to draw on top
|
* The request code identifying requests for the permission to draw on top
|
||||||
|
@ -50,6 +49,12 @@ public class JitsiMeetActivity
|
||||||
private static final int OVERLAY_PERMISSION_REQUEST_CODE
|
private static final int OVERLAY_PERMISSION_REQUEST_CODE
|
||||||
= (int) (Math.random() * Short.MAX_VALUE);
|
= (int) (Math.random() * Short.MAX_VALUE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default behavior of this <tt>JitsiMeetActivity</tt> upon invoking the
|
||||||
|
* back button if {@link #view} does not handle the invocation.
|
||||||
|
*/
|
||||||
|
private DefaultHardwareBackBtnHandler defaultBackButtonImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of the {@link JitsiMeetView} which this activity will display.
|
* Instance of the {@link JitsiMeetView} which this activity will display.
|
||||||
*/
|
*/
|
||||||
|
@ -133,23 +138,23 @@ public class JitsiMeetActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called if the JS part does not handle the physical back
|
|
||||||
* button press.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void invokeDefaultOnBackPressed() {
|
|
||||||
super.onBackPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (!JitsiMeetView.onBackPressed()) {
|
if (!JitsiMeetView.onBackPressed()) {
|
||||||
// Invoke the default handler if it wasn't handled by React.
|
// JitsiMeetView didn't handle the invocation of the back button.
|
||||||
|
// Generally, an Activity extender would very likely want to invoke
|
||||||
|
// Activity#onBackPressed(). For the sake of consistency with
|
||||||
|
// JitsiMeetView and within the Jitsi Meet SDK for Android though,
|
||||||
|
// JitsiMeetActivity does what JitsiMeetView would've done if it
|
||||||
|
// were able to handle the invocation.
|
||||||
|
if (defaultBackButtonImpl == null) {
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
|
} else {
|
||||||
|
defaultBackButtonImpl.invokeDefaultOnBackPressed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +211,7 @@ public class JitsiMeetActivity
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
JitsiMeetView.onHostPause(this);
|
JitsiMeetView.onHostPause(this);
|
||||||
|
defaultBackButtonImpl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,7 +221,8 @@ public class JitsiMeetActivity
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
JitsiMeetView.onHostResume(this, this);
|
defaultBackButtonImpl = new DefaultHardwareBackBtnHandlerImpl(this);
|
||||||
|
JitsiMeetView.onHostResume(this, defaultBackButtonImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,6 @@ import android.support.annotation.Nullable;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.facebook.react.ReactInstanceManager;
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.ReactInstanceManagerBuilder;
|
|
||||||
import com.facebook.react.ReactRootView;
|
import com.facebook.react.ReactRootView;
|
||||||
import com.facebook.react.bridge.NativeModule;
|
import com.facebook.react.bridge.NativeModule;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
@ -148,11 +147,11 @@ public class JitsiMeetView extends FrameLayout {
|
||||||
* implementation.
|
* implementation.
|
||||||
*/
|
*/
|
||||||
public static boolean onBackPressed() {
|
public static boolean onBackPressed() {
|
||||||
if (reactInstanceManager != null) {
|
if (reactInstanceManager == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
reactInstanceManager.onBackPressed();
|
reactInstanceManager.onBackPressed();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,14 +185,25 @@ public class JitsiMeetView extends FrameLayout {
|
||||||
* <tt>Activity.onResume</tt> so we can do the required internal processing.
|
* <tt>Activity.onResume</tt> so we can do the required internal processing.
|
||||||
*
|
*
|
||||||
* @param activity - <tt>Activity</tt> being resumed.
|
* @param activity - <tt>Activity</tt> being resumed.
|
||||||
* @param backHandler - a <tt>DefaultHardwareBackBtnHandler</tt> which
|
|
||||||
* will handle the back button press in case there's nothing to handle on
|
|
||||||
* the JS side.
|
|
||||||
*/
|
*/
|
||||||
public static void onHostResume(Activity activity,
|
public static void onHostResume(Activity activity) {
|
||||||
DefaultHardwareBackBtnHandler backHandler) {
|
onHostResume(activity, new DefaultHardwareBackBtnHandlerImpl(activity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activity lifecycle method which should be called from
|
||||||
|
* <tt>Activity.onResume</tt> so we can do the required internal processing.
|
||||||
|
*
|
||||||
|
* @param activity - <tt>Activity</tt> being resumed.
|
||||||
|
* @param defaultBackButtonImpl - a <tt>DefaultHardwareBackBtnHandler</tt>
|
||||||
|
* to handle invoking the back button if no <tt>JitsiMeetView</tt> handles
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
public static void onHostResume(
|
||||||
|
Activity activity,
|
||||||
|
DefaultHardwareBackBtnHandler defaultBackButtonImpl) {
|
||||||
if (reactInstanceManager != null) {
|
if (reactInstanceManager != null) {
|
||||||
reactInstanceManager.onHostResume(activity, backHandler);
|
reactInstanceManager.onHostResume(activity, defaultBackButtonImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue