Kill launcher when display size changes

Bug: 112876936
Test: Verified by changing display cutout overlay
Change-Id: I3ca13c7be873509334457e3484ac5604731adeae
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 2489d30..611931d 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -21,37 +21,102 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
+import android.graphics.Point;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Handler;
 import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
 
 /**
  * {@link BroadcastReceiver} which watches configuration changes and
  * restarts the process in case changes which affect the device profile occur.
  */
-public class ConfigMonitor extends BroadcastReceiver {
+public class ConfigMonitor extends BroadcastReceiver implements DisplayListener {
+
+    private static final String TAG = "ConfigMonitor";
+
+    private final Point mTmpPoint1 = new Point();
+    private final Point mTmpPoint2 = new Point();
 
     private final Context mContext;
     private final float mFontScale;
     private final int mDensity;
 
+    private final int mDisplayId;
+    private final Point mRealSize;
+    private final Point mSmallestSize, mLargestSize;
+
     public ConfigMonitor(Context context) {
         mContext = context;
 
         Configuration config = context.getResources().getConfiguration();
         mFontScale = config.fontScale;
         mDensity = config.densityDpi;
+
+        Display display = getDefaultDisplay(context);
+        mDisplayId = display.getDisplayId();
+
+        mRealSize = new Point();
+        display.getRealSize(mRealSize);
+
+        mSmallestSize = new Point();
+        mLargestSize = new Point();
+        display.getCurrentSizeRange(mSmallestSize, mLargestSize);
     }
 
     @Override
     public void onReceive(Context context, Intent intent) {
         Configuration config = context.getResources().getConfiguration();
         if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
-            Log.d("ConfigMonitor", "Configuration changed, restarting launcher");
-            mContext.unregisterReceiver(this);
-            android.os.Process.killProcess(android.os.Process.myPid());
+            Log.d(TAG, "Configuration changed");
+            killProcess();
         }
     }
 
     public void register() {
         mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
+        mContext.getSystemService(DisplayManager.class)
+                .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
+    }
+
+    @Override
+    public void onDisplayAdded(int displayId) { }
+
+    @Override
+    public void onDisplayRemoved(int displayId) { }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        Display display = getDefaultDisplay(mContext);
+        display.getRealSize(mTmpPoint1);
+
+        if (!mRealSize.equals(mTmpPoint1) && !mRealSize.equals(mTmpPoint1.y, mTmpPoint1.x)) {
+            Log.d(TAG, String.format("Display size changed from %s to %s", mRealSize, mTmpPoint1));
+            killProcess();
+            return;
+        }
+
+        display.getCurrentSizeRange(mTmpPoint1, mTmpPoint2);
+        if (!mSmallestSize.equals(mTmpPoint1) || !mLargestSize.equals(mTmpPoint2)) {
+            Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
+                    mSmallestSize, mLargestSize, mTmpPoint1, mTmpPoint2));
+            killProcess();
+        }
+    }
+
+    private void killProcess() {
+        Log.d(TAG, "restarting launcher");
+        mContext.unregisterReceiver(this);
+        mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+        android.os.Process.killProcess(android.os.Process.myPid());
+    }
+
+    private Display getDefaultDisplay(Context context) {
+        return context.getSystemService(WindowManager.class).getDefaultDisplay();
     }
 }