Merge "More granular reporting of size configurations."
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a24b1ec..da743f8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2681,19 +2681,10 @@
         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);
+            int[] horizontal = readIntArray(data);
+            int[] vertical = readIntArray(data);
+            int[] smallest = readIntArray(data);
+            reportSizeConfigurations(token, horizontal, vertical, smallest);
             return true;
         }
         case SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION: {
@@ -2715,6 +2706,16 @@
         return super.onTransact(code, data, reply, flags);
     }
 
+    private int[] readIntArray(Parcel data) {
+        int[] smallest = null;
+        int smallestSize = data.readInt();
+        if (smallestSize > 0) {
+            smallest = new int[smallestSize];
+            data.readIntArray(smallest);
+        }
+        return smallest;
+    }
+
     public IBinder asBinder() {
         return this;
     }
@@ -6241,29 +6242,30 @@
 
     @Override
     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations) throws RemoteException {
+            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations)
+            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);
-        }
+        writeIntArray(horizontalSizeConfiguration, data);
+        writeIntArray(verticalSizeConfigurations, data);
+        writeIntArray(smallestSizeConfigurations, data);
         mRemote.transact(REPORT_SIZE_CONFIGURATIONS, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
     }
 
+    private static void writeIntArray(int[] array, Parcel data) {
+        if (array == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(array.length);
+            data.writeIntArray(array);
+        }
+    }
+
     @Override
     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b9292de..a74f528 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -88,6 +88,7 @@
 import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
+import android.util.SparseIntArray;
 import android.util.SuperNotCalledException;
 import android.view.Display;
 import android.view.HardwareRenderer;
@@ -2638,32 +2639,24 @@
         if (configurations == null) {
             return;
         }
-        IntArray horizontal = new IntArray();
-        IntArray vertical = new IntArray();
+        SparseIntArray horizontal = new SparseIntArray();
+        SparseIntArray vertical = new SparseIntArray();
+        SparseIntArray smallest = new SparseIntArray();
         for (int i = configurations.length - 1; i >= 0; i--) {
             Configuration config = configurations[i];
             if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-                vertical.add(config.screenHeightDp);
+                vertical.put(config.screenHeightDp, 0);
             }
             if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
-                horizontal.add(config.screenWidthDp);
+                horizontal.put(config.screenWidthDp, 0);
             }
             if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
-                vertical.add(config.smallestScreenWidthDp);
-                horizontal.add(config.smallestScreenWidthDp);
+                smallest.put(config.smallestScreenWidthDp, 0);
             }
         }
-        int[] horizontalArray = null;
-        if (horizontal.size() > 0) {
-            horizontalArray = horizontal.toArray();
-        }
-        int[] verticalArray = null;
-        if (vertical.size() > 0) {
-            verticalArray = vertical.toArray();
-        }
         try {
-            ActivityManagerNative.getDefault().reportSizeConfigurations(r.token, horizontalArray,
-                    verticalArray);
+            ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
+                    horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
         } catch (RemoteException ex) {
         }
 
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ebdd302..fcc040b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -123,7 +123,8 @@
     public void activitySlept(IBinder token) throws RemoteException;
     public void activityDestroyed(IBinder token) throws RemoteException;
     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations) throws RemoteException;
+            int[] verticalSizeConfigurations, int[] smallestWidthConfigurations)
+            throws RemoteException;
     public String getCallingPackage(IBinder token) throws RemoteException;
     public ComponentName getCallingActivity(IBinder token) throws RemoteException;
     public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException;
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index e5c729d..3b832dd 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -19,6 +19,8 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
+import java.util.Arrays;
+
 import libcore.util.EmptyArray;
 
 /**
@@ -239,6 +241,18 @@
     }
 
     /**
+     * Provides a copy of keys.
+     *
+     * @hide
+     * */
+    public int[] copyKeys() {
+        if (size() == 0) {
+            return null;
+        }
+        return Arrays.copyOf(mKeys, size());
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p>This implementation composes a string by iterating over its mappings.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 90a119d..5aab804 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6527,7 +6527,7 @@
 
     @Override
     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations) {
+            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
         synchronized (this) {
@@ -6537,7 +6537,7 @@
                         + "found for: " + token);
             }
             record.setSizeConfigurations(horizontalSizeConfiguration,
-                    verticalSizeConfigurations);
+                    verticalSizeConfigurations, smallestSizeConfigurations);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 8061a92..499aba9 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -190,6 +190,7 @@
     // and drawable-sw400dp will be added to both as 400.
     private int[] mVerticalSizeConfigurations;
     private int[] mHorizontalSizeConfigurations;
+    private int[] mSmallestSizeConfigurations;
 
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
@@ -342,6 +343,10 @@
         return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
     }
 
+    public boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
+        return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
+    }
+
     /**
      * The purpose of this method is to decide whether the activity needs to be relaunched upon
      * changing its size. In most cases the activities don't need to be relaunched, if the resize
@@ -372,9 +377,10 @@
     }
 
     public void setSizeConfigurations(int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations) {
+            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
         mHorizontalSizeConfigurations = horizontalSizeConfiguration;
         mVerticalSizeConfigurations = verticalSizeConfigurations;
+        mSmallestSizeConfigurations = smallestSizeConfigurations;
     }
 
     static class Token extends IApplicationToken.Stub {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2104830..b5f424d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4153,9 +4153,7 @@
         if ((taskChanges & ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
             final int oldSmallest = oldTaskOverride.smallestScreenWidthDp;
             final int newSmallest = taskConfig.smallestScreenWidthDp;
-            final boolean crosses = record.crossesHorizontalSizeThreshold(oldSmallest, newSmallest)
-                    || record.crossesVerticalSizeThreshold(oldSmallest, newSmallest);
-            if (!crosses) {
+            if (!record.crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
                 taskChanges &= ~ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
             }
         }