1
0
mirror of https://github.com/nextcloud/talk-android synced 2025-07-07 21:09:46 +01:00
talk-android/app/src/main/java/com/nextcloud/talk/activities/CallBaseActivity.java
Marcel Hibbe f2e75a7b71
add workaround to start videocalls when PIP is disabled
this is a dirty workaround for issue 

Somehow onUserLeaveHint is executed when the user starts a videocall. If PIP is disabled, the logic inside enterPipMode would finish the activity right after it was started.
This workaround suppresses the execution of enterPipMode right after the activity was started.
However if a user would press the home button in the first three seconds, the call would continue in background without the ability to recover the UI.

To better fix this bug it must be found out why onUserLeaveHint is executed on start (this should not happen!).

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
2021-11-15 12:19:40 +01:00

143 lines
5.1 KiB
Java

package com.nextcloud.talk.activities;
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
import android.app.KeyguardManager;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.util.Rational;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nextcloud.talk.BuildConfig;
public abstract class CallBaseActivity extends BaseActivity {
public static final String TAG = "CallBaseActivity";
public PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
public Boolean isInPipMode = false;
long onCreateTime;
@SuppressLint("ClickableViewAccessibility")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreateTime = System.currentTimeMillis();
requestWindowFeature(Window.FEATURE_NO_TITLE);
dismissKeyguard();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (isGreaterEqualOreo() && isPipModePossible()) {
mPictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
}
}
void hideNavigationIfNoPipAvailable(){
if (!isPipModePossible()) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
suppressFitsSystemWindows();
}
}
void dismissKeyguard() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
}
void enableKeyguard() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(false);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
}
@Override
public void onStop() {
super.onStop();
if (isInPipMode) {
finish();
}
}
@Override
public void onBackPressed() {
if (isPipModePossible()) {
enterPipMode();
}
}
@Override
protected void onUserLeaveHint() {
long onUserLeaveHintTime = System.currentTimeMillis();
long diff = onUserLeaveHintTime - onCreateTime;
Log.d(TAG, "onUserLeaveHintTime - onCreateTime: " + diff);
if (diff < 3000) {
Log.d(TAG, "enterPipMode skipped");
} else {
enterPipMode();
}
}
void enterPipMode() {
enableKeyguard();
if (isGreaterEqualOreo() && isPipModePossible()) {
Rational pipRatio = new Rational(300, 500);
mPictureInPictureParamsBuilder.setAspectRatio(pipRatio);
enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
} else {
// we don't support other solutions than PIP to have a call in the background.
// If PIP is not available the call is ended when user presses the home button.
Log.d(TAG, "Activity was finished because PIP is not available.");
finish();
}
}
boolean isPipModePossible() {
if (isGreaterEqualOreo()) {
boolean deviceHasPipFeature = getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
boolean isPipFeatureGranted = appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
android.os.Process.myUid(),
BuildConfig.APPLICATION_ID) == AppOpsManager.MODE_ALLOWED;
return deviceHasPipFeature && isPipFeatureGranted;
}
return false;
}
boolean isGreaterEqualOreo(){
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
}
abstract void updateUiForPipMode();
abstract void updateUiForNormalMode();
abstract void suppressFitsSystemWindows();
}