am 7b60431b: update <uses-feature> for OpenGL ES version with 3.0 example and API guide link. bug: 10207619

* commit '7b60431ba0f69e51b25e5bf92379222d8ef8691b':
  update <uses-feature> for OpenGL ES version with 3.0 example and API guide link. bug: 10207619
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/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c9776f1..4fcb18a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -422,6 +422,14 @@
         }
     }
 
+    /** @hide */
+    public void resetAllModes() {
+        try {
+            mService.resetAllModes();
+        } catch (RemoteException e) {
+        }
+    }
+
     public void startWatchingMode(int op, String packageName, final Callback callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index a9da863..cfd9cc7 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -33,4 +33,5 @@
     List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
     List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
     void setMode(int code, int uid, String packageName, int mode);
+    void resetAllModes();
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index f3a91c5..ee867ff 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -157,4 +157,11 @@
     public static final int STREAM_H264_480_360_1411k_DURATION = 46000;
     public static final int VIDEO_H263_AAC_DURATION = 501000;
     public static final int VIDEO_H263_AMR_DURATION = 502000;
+
+    // Video files for WiFi IOT video streaming test.
+    public static final String[] NETWORK_VIDEO_FILES = {
+            "H264_BP_720x480_25fps_256kbps_AMRNB_8khz_12.2kbps_m_0_26.mp4",
+            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4",
+            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4"
+    };
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index 67da6ac..e289812 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -17,18 +17,13 @@
 package com.android.mediaframeworktest.stress;
 
 import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
 
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.hardware.Camera;
-import android.media.MediaPlayer;
-import android.media.MediaRecorder;
+import android.os.Bundle;
 import android.os.Environment;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
-import android.view.SurfaceHolder;
 
 import com.android.mediaframeworktest.MediaNames;
 import com.android.mediaframeworktest.functional.CodecTest;
@@ -38,14 +33,12 @@
 import java.io.FileWriter;
 import java.io.Writer;
 
-import android.test.AndroidTestCase;
-import android.test.InstrumentationTestCase;
-
 /**
  * Junit / Instrumentation test case for the media player
  */
 public class MediaPlayerStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
     private String TAG = "MediaPlayerStressTest";
+    private String mMediaSrc;
 
     public MediaPlayerStressTest() {
         super("com.android.mediaframeworktest", MediaFrameworkTest.class);
@@ -56,6 +49,12 @@
         //the workaround for the race condition of requesting the updated surface.
         Thread.sleep(2000);
         getActivity();
+        MediaPlayerStressTestRunner mRunner = (MediaPlayerStressTestRunner)getInstrumentation();
+        Bundle arguments = mRunner.getArguments();
+        mMediaSrc = arguments.getString("media-source");
+        if (mMediaSrc == null) {
+            mMediaSrc = MediaNames.MEDIA_SAMPLE_POOL;
+        }
         super.setUp();
     }
 
@@ -119,17 +118,20 @@
         boolean testResult = true;
         // load directory files
         boolean onCompleteSuccess = false;
-        File dir = new File(MediaNames.MEDIA_SAMPLE_POOL);
-        String[] children = dir.list();
+        String[] children = MediaNames.NETWORK_VIDEO_FILES;
+        if (MediaNames.MEDIA_SAMPLE_POOL.equals(mMediaSrc)) {
+            File dir = new File(mMediaSrc);
+            children = dir.list();
+        }
         if (children == null) {
             Log.v("MediaPlayerApiTest:testMediaSamples", "dir is empty");
             return;
         } else {
             for (int i = 0; i < children.length; i++) {
-                //Get filename of directory
+                //Get filename
                 String filename = children[i];
                 onCompleteSuccess =
-                    CodecTest.playMediaSamples(dir + "/" + filename);
+                    CodecTest.playMediaSamples(mMediaSrc + filename);
                 if (!onCompleteSuccess){
                     //Don't fail the test right away, print out the failure file.
                     fileWithError += filename + '\n';
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index a402642..20ad636 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -42,6 +43,7 @@
 import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -288,6 +290,24 @@
         }
     }
 
+    private void pruneOp(Op op, int uid, String packageName) {
+        if (op.time == 0 && op.rejectTime == 0) {
+            Ops ops = getOpsLocked(uid, packageName, false);
+            if (ops != null) {
+                ops.remove(op.op);
+                if (ops.size() <= 0) {
+                    HashMap<String, Ops> pkgOps = mUidOps.get(uid);
+                    if (pkgOps != null) {
+                        pkgOps.remove(ops.packageName);
+                        if (pkgOps.size() <= 0) {
+                            mUidOps.remove(uid);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public void setMode(int code, int uid, String packageName, int mode) {
         verifyIncomingUid(uid);
@@ -316,21 +336,7 @@
                     if (mode == AppOpsManager.MODE_ALLOWED) {
                         // If going into the default mode, prune this op
                         // if there is nothing else interesting in it.
-                        if (op.time == 0 && op.rejectTime == 0) {
-                            Ops ops = getOpsLocked(uid, packageName, false);
-                            if (ops != null) {
-                                ops.remove(op.op);
-                                if (ops.size() <= 0) {
-                                    HashMap<String, Ops> pkgOps = mUidOps.get(uid);
-                                    if (pkgOps != null) {
-                                        pkgOps.remove(ops.packageName);
-                                        if (pkgOps.size() <= 0) {
-                                            mUidOps.remove(uid);
-                                        }
-                                    }
-                                }
-                            }
-                        }
+                        pruneOp(op, uid, packageName);
                     }
                     scheduleWriteNowLocked();
                 }
@@ -346,6 +352,72 @@
         }
     }
 
+    private static HashMap<Callback, ArrayList<Pair<String, Integer>>> addCallbacks(
+            HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks,
+            String packageName, int op, ArrayList<Callback> cbs) {
+        if (cbs == null) {
+            return callbacks;
+        }
+        if (callbacks == null) {
+            callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
+        }
+        for (int i=0; i<cbs.size(); i++) {
+            Callback cb = cbs.get(i);
+            ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
+            if (reports == null) {
+                reports = new ArrayList<Pair<String, Integer>>();
+                callbacks.put(cb, reports);
+            }
+            reports.add(new Pair<String, Integer>(packageName, op));
+        }
+        return callbacks;
+    }
+
+    @Override
+    public void resetAllModes() {
+        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+        HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
+        synchronized (this) {
+            boolean changed = false;
+            for (int i=0; i<mUidOps.size(); i++) {
+                HashMap<String, Ops> packages = mUidOps.valueAt(i);
+                for (Map.Entry<String, Ops> ent : packages.entrySet()) {
+                    String packageName = ent.getKey();
+                    Ops pkgOps = ent.getValue();
+                    for (int j=0; j<pkgOps.size(); j++) {
+                        Op curOp = pkgOps.valueAt(j);
+                        if (curOp.mode != AppOpsManager.MODE_ALLOWED) {
+                            curOp.mode = AppOpsManager.MODE_ALLOWED;
+                            changed = true;
+                            callbacks = addCallbacks(callbacks, packageName, curOp.op,
+                                    mOpModeWatchers.get(curOp.op));
+                            callbacks = addCallbacks(callbacks, packageName, curOp.op,
+                                    mPackageModeWatchers.get(packageName));
+                            pruneOp(curOp, mUidOps.keyAt(i), packageName);
+                        }
+                    }
+                }
+            }
+            if (changed) {
+                scheduleWriteNowLocked();
+            }
+        }
+        if (callbacks != null) {
+            for (Map.Entry<Callback, ArrayList<Pair<String, Integer>>> ent : callbacks.entrySet()) {
+                Callback cb = ent.getKey();
+                ArrayList<Pair<String, Integer>> reports = ent.getValue();
+                for (int i=0; i<reports.size(); i++) {
+                    Pair<String, Integer> rep = reports.get(i);
+                    try {
+                        cb.mCallback.opChanged(rep.second, rep.first);
+                    } catch (RemoteException e) {
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
         synchronized (this) {
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;