call overwritten super earlier to prevent NPE be thrown on calling getInsetsController()

The Activity#setContentView(int) in CaptureActivity#initializeContent() of super class needs to be called
before getInsetsController(), otherwise NPE will be thrown because the top-level view of
the current Window, containing the window decor, is not yet initialized.

FIXE #806

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
This commit is contained in:
Daniel Ziegenberg 2021-04-11 20:56:50 +02:00
parent c11a4eb56f
commit 6aa3564d0e
No known key found for this signature in database
GPG key ID: 7E6F98FFADBEFD39

View file

@ -25,9 +25,11 @@ package org.shadowice.flocke.andotp.Activities;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.view.Window;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.view.WindowInsetsController; import android.view.WindowInsetsController;
import android.view.WindowManager; import android.view.WindowManager;
import com.journeyapps.barcodescanner.CaptureActivity; import com.journeyapps.barcodescanner.CaptureActivity;
import com.journeyapps.barcodescanner.DecoratedBarcodeView; import com.journeyapps.barcodescanner.DecoratedBarcodeView;
@ -36,6 +38,25 @@ import org.shadowice.flocke.andotp.Utilities.Settings;
import java.util.Locale; import java.util.Locale;
public class SecureCaptureActivity extends CaptureActivity { public class SecureCaptureActivity extends CaptureActivity {
/**
* Overwrites {@link CaptureActivity#initializeContent()} to:
* <ul>
* <li>preventing the window from appearing in screenshots or from being viewed on
* non-secure displays, if this was enabled in the app settings.</li>
* <li>request hardware acceleration to be turned on.</li>
* <li>hide all screen decorations like navigation and status bars.</li>
* </ul>
*
* <em>
* Note:
* {@link android.app.Activity#setContentView(int)} in {@link CaptureActivity#initializeContent()}
* of super class needs to be called before {@link Window#getInsetsController()}, otherwise NPE will be thrown
* because the top-level view of the current {@link Window}, containing the window decor, is not yet initialized.
* </em>
*
* @return the DecoratedBarcodeView
*/
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected DecoratedBarcodeView initializeContent() { protected DecoratedBarcodeView initializeContent() {
@ -44,8 +65,19 @@ public class SecureCaptureActivity extends CaptureActivity {
setTheme(settings.getTheme()); setTheme(settings.getTheme());
setLocale(settings); setLocale(settings);
if (!settings.getScreenshotsEnabled()) // This flag must be set before setting the content view of the activity or dialog.
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
);
// All window flags, that must be set before the window decoration is created, are already set
// so we are safe to call super here.
DecoratedBarcodeView barcodeScannerView = super.initializeContent();
if (!settings.getScreenshotsEnabled()) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
final WindowInsetsController insetsController = getWindow().getInsetsController(); final WindowInsetsController insetsController = getWindow().getInsetsController();
@ -54,12 +86,13 @@ public class SecureCaptureActivity extends CaptureActivity {
insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
} }
} else { } else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
);
} }
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); return barcodeScannerView;
return super.initializeContent();
} }
private void setLocale(Settings settings) { private void setLocale(Settings settings) {