Disable navigation bar and quick settings for Chile

From SAE 4.0 section Interruptions:
When device receive the SAE message, the pop-up must still
in screen together sound and vibration until user decide stop it.
The only way to stop the pop-up, sound, and vibration (at same time)
is the option available into pop-up, I mean “Ver” or “Siguiente”,
any other option is not allowed, as home key, power button,
volume button, etc. Thus disable navigation bar and quick settings.
Note this is done through reflection and there is no guarantee the
existence or proper function of statusBarManager APIs.

Bug: 205157514
Test: Manual test on Chilean SIM card
Change-Id: I5f5af5b9368005a80d355ab2713d4fe71b3ea53b
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 00fa2a4..41b6cda 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,6 +42,7 @@
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
     <uses-permission android:name="android.permission.MODIFY_CELL_BROADCASTS" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.STATUS_BAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.MANAGE_USERS" />
diff --git a/AndroidManifest_Platform.xml b/AndroidManifest_Platform.xml
index 4e2992b..97fe723 100644
--- a/AndroidManifest_Platform.xml
+++ b/AndroidManifest_Platform.xml
@@ -28,6 +28,7 @@
   <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
   <uses-permission android:name="android.permission.MODIFY_CELL_BROADCASTS" />
   <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <uses-permission android:name="android.permission.STATUS_BAR" />
   <uses-permission android:name="android.permission.VIBRATE" />
   <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
   <uses-permission android:name="android.permission.MANAGE_USERS" />
diff --git a/res/values-mcc730/config.xml b/res/values-mcc730/config.xml
index f7396f5..50f0f64 100644
--- a/res/values-mcc730/config.xml
+++ b/res/values-mcc730/config.xml
@@ -66,6 +66,9 @@
     <string name="link_method" translatable="false">none</string>
     <!-- Whether the user can mute the alert by physical button -->
     <bool name="mute_by_physical_button">false</bool>
+    <!-- Whether to disable the status bar while alert is showing, not allow
+    users to interact with other activities until pressing the "ok" button -->
+    <bool name="disable_status_bar">true</bool>
     <!-- Whether to disable the opt-out dialog for all channels -->
     <bool name="disable_opt_out_dialog">true</bool>
     <bool name="show_main_switch_settings">false</bool>
diff --git a/res/values/config.xml b/res/values/config.xml
index de63dfa..9c2c0c2 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -261,6 +261,11 @@
     KR carriers mandate to always show notifications along with alert dialog.  -->
     <bool name="show_alert_dialog_with_notification">false</bool>
 
+    <!-- Whether to disable status bar while alert dialog is showing.
+    Some carriers mandate this to make sure users do not switch to other activities
+    until pressing the "ok" button -->
+    <bool name="disable_status_bar">false</bool>
+
     <!-- Whether to show the alert dialog at the bottom of the screen in order to avoid blocking
          other content -->
     <bool name="alert_dialog_bottom">false</bool>
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
index 5514299..c57faa4 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
@@ -24,6 +24,7 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.RemoteAction;
+import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.ClipData;
 import android.content.ClipboardManager;
@@ -72,6 +73,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Method;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -371,7 +373,9 @@
 
         // Disable home button when alert dialog is showing if mute_by_physical_button is false.
         if (!CellBroadcastSettings.getResourcesForDefaultSubId(getApplicationContext())
-                .getBoolean(R.bool.mute_by_physical_button)) {
+                .getBoolean(R.bool.mute_by_physical_button) && !CellBroadcastSettings
+                .getResourcesForDefaultSubId(getApplicationContext())
+                .getBoolean(R.bool.disable_status_bar)) {
             final View decorView = win.getDecorView();
             decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
         }
@@ -467,6 +471,10 @@
                 mAnimationHandler.startIconAnimation(subId);
             }
         }
+        // Some LATAM carriers mandate to disable navigation bars, quick settings etc when alert
+        // dialog is showing. This is to make sure users to ack the alert before switching to
+        // other activities.
+        setStatusBarDisabledIfNeeded(true);
     }
 
     /**
@@ -477,6 +485,7 @@
     public void onPause() {
         Log.d(TAG, "onPause called");
         mAnimationHandler.stopIconAnimation();
+        setStatusBarDisabledIfNeeded(false);
         super.onPause();
     }
 
@@ -1161,4 +1170,48 @@
         }
         return dialogMessageList;
     }
+
+    /**
+     * To disable navigation bars, quick settings etc. Force users to engage with the alert dialog
+     * before switching to other activities.
+     *
+     * @param disable if set to {@code true} to disable the status bar. {@code false} otherwise.
+     */
+    private void setStatusBarDisabledIfNeeded(boolean disable) {
+        if (!CellBroadcastSettings.getResourcesForDefaultSubId(getApplicationContext())
+                .getBoolean(R.bool.disable_status_bar)) {
+            return;
+        }
+        try {
+            // TODO change to system API in future.
+            StatusBarManager statusBarManager = getSystemService(StatusBarManager.class);
+            Method disableMethod = StatusBarManager.class.getDeclaredMethod(
+                    "disable", int.class);
+            Method disableMethod2 = StatusBarManager.class.getDeclaredMethod(
+                    "disable2", int.class);
+            if (disable) {
+                // flags to be disabled
+                int disableHome = StatusBarManager.class.getDeclaredField("DISABLE_HOME")
+                        .getInt(null);
+                int disableRecent = StatusBarManager.class
+                        .getDeclaredField("DISABLE_RECENT").getInt(null);
+                int disableBack = StatusBarManager.class.getDeclaredField("DISABLE_BACK")
+                        .getInt(null);
+                int disableQuickSettings = StatusBarManager.class.getDeclaredField(
+                        "DISABLE2_QUICK_SETTINGS").getInt(null);
+                int disableNotificationShaded = StatusBarManager.class.getDeclaredField(
+                        "DISABLE2_NOTIFICATION_SHADE").getInt(null);
+                disableMethod.invoke(statusBarManager, disableHome | disableBack | disableRecent);
+                disableMethod2.invoke(statusBarManager, disableQuickSettings
+                        | disableNotificationShaded);
+            } else {
+                int disableNone = StatusBarManager.class.getDeclaredField("DISABLE_NONE")
+                        .getInt(null);
+                disableMethod.invoke(statusBarManager, disableNone);
+                disableMethod2.invoke(statusBarManager, disableNone);
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to disable navigation when showing alert: ", e);
+        }
+    }
 }