Only allow 8 OBBs to be mounted by a UID

Change-Id: I4f017c5408af903c6c9ba007a2cf7f488a7fcd27
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index ea280a5..62a9894 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -76,6 +76,8 @@
 
     private static final String VOLD_TAG = "VoldConnector";
 
+    protected static final int MAX_OBBS = 8;
+
     /*
      * Internal vold volume state constants
      */
@@ -154,6 +156,7 @@
      * Mounted OBB tracking information. Used to track the current state of all
      * OBBs.
      */
+    final private Map<Integer, Integer> mObbUidUsage = new HashMap<Integer, Integer>();
     final private Map<IObbActionListener, List<ObbState>> mObbMounts = new HashMap<IObbActionListener, List<ObbState>>();
     final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>();
 
@@ -1576,6 +1579,12 @@
             }
 
             final int callerUid = Binder.getCallingUid();
+
+            final Integer uidUsage = mObbUidUsage.get(callerUid);
+            if (uidUsage != null && uidUsage > MAX_OBBS) {
+                throw new IllegalStateException("Maximum number of OBBs mounted!");
+            }
+
             obbState = new ObbState(filename, token, callerUid);
             addObbState(obbState);
         }
@@ -1637,6 +1646,15 @@
             }
             obbStates.add(obbState);
             mObbPathToStateMap.put(obbState.filename, obbState);
+
+            // Track the number of OBBs used by this UID.
+            final int uid = obbState.callerUid;
+            final Integer uidUsage = mObbUidUsage.get(uid);
+            if (uidUsage == null) {
+                mObbUidUsage.put(uid, 1);
+            } else {
+                mObbUidUsage.put(uid, uidUsage + 1);
+            }
         }
     }
 
@@ -1650,6 +1668,20 @@
                 mObbMounts.remove(obbState.token);
             }
             mObbPathToStateMap.remove(obbState.filename);
+
+            // Track the number of OBBs used by this UID.
+            final int uid = obbState.callerUid;
+            final Integer uidUsage = mObbUidUsage.get(uid);
+            if (uidUsage == null) {
+                Slog.e(TAG, "Called removeObbState for UID that isn't in map: " + uid);
+            } else {
+                final int newUsage = uidUsage - 1;
+                if (newUsage == 0) {
+                    mObbUidUsage.remove(uid);
+                } else {
+                    mObbUidUsage.put(uid, newUsage);
+                }
+            }
         }
     }