Merge "Fix for missing location icon" into pi-dev
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fcab8c1..c58b91e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1555,6 +1555,7 @@
         private final long[] mRejectTimes;
         private final int mDuration;
         private final int mProxyUid;
+        private final boolean mRunning;
         private final String mProxyPackageName;
 
         public OpEntry(int op, int mode, long time, long rejectTime, int duration,
@@ -1566,12 +1567,13 @@
             mTimes[0] = time;
             mRejectTimes[0] = rejectTime;
             mDuration = duration;
+            mRunning = duration == -1;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
         }
 
         public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
-                int proxyUid, String proxyPackage) {
+                boolean running, int proxyUid, String proxyPackage) {
             mOp = op;
             mMode = mode;
             mTimes = new long[_NUM_UID_STATE];
@@ -1579,10 +1581,16 @@
             System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
             System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
             mDuration = duration;
+            mRunning = running;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
         }
 
+        public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
+                int proxyUid, String proxyPackage) {
+            this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage);
+        }
+
         public int getOp() {
             return mOp;
         }
@@ -1632,7 +1640,7 @@
         }
 
         public boolean isRunning() {
-            return mDuration == -1;
+            return mRunning;
         }
 
         public int getDuration() {
@@ -1659,6 +1667,7 @@
             dest.writeLongArray(mTimes);
             dest.writeLongArray(mRejectTimes);
             dest.writeInt(mDuration);
+            dest.writeBoolean(mRunning);
             dest.writeInt(mProxyUid);
             dest.writeString(mProxyPackageName);
         }
@@ -1669,6 +1678,7 @@
             mTimes = source.createLongArray();
             mRejectTimes = source.createLongArray();
             mDuration = source.readInt();
+            mRunning = source.readBoolean();
             mProxyUid = source.readInt();
             mProxyPackageName = source.readString();
         }
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 3beebcb..aa86ea8 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -812,11 +812,12 @@
             resOps = new ArrayList<>();
             for (int j=0; j<pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
-                long duration = curOp.duration == -1
+                final boolean running = curOp.duration == -1;
+                long duration = running
                         ? (elapsedNow - curOp.startRealtime)
                         : curOp.duration;
                 resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                        curOp.rejectTime, (int) duration, curOp.proxyUid,
+                        curOp.rejectTime, (int) duration, running, curOp.proxyUid,
                         curOp.proxyPackageName));
             }
         } else {
@@ -826,11 +827,12 @@
                     if (resOps == null) {
                         resOps = new ArrayList<>();
                     }
-                    long duration = curOp.duration == -1
+                    final boolean running = curOp.duration == -1;
+                    final long duration = running
                             ? (elapsedNow - curOp.startRealtime)
                             : curOp.duration;
                     resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                            curOp.rejectTime, (int) duration, curOp.proxyUid,
+                            curOp.rejectTime, (int) duration, running, curOp.proxyUid,
                             curOp.proxyPackageName));
                 }
             }
diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
index ea0fe45..7f397d6 100644
--- a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -36,6 +38,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.List;
+
 /**
  * Tests app ops version upgrades
  */
@@ -107,6 +111,46 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @Test
+    public void testIsRunning() throws Exception {
+        final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+        // Start the op
+        appOpsManager.startOp(AppOpsManager.OP_CAMERA);
+
+        assertTrue("Camera should be running", isCameraOn(appOpsManager));
+
+        // Finish the op
+        appOpsManager.finishOp(AppOpsManager.OP_CAMERA);
+
+        assertFalse("Camera should not be running", isCameraOn(appOpsManager));
+    }
+
+    private boolean isCameraOn(AppOpsManager appOpsManager) {
+        List<AppOpsManager.PackageOps> packages
+                = appOpsManager.getPackagesForOps(new int[] {AppOpsManager.OP_CAMERA});
+        // AppOpsManager can return null when there is no requested data.
+        if (packages != null) {
+            final int numPackages = packages.size();
+            for (int packageInd = 0; packageInd < numPackages; packageInd++) {
+                AppOpsManager.PackageOps packageOp = packages.get(packageInd);
+                List<AppOpsManager.OpEntry> opEntries = packageOp.getOps();
+                if (opEntries != null) {
+                    final int numOps = opEntries.size();
+                    for (int opInd = 0; opInd < numOps; opInd++) {
+                        AppOpsManager.OpEntry opEntry = opEntries.get(opInd);
+                        if (opEntry.getOp() == AppOpsManager.OP_CAMERA) {
+                            if (opEntry.isRunning()) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
     private static Context getContext() {
         return InstrumentationRegistry.getContext();
     }