Add SDK 29 sources.

Test: N/A
Change-Id: Iedb7a31029e003928eb16f7e69ed147e72bb6235
diff --git a/java/lang/Daemons.java b/java/lang/Daemons.java
new file mode 100644
index 0000000..7d0eca2
--- /dev/null
+++ b/java/lang/Daemons.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.system.Os;
+import android.system.OsConstants;
+import dalvik.annotation.compat.UnsupportedAppUsage;
+import dalvik.system.VMRuntime;
+import java.lang.ref.FinalizerReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
+import libcore.util.EmptyArray;
+
+/**
+ * Calls Object.finalize() on objects in the finalizer reference queue. The VM
+ * will abort if any finalize() call takes more than the maximum finalize time
+ * to complete.
+ *
+ * @hide
+ */
+public final class Daemons {
+    private static final int NANOS_PER_MILLI = 1000 * 1000;
+
+    // This used to be final. IT IS NOW ONLY WRITTEN. We now update it when we look at the command
+    // line argument, for the benefit of mis-behaved apps that might read it.  SLATED FOR REMOVAL.
+    // There is no reason to use this: Finalizers should not rely on the value. If a finalizer takes
+    // appreciable time, the work should be done elsewhere.  Based on disassembly of Daemons.class,
+    // the value is effectively inlined, so changing the field never did have an effect.
+    // DO NOT USE. FOR ANYTHING. THIS WILL BE REMOVED SHORTLY.
+    @UnsupportedAppUsage
+    private static long MAX_FINALIZE_NANOS = 10L * 1000 * NANOS_PER_MILLI;
+
+    private static final Daemon[] DAEMONS = new Daemon[] {
+            HeapTaskDaemon.INSTANCE,
+            ReferenceQueueDaemon.INSTANCE,
+            FinalizerDaemon.INSTANCE,
+            FinalizerWatchdogDaemon.INSTANCE,
+    };
+    private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+    private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+
+    private static boolean postZygoteFork = false;
+
+    @UnsupportedAppUsage
+    public static void start() {
+        for (Daemon daemon : DAEMONS) {
+            daemon.start();
+        }
+    }
+
+    public static void startPostZygoteFork() {
+        postZygoteFork = true;
+        for (Daemon daemon : DAEMONS) {
+            daemon.startPostZygoteFork();
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static void stop() {
+        for (Daemon daemon : DAEMONS) {
+            daemon.stop();
+        }
+    }
+
+    private static void waitForDaemonStart() throws Exception {
+        if (postZygoteFork) {
+            POST_ZYGOTE_START_LATCH.await();
+        } else {
+            PRE_ZYGOTE_START_LATCH.await();
+        }
+    }
+
+    /**
+     * A background task that provides runtime support to the application.
+     * Daemons can be stopped and started, but only so that the zygote can be a
+     * single-threaded process when it forks.
+     */
+    private static abstract class Daemon implements Runnable {
+        @UnsupportedAppUsage
+        private Thread thread;
+        private String name;
+        private boolean postZygoteFork;
+
+        protected Daemon(String name) {
+            this.name = name;
+        }
+
+        @UnsupportedAppUsage
+        public synchronized void start() {
+            startInternal();
+        }
+
+        public synchronized void startPostZygoteFork() {
+            postZygoteFork = true;
+            startInternal();
+        }
+
+        public void startInternal() {
+            if (thread != null) {
+                throw new IllegalStateException("already running");
+            }
+            thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
+            thread.setDaemon(true);
+            thread.setSystemDaemon(true);
+            thread.start();
+        }
+
+        public final void run() {
+            if (postZygoteFork) {
+                // We don't set the priority before the Thread.start() call above because
+                // Thread.start() will call SetNativePriority and overwrite the desired native
+                // priority. We (may) use a native priority that doesn't have a corresponding
+                // java.lang.Thread-level priority (native priorities are more coarse-grained.)
+                VMRuntime.getRuntime().setSystemDaemonThreadPriority();
+                POST_ZYGOTE_START_LATCH.countDown();
+            } else {
+                PRE_ZYGOTE_START_LATCH.countDown();
+            }
+            runInternal();
+        }
+
+        public abstract void runInternal();
+
+        /**
+         * Returns true while the current thread should continue to run; false
+         * when it should return.
+         */
+        @UnsupportedAppUsage
+        protected synchronized boolean isRunning() {
+            return thread != null;
+        }
+
+        public synchronized void interrupt() {
+            interrupt(thread);
+        }
+
+        public synchronized void interrupt(Thread thread) {
+            if (thread == null) {
+                throw new IllegalStateException("not running");
+            }
+            thread.interrupt();
+        }
+
+        /**
+         * Waits for the runtime thread to stop. This interrupts the thread
+         * currently running the runnable and then waits for it to exit.
+         */
+        @UnsupportedAppUsage
+        public void stop() {
+            Thread threadToStop;
+            synchronized (this) {
+                threadToStop = thread;
+                thread = null;
+            }
+            if (threadToStop == null) {
+                throw new IllegalStateException("not running");
+            }
+            interrupt(threadToStop);
+            while (true) {
+                try {
+                    threadToStop.join();
+                    return;
+                } catch (InterruptedException ignored) {
+                } catch (OutOfMemoryError ignored) {
+                    // An OOME may be thrown if allocating the InterruptedException failed.
+                }
+            }
+        }
+
+        /**
+         * Returns the current stack trace of the thread, or an empty stack trace
+         * if the thread is not currently running.
+         */
+        public synchronized StackTraceElement[] getStackTrace() {
+            return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
+        }
+    }
+
+    /**
+     * This heap management thread moves elements from the garbage collector's
+     * pending list to the managed reference queue.
+     */
+    private static class ReferenceQueueDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
+
+        ReferenceQueueDaemon() {
+            super("ReferenceQueueDaemon");
+        }
+
+        @Override public void runInternal() {
+            while (isRunning()) {
+                Reference<?> list;
+                try {
+                    synchronized (ReferenceQueue.class) {
+                        while (ReferenceQueue.unenqueued == null) {
+                            ReferenceQueue.class.wait();
+                        }
+                        list = ReferenceQueue.unenqueued;
+                        ReferenceQueue.unenqueued = null;
+                    }
+                } catch (InterruptedException e) {
+                    continue;
+                } catch (OutOfMemoryError e) {
+                    continue;
+                }
+                ReferenceQueue.enqueuePending(list);
+            }
+        }
+    }
+
+    private static class FinalizerDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
+        private final ReferenceQueue<Object> queue = FinalizerReference.queue;
+        private final AtomicInteger progressCounter = new AtomicInteger(0);
+        // Object (not reference!) being finalized. Accesses may race!
+        @UnsupportedAppUsage
+        private Object finalizingObject = null;
+
+        FinalizerDaemon() {
+            super("FinalizerDaemon");
+        }
+
+        @Override public void runInternal() {
+            // This loop may be performance critical, since we need to keep up with mutator
+            // generation of finalizable objects.
+            // We minimize the amount of work we do per finalizable object. For example, we avoid
+            // reading the current time here, since that involves a kernel call per object.  We
+            // limit fast path communication with FinalizerWatchDogDaemon to what's unavoidable: A
+            // non-volatile store to communicate the current finalizable object, e.g. for
+            // reporting, and a release store (lazySet) to a counter.
+            // We do stop the  FinalizerWatchDogDaemon if we have nothing to do for a
+            // potentially extended period.  This prevents the device from waking up regularly
+            // during idle times.
+
+            // Local copy of progressCounter; saves a fence per increment on ARM and MIPS.
+            int localProgressCounter = progressCounter.get();
+
+            while (isRunning()) {
+                try {
+                    // Use non-blocking poll to avoid FinalizerWatchdogDaemon communication
+                    // when busy.
+                    FinalizerReference<?> finalizingReference = (FinalizerReference<?>)queue.poll();
+                    if (finalizingReference != null) {
+                        finalizingObject = finalizingReference.get();
+                        progressCounter.lazySet(++localProgressCounter);
+                    } else {
+                        finalizingObject = null;
+                        progressCounter.lazySet(++localProgressCounter);
+                        // Slow path; block.
+                        FinalizerWatchdogDaemon.INSTANCE.goToSleep();
+                        finalizingReference = (FinalizerReference<?>)queue.remove();
+                        finalizingObject = finalizingReference.get();
+                        progressCounter.set(++localProgressCounter);
+                        FinalizerWatchdogDaemon.INSTANCE.wakeUp();
+                    }
+                    doFinalize(finalizingReference);
+                } catch (InterruptedException ignored) {
+                } catch (OutOfMemoryError ignored) {
+                }
+            }
+        }
+
+        @FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")
+        private void doFinalize(FinalizerReference<?> reference) {
+            FinalizerReference.remove(reference);
+            Object object = reference.get();
+            reference.clear();
+            try {
+                object.finalize();
+            } catch (Throwable ex) {
+                // The RI silently swallows these, but Android has always logged.
+                System.logE("Uncaught exception thrown by finalizer", ex);
+            } finally {
+                // Done finalizing, stop holding the object as live.
+                finalizingObject = null;
+            }
+        }
+    }
+
+    /**
+     * The watchdog exits the VM if the finalizer ever gets stuck. We consider
+     * the finalizer to be stuck if it spends more than MAX_FINALIZATION_MILLIS
+     * on one instance.
+     */
+    private static class FinalizerWatchdogDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
+
+        private boolean needToWork = true;  // Only accessed in synchronized methods.
+
+        private long finalizerTimeoutMs = 0;  // Lazily initialized.
+
+        FinalizerWatchdogDaemon() {
+            super("FinalizerWatchdogDaemon");
+        }
+
+        @Override public void runInternal() {
+            while (isRunning()) {
+                if (!sleepUntilNeeded()) {
+                    // We have been interrupted, need to see if this daemon has been stopped.
+                    continue;
+                }
+                final Object finalizing = waitForFinalization();
+                if (finalizing != null && !VMRuntime.getRuntime().isDebuggerActive()) {
+                    finalizerTimedOut(finalizing);
+                    break;
+                }
+            }
+        }
+
+        /**
+         * Wait until something is ready to be finalized.
+         * Return false if we have been interrupted
+         * See also http://code.google.com/p/android/issues/detail?id=22778.
+         */
+        private synchronized boolean sleepUntilNeeded() {
+            while (!needToWork) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    // Daemon.stop may have interrupted us.
+                    return false;
+                } catch (OutOfMemoryError e) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Notify daemon that it's OK to sleep until notified that something is ready to be
+         * finalized.
+         */
+        private synchronized void goToSleep() {
+            needToWork = false;
+        }
+
+        /**
+         * Notify daemon that there is something ready to be finalized.
+         */
+        private synchronized void wakeUp() {
+            needToWork = true;
+            notify();
+        }
+
+        private synchronized boolean getNeedToWork() {
+            return needToWork;
+        }
+
+        /**
+         * Sleep for the given number of milliseconds.
+         * @return false if we were interrupted.
+         */
+        private boolean sleepForMillis(long durationMillis) {
+            long startMillis = System.currentTimeMillis();
+            while (true) {
+                long elapsedMillis = System.currentTimeMillis() - startMillis;
+                long sleepMillis = durationMillis - elapsedMillis;
+                if (sleepMillis <= 0) {
+                    return true;
+                }
+                try {
+                    Thread.sleep(sleepMillis);
+                } catch (InterruptedException e) {
+                    if (!isRunning()) {
+                        return false;
+                    }
+                } catch (OutOfMemoryError ignored) {
+                    if (!isRunning()) {
+                        return false;
+                    }
+                }
+            }
+        }
+
+
+        /**
+         * Return an object that took too long to finalize or return null.
+         * Wait VMRuntime.getFinalizerTimeoutMs.  If the FinalizerDaemon took essentially the
+         * whole time processing a single reference, return that reference.  Otherwise return
+         * null.  Only called from a single thread.
+         */
+        private Object waitForFinalization() {
+            if (finalizerTimeoutMs == 0) {
+                finalizerTimeoutMs = VMRuntime.getRuntime().getFinalizerTimeoutMs();
+                // Temporary app backward compatibility. Remove eventually.
+                MAX_FINALIZE_NANOS = NANOS_PER_MILLI * finalizerTimeoutMs;
+            }
+            long startCount = FinalizerDaemon.INSTANCE.progressCounter.get();
+            // Avoid remembering object being finalized, so as not to keep it alive.
+            if (!sleepForMillis(finalizerTimeoutMs)) {
+                // Don't report possibly spurious timeout if we are interrupted.
+                return null;
+            }
+            if (getNeedToWork() && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+                // We assume that only remove() and doFinalize() may take time comparable to
+                // the finalizer timeout.
+                // We observed neither the effect of the gotoSleep() nor the increment preceding a
+                // later wakeUp. Any remove() call by the FinalizerDaemon during our sleep
+                // interval must have been followed by a wakeUp call before we checked needToWork.
+                // But then we would have seen the counter increment.  Thus there cannot have
+                // been such a remove() call.
+                // The FinalizerDaemon must not have progressed (from either the beginning or the
+                // last progressCounter increment) to either the next increment or gotoSleep()
+                // call.  Thus we must have taken essentially the whole finalizerTimeoutMs in a
+                // single doFinalize() call.  Thus it's OK to time out.  finalizingObject was set
+                // just before the counter increment, which preceded the doFinalize call.  Thus we
+                // are guaranteed to get the correct finalizing value below, unless doFinalize()
+                // just finished as we were timing out, in which case we may get null or a later
+                // one.  In this last case, we are very likely to discard it below.
+                Object finalizing = FinalizerDaemon.INSTANCE.finalizingObject;
+                sleepForMillis(500);
+                // Recheck to make it even less likely we report the wrong finalizing object in
+                // the case which a very slow finalization just finished as we were timing out.
+                if (getNeedToWork()
+                        && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+                    return finalizing;
+                }
+            }
+            return null;
+        }
+
+        private static void finalizerTimedOut(Object object) {
+            // The current object has exceeded the finalization deadline; abort!
+            String message = object.getClass().getName() + ".finalize() timed out after "
+                    + VMRuntime.getRuntime().getFinalizerTimeoutMs() / 1000 + " seconds";
+            Exception syntheticException = new TimeoutException(message);
+            // We use the stack from where finalize() was running to show where it was stuck.
+            syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
+
+            // Send SIGQUIT to get native stack traces.
+            try {
+                Os.kill(Os.getpid(), OsConstants.SIGQUIT);
+                // Sleep a few seconds to let the stack traces print.
+                Thread.sleep(5000);
+            } catch (Exception e) {
+                System.logE("failed to send SIGQUIT", e);
+            } catch (OutOfMemoryError ignored) {
+                // May occur while trying to allocate the exception.
+            }
+
+            // Ideally, we'd want to do this if this Thread had no handler to dispatch to.
+            // Unfortunately, it's extremely to messy to query whether a given Thread has *some*
+            // handler to dispatch to, either via a handler set on itself, via its ThreadGroup
+            // object or via the defaultUncaughtExceptionHandler.
+            //
+            // As an approximation, we log by hand an exit if there's no pre-exception handler nor
+            // a default uncaught exception handler.
+            //
+            // Note that this condition will only ever be hit by ART host tests and standalone
+            // dalvikvm invocations. All zygote forked process *will* have a pre-handler set
+            // in RuntimeInit and they cannot subsequently override it.
+            if (Thread.getUncaughtExceptionPreHandler() == null &&
+                    Thread.getDefaultUncaughtExceptionHandler() == null) {
+                // If we have no handler, log and exit.
+                System.logE(message, syntheticException);
+                System.exit(2);
+            }
+
+            // Otherwise call the handler to do crash reporting.
+            // We don't just throw because we're not the thread that
+            // timed out; we're the thread that detected it.
+            Thread.currentThread().dispatchUncaughtException(syntheticException);
+        }
+    }
+
+    // Adds a heap trim task to the heap event processor, not called from java. Left for
+    // compatibility purposes due to reflection.
+    @UnsupportedAppUsage
+    public static void requestHeapTrim() {
+        VMRuntime.getRuntime().requestHeapTrim();
+    }
+
+    // Adds a concurrent GC request task ot the heap event processor, not called from java. Left
+    // for compatibility purposes due to reflection.
+    public static void requestGC() {
+        VMRuntime.getRuntime().requestConcurrentGC();
+    }
+
+    private static class HeapTaskDaemon extends Daemon {
+        private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();
+
+        HeapTaskDaemon() {
+            super("HeapTaskDaemon");
+        }
+
+        // Overrides the Daemon.interupt method which is called from Daemons.stop.
+        public synchronized void interrupt(Thread thread) {
+            VMRuntime.getRuntime().stopHeapTaskProcessor();
+        }
+
+        @Override public void runInternal() {
+            synchronized (this) {
+                if (isRunning()) {
+                  // Needs to be synchronized or else we there is a race condition where we start
+                  // the thread, call stopHeapTaskProcessor before we start the heap task
+                  // processor, resulting in a deadlock since startHeapTaskProcessor restarts it
+                  // while the other thread is waiting in Daemons.stop().
+                  VMRuntime.getRuntime().startHeapTaskProcessor();
+                }
+            }
+            // This runs tasks until we are stopped and there is no more pending task.
+            VMRuntime.getRuntime().runHeapTasks();
+        }
+    }
+}