From f44199be30155f9dd1ce548f3463d84d3c57679b Mon Sep 17 00:00:00 2001 From: Justin Nesselrotte Date: Sat, 7 Sep 2019 13:32:29 -0600 Subject: [PATCH] Enabling a little more kiosk security --- app/src/main/AndroidManifest.xml | 3 +- .../java/org/denhac/kiosk/KioskActivity.java | 116 ++++++++++++++++++ .../java/org/denhac/kiosk/MainActivity.java | 3 +- .../org/denhac/kiosk/WebViewActivity.java | 3 +- .../java/org/denhac/kiosk/WifiActivity.java | 4 +- .../denhac/kiosk/events/EventsActivity.java | 4 +- 6 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/org/denhac/kiosk/KioskActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 06e12b3..b79ad7b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,9 +30,10 @@ + - + \ No newline at end of file diff --git a/app/src/main/java/org/denhac/kiosk/KioskActivity.java b/app/src/main/java/org/denhac/kiosk/KioskActivity.java new file mode 100644 index 0000000..b65e39d --- /dev/null +++ b/app/src/main/java/org/denhac/kiosk/KioskActivity.java @@ -0,0 +1,116 @@ +package org.denhac.kiosk; + +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.content.Context; +import android.os.Build; +import android.os.Handler; + +import androidx.appcompat.app.AppCompatActivity; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public abstract class KioskActivity extends AppCompatActivity { + // To keep track of activity's window focus + boolean currentFocus; + + // To keep track of activity's foreground/background status + boolean isPaused; + + Handler collapseNotificationHandler; + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + + currentFocus = hasFocus; + + if (!hasFocus) { + + // Method that handles loss of window focus + collapseNow(); + } + } + + @Override + protected void onPause() { + super.onPause(); + + isPaused = true; + + ActivityManager activityManager = (ActivityManager) getApplicationContext() + .getSystemService(Context.ACTIVITY_SERVICE); + + activityManager.moveTaskToFront(getTaskId(), 0); + } + + @Override + protected void onResume() { + super.onResume(); + + isPaused = false; + } + + public void collapseNow() { + + // Initialize 'collapseNotificationHandler' + if (collapseNotificationHandler == null) { + collapseNotificationHandler = new Handler(); + } + + // If window focus has been lost && activity is not in a paused state + // Its a valid check because showing of notification panel + // steals the focus from current activity's window, but does not + // 'pause' the activity + if (!currentFocus && !isPaused) { + + // Post a Runnable with some delay - currently set to 300 ms + collapseNotificationHandler.postDelayed(new Runnable() { + + @Override + public void run() { + + // Use reflection to trigger a method from 'StatusBarManager' + + @SuppressLint("WrongConstant") Object statusBarService = getSystemService("statusbar"); + Class statusBarManager = null; + + try { + statusBarManager = Class.forName("android.app.StatusBarManager"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + Method collapseStatusBar = null; + + try { + + // Prior to API 17, the method to call is 'collapse()' + // API 17 onwards, the method to call is `collapsePanels()` + + collapseStatusBar = statusBarManager.getMethod("collapsePanels"); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + + collapseStatusBar.setAccessible(true); + + try { + collapseStatusBar.invoke(statusBarService); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + // Check if the window focus has been returned + // If it hasn't been returned, post this Runnable again + // Currently, the delay is 100 ms. You can change this + // value to suit your needs. + if (!currentFocus && !isPaused) { + collapseNotificationHandler.postDelayed(this, 100L); + } + + } + }, 300L); + } + } +} diff --git a/app/src/main/java/org/denhac/kiosk/MainActivity.java b/app/src/main/java/org/denhac/kiosk/MainActivity.java index 1328c43..11ade10 100644 --- a/app/src/main/java/org/denhac/kiosk/MainActivity.java +++ b/app/src/main/java/org/denhac/kiosk/MainActivity.java @@ -5,12 +5,11 @@ import android.view.View; import android.widget.Toast; -import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import org.denhac.kiosk.events.EventsActivity; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends KioskActivity { @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/org/denhac/kiosk/WebViewActivity.java b/app/src/main/java/org/denhac/kiosk/WebViewActivity.java index bb8032b..5380add 100644 --- a/app/src/main/java/org/denhac/kiosk/WebViewActivity.java +++ b/app/src/main/java/org/denhac/kiosk/WebViewActivity.java @@ -20,7 +20,6 @@ import android.widget.TextView; import android.widget.Toast; -import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.widget.ContentLoadingProgressBar; @@ -37,7 +36,7 @@ import io.reactivex.functions.Consumer; -public class WebViewActivity extends AppCompatActivity implements WebAppInterface.Callback { +public class WebViewActivity extends KioskActivity implements WebAppInterface.Callback { private static final String EXTRA_URL = "ExtraUrl"; private ConstraintLayout loadingScreen; diff --git a/app/src/main/java/org/denhac/kiosk/WifiActivity.java b/app/src/main/java/org/denhac/kiosk/WifiActivity.java index 18ca7e1..35c4602 100644 --- a/app/src/main/java/org/denhac/kiosk/WifiActivity.java +++ b/app/src/main/java/org/denhac/kiosk/WifiActivity.java @@ -6,14 +6,12 @@ import android.view.View; import android.widget.ImageView; -import androidx.appcompat.app.AppCompatActivity; - import com.google.zxing.WriterException; import androidmads.library.qrgenearator.QRGContents; import androidmads.library.qrgenearator.QRGEncoder; -public class WifiActivity extends AppCompatActivity { +public class WifiActivity extends KioskActivity { private ImageView qrCodeView; diff --git a/app/src/main/java/org/denhac/kiosk/events/EventsActivity.java b/app/src/main/java/org/denhac/kiosk/events/EventsActivity.java index e1c6bfe..68d9164 100644 --- a/app/src/main/java/org/denhac/kiosk/events/EventsActivity.java +++ b/app/src/main/java/org/denhac/kiosk/events/EventsActivity.java @@ -6,9 +6,9 @@ import android.widget.ImageView; import android.widget.TextView; -import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; +import org.denhac.kiosk.KioskActivity; import org.denhac.kiosk.R; import org.denhac.kiosk.events.meetup.MeetupRepository; import org.denhac.kiosk.events.popup.PopupView; @@ -24,7 +24,7 @@ import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; -public class EventsActivity extends AppCompatActivity implements MeetupRepository.NetworkStatus, PopupWindow.Callback { +public class EventsActivity extends KioskActivity implements MeetupRepository.NetworkStatus, PopupWindow.Callback { private TextView monthText; private Calendar currentDay;