am 4633a50b: Merge "new class on using action bar for training basics" into jb-mr2-docs

* commit '4633a50b6ddf630543e7778e00e084106e503c38':
  new class on using action bar for training basics
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bb9e19f..a25e311 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.R;
 import com.android.internal.app.IUsageStats;
 import com.android.internal.os.PkgUsageStats;
 import com.android.internal.util.MemInfoReader;
@@ -369,9 +370,9 @@
         // Really brain dead right now -- just take this from the configured
         // vm heap size, and assume it is in megabytes and thus ends with "m".
         String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
-        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
     }
-    
+
     /**
      * Used by persistent processes to determine if they are running on a
      * higher-end device so should be okay using hardware drawing acceleration
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index a402642..9834479 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -63,6 +63,8 @@
     // Write at most every 30 minutes.
     static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000;
 
+    static final int CURRENT_VERSION = 1;
+
     Context mContext;
     final AtomicFile mFile;
     final Handler mHandler;
@@ -631,6 +633,9 @@
                         throw new IllegalStateException("no start tag found");
                     }
 
+                    String versStr = parser.getAttributeValue(null, "vers");
+                    int vers = versStr != null ? Integer.parseInt(versStr) : 0;
+
                     int outerDepth = parser.getDepth();
                     while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                             && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -640,7 +645,7 @@
 
                         String tagName = parser.getName();
                         if (tagName.equals("pkg")) {
-                            readPackage(parser);
+                            readPackage(parser, vers);
                         } else {
                             Slog.w(TAG, "Unknown element under <app-ops>: "
                                     + parser.getName());
@@ -673,7 +678,7 @@
         }
     }
 
-    void readPackage(XmlPullParser parser) throws NumberFormatException,
+    void readPackage(XmlPullParser parser, int vers) throws NumberFormatException,
             XmlPullParserException, IOException {
         String pkgName = parser.getAttributeValue(null, "n");
         int outerDepth = parser.getDepth();
@@ -686,7 +691,7 @@
 
             String tagName = parser.getName();
             if (tagName.equals("uid")) {
-                readUid(parser, pkgName);
+                readUid(parser, vers, pkgName);
             } else {
                 Slog.w(TAG, "Unknown element under <pkg>: "
                         + parser.getName());
@@ -695,7 +700,7 @@
         }
     }
 
-    void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException,
+    void readUid(XmlPullParser parser, int vers, String pkgName) throws NumberFormatException,
             XmlPullParserException, IOException {
         int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
         int outerDepth = parser.getDepth();
@@ -711,7 +716,12 @@
                 Op op = new Op(Integer.parseInt(parser.getAttributeValue(null, "n")));
                 String mode = parser.getAttributeValue(null, "m");
                 if (mode != null) {
-                    op.mode = Integer.parseInt(mode);
+                    if (vers < CURRENT_VERSION && op.op != AppOpsManager.OP_POST_NOTIFICATION) {
+                        Slog.w(TAG, "AppOps vers " + vers + ": drop mode from "
+                                + pkgName + "/" + uid + " op " + op.op);
+                    } else {
+                        op.mode = Integer.parseInt(mode);
+                    }
                 }
                 String time = parser.getAttributeValue(null, "t");
                 if (time != null) {
@@ -761,6 +771,7 @@
                 out.setOutput(stream, "utf-8");
                 out.startDocument(null, true);
                 out.startTag(null, "app-ops");
+                out.attribute(null, "vers", Integer.toString(CURRENT_VERSION));
 
                 if (allOps != null) {
                     String lastPkg = null;
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index 058857d..0bf03b5 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -154,31 +154,36 @@
             if (clip != null && clip.getItemCount() <= 0) {
                 throw new IllegalArgumentException("No items");
             }
-            if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, Binder.getCallingUid(),
+            final int callingUid = Binder.getCallingUid();
+            if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid,
                     callingPackage) != AppOpsManager.MODE_ALLOWED) {
                 return;
             }
-            checkDataOwnerLocked(clip, Binder.getCallingUid());
+            checkDataOwnerLocked(clip, callingUid);
             clearActiveOwnersLocked();
             PerUserClipboard clipboard = getClipboard();
             clipboard.primaryClip = clip;
+            final long ident = Binder.clearCallingIdentity();
             final int n = clipboard.primaryClipListeners.beginBroadcast();
-            for (int i = 0; i < n; i++) {
-                try {
-                    ListenerInfo li = (ListenerInfo)
-                            clipboard.primaryClipListeners.getBroadcastCookie(i);
-                    if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid,
-                            li.mPackageName) == AppOpsManager.MODE_ALLOWED) {
-                        clipboard.primaryClipListeners.getBroadcastItem(i)
-                                .dispatchPrimaryClipChanged();
+            try {
+                for (int i = 0; i < n; i++) {
+                    try {
+                        ListenerInfo li = (ListenerInfo)
+                                clipboard.primaryClipListeners.getBroadcastCookie(i);
+                        if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid,
+                                li.mPackageName) == AppOpsManager.MODE_ALLOWED) {
+                            clipboard.primaryClipListeners.getBroadcastItem(i)
+                                    .dispatchPrimaryClipChanged();
+                        }
+                    } catch (RemoteException e) {
+                        // The RemoteCallbackList will take care of removing
+                        // the dead object for us.
                     }
-                } catch (RemoteException e) {
-
-                    // The RemoteCallbackList will take care of removing
-                    // the dead object for us.
                 }
+            } finally {
+                clipboard.primaryClipListeners.finishBroadcast();
+                Binder.restoreCallingIdentity(ident);
             }
-            clipboard.primaryClipListeners.finishBroadcast();
         }
     }
     
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 29aaeaf..29780c0 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1606,7 +1606,7 @@
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
         }
         checkCallerIsSystemOrSameApp(pkg);
-        final boolean isSystemNotification = isCallerSystem() || ("android".equals(pkg));
+        final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
 
         userId = ActivityManager.handleIncomingUser(callingPid,
                 callingUid, userId, true, false, "enqueueNotification", pkg);
@@ -2084,14 +2084,18 @@
         cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
     }
 
-    // Return true if the caller is a system or phone UID and therefore should not have
+    // Return true if the UID is a system or phone UID and therefore should not have
     // any notifications or toasts blocked.
-    boolean isCallerSystem() {
-        final int uid = Binder.getCallingUid();
+    boolean isUidSystem(int uid) {
         final int appid = UserHandle.getAppId(uid);
         return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
     }
 
+    // same as isUidSystem(int, int) for the Binder caller's UID.
+    boolean isCallerSystem() {
+        return isUidSystem(Binder.getCallingUid());
+    }
+
     void checkCallerIsSystem() {
         if (isCallerSystem()) {
             return;