Only relaunch activity on significant size configuration changes.

Currently if the configuration width/height/smallest width changes, we
relaunch the activity or invoke onConfigurationChanged callback. When it
comes to size based configuration changes it might not be necessary: if
the size change doesn't pass one of the threshold defined by the
resources, it means there is no need to relaunch the activity.

In this CL the ActivityManager will receive the thresholds from the
application and use them to decide, whether to relaunch the activity.
The application reads the thresholds from the resources, specifically
from resource qualifiers used by the app.

Change-Id: Ie3cf0a172dc1ba0b865cf30c2962e7cfd9ad8436
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 0950a16..10c122a 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -107,8 +107,8 @@
             int userId) {
         try {
             getDefault().broadcastIntent(
-                null, intent, null, null, Activity.RESULT_OK, null, null,
-                null /*permission*/, appOp, null, false, true, userId);
+                    null, intent, null, null, Activity.RESULT_OK, null, null,
+                    null /*permission*/, appOp, null, false, true, userId);
         } catch (RemoteException ex) {
         }
     }
@@ -2653,6 +2653,24 @@
             reply.writeNoException();
             return true;
         }
+        case REPORT_SIZE_CONFIGURATIONS: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            int horizontalSize = data.readInt();
+            int[] horizontal = null;
+            if (horizontalSize > 0) {
+                horizontal = new int[horizontalSize];
+                data.readIntArray(horizontal);
+            }
+            int[] vertical = null;
+            int verticalSize = data.readInt();
+            if (verticalSize > 0) {
+                vertical = new int[verticalSize];
+                data.readIntArray(vertical);
+            }
+            reportSizeConfigurations(token, horizontal, vertical);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -6146,5 +6164,30 @@
         return stackId;
     }
 
+    @Override
+    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
+            int[] verticalSizeConfigurations) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        if (horizontalSizeConfiguration == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(horizontalSizeConfiguration.length);
+            data.writeIntArray(horizontalSizeConfiguration);
+        }
+        if (verticalSizeConfigurations == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(verticalSizeConfigurations.length);
+            data.writeIntArray(verticalSizeConfigurations);
+        }
+        mRemote.transact(REPORT_SIZE_CONFIGURATIONS, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }