1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.lang;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A {@code ThreadGroup} is a means of organizing {@link Thread}s into a
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hierarchical structure. A {@code ThreadGroup} can contain zero or more
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Thread}s and zero or more other {@code ThreadGroup}s. Each {@code
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Thread} and each {@code ThreadGroup} (except the root group) has a unique
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * parent {@code ThreadGroup}. The result is a tree whose inner nodes are
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code ThreadGroup}s and whose leaf nodes are {@code Threads}. The unique
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * root of the tree is a {@code ThreadGroup} that is created at VM startup and
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has the name "system". The benefit of using {@code ThreadGroup}s, in addition
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the mere housekeeping aspect, is that all {@code Thread}s in a {@code
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ThreadGroup} can be manipulated together, that is, the {@code ThreadGroup}
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has methods that delegate to all its all {@code Thread}s.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see Thread
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see SecurityManager
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class ThreadGroup implements Thread.UncaughtExceptionHandler {
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Name of this ThreadGroup
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String name;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-note
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // VM needs this field name for debugging.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-note
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Maximum priority for Threads inside this ThreadGroup
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int maxPriority = Thread.MAX_PRIORITY;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // The ThreadGroup to which this ThreadGroup belongs
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ThreadGroup parent;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-note
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // VM needs this field name for debugging.
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-note
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numThreads;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // The Threads this ThreadGroup contains
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Thread[] childrenThreads = new Thread[5];
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // The number of children groups
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numGroups;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // The ThreadGroups this ThreadGroup contains
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ThreadGroup[] childrenGroups = new ThreadGroup[3];
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Locked when using the childrenGroups field
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private class ChildrenGroupsLock {}
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Object childrenGroupsLock = new ChildrenGroupsLock();
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Locked when using the childrenThreads field
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private class ChildrenThreadsLock {}
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Object childrenThreadsLock = new ChildrenThreadsLock();
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Whether this ThreadGroup is a daemon ThreadGroup or not
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean isDaemon;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Whether this ThreadGroup has already been destroyed or not
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean isDestroyed;
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-added
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* the VM uses these directly; do not rename */
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static ThreadGroup mSystem = new ThreadGroup();
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static ThreadGroup mMain = new ThreadGroup(mSystem, "main");
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-added
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-removed
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // /**
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //  * Used by the JVM to create the "system" ThreadGroup. Construct a
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //  * ThreadGroup instance, and assign the name "system".
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //  */
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // private ThreadGroup() {
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //     name = "system";
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // }
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-removed
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new ThreadGroup with the name provided. The new ThreadGroup
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * will be child of the ThreadGroup to which the
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code Thread.currentThread()} belongs.
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name the name for the ThreadGroup being created
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code checkAccess()} for the parent
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         group fails with a SecurityException
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.Thread#currentThread
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ThreadGroup(String name) {
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(Thread.currentThread().getThreadGroup(), name);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new ThreadGroup with the name provided, as child of the
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * ThreadGroup {@code parent}.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param parent the parent ThreadGroup
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name the name for the ThreadGroup being created
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException if {@code parent} is
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         {@code null}
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code checkAccess()} for the parent
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         group fails with a SecurityException
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if {@code parent} has been
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         destroyed already
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ThreadGroup(ThreadGroup parent, String name) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super();
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (Thread.currentThread() != null) {
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // If parent is null we must throw NullPointerException, but that
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // will be done "for free" with the message send below
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parent.checkAccess();
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.name = name;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.setParent(parent);
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parent != null) {
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.setMaxPriority(parent.getMaxPriority());
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (parent.isDaemon()) {
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.setDaemon(true);
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initialize the special "system" ThreadGroup. Was "main" in Harmony,
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * but we have an additional group above that in Android.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ThreadGroup() {
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.name = "system";
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.setParent(null);
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the number of Threads which are children of the receiver,
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directly or indirectly and are running.
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of children Threads
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int activeCount() {
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = 0;
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock the children thread list
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if(childrenThreads[i].isAlive()) {
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    count++;
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count += this.childrenGroups[i].activeCount();
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return count;
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the number of ThreadGroups which are children of the receiver,
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directly or indirectly.
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of children ThreadGroups
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int activeGroupCount() {
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = 0;
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // One for this group & the subgroups
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count += 1 + this.childrenGroups[i].activeGroupCount();
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return count;
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a Thread to the receiver. This should only be visible to class
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * java.lang.Thread, and should only be called when a new Thread is created
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and initialized by the constructor.
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param thread Thread to add to the receiver
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if the receiver has been destroyed
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         already
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #remove(java.lang.Thread)
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    final void add(Thread thread) throws IllegalThreadStateException {
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!isDestroyed) {
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (childrenThreads.length == numThreads) {
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Thread[] newThreads = new Thread[childrenThreads.length * 2];
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.arraycopy(childrenThreads, 0, newThreads, 0, numThreads);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newThreads[numThreads++] = thread;
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenThreads = newThreads;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenThreads[numThreads++] = thread;
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalThreadStateException();
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a ThreadGroup to the receiver.
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param g ThreadGroup to add to the receiver
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if the receiver has been destroyed
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         already
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void add(ThreadGroup g) throws IllegalThreadStateException {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!isDestroyed) {
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (childrenGroups.length == numGroups) {
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ThreadGroup[] newGroups = new ThreadGroup[childrenGroups.length * 2];
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.arraycopy(childrenGroups, 0, newGroups, 0, numGroups);
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newGroups[numGroups++] = g;
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenGroups = newGroups;
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenGroups[numGroups++] = g;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalThreadStateException();
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does nothing. The definition of this method depends on the deprecated
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method {@link #suspend()}. The exact behavior of this call was never
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * specified.
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param b Used to control low memory implicit suspension
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} (always)
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Required deprecated method suspend().
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean allowThreadSuspension(boolean b) {
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Does not apply to this VM, no-op
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Checks the accessibility of the ThreadGroup from the perspective of the
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * caller. If there is a SecurityManager installed, calls
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code checkAccess} with the receiver as a parameter, otherwise does
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * nothing.
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void checkAccess() {
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Forwards the message to the SecurityManager (if there's one) passing
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // the receiver as parameter
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager currentManager = System.getSecurityManager();
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (currentManager != null) {
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            currentManager.checkAccess(this);
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Destroys the receiver and recursively all its subgroups. It is only legal
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to destroy a ThreadGroup that has no Threads in it. Any daemon
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * ThreadGroup is destroyed automatically when it becomes empty (no Threads
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and no ThreadGroups in it).
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if the receiver or any of its
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         subgroups has been destroyed already or if it still contains
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         threads.
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code this.checkAccess()} fails with
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         a SecurityException
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void destroy() {
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            synchronized (this.childrenGroupsLock) {
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // BEGIN android-added
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (this.isDestroyed) {
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalThreadStateException(
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "Thread group was already destroyed: "
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            + (this.name != null ? this.name : "n/a"));
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (this.numThreads > 0) {
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalThreadStateException(
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "Thread group still contains threads: "
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            + (this.name != null ? this.name : "n/a"));
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // END android-added
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int toDestroy = numGroups;
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Call recursively for subgroups
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (int i = 0; i < toDestroy; i++) {
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // We always get the first element - remember, when the
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // child dies it removes itself from our collection. See
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // below.
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    this.childrenGroups[0].destroy();
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (parent != null) {
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    parent.remove(this);
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Now that the ThreadGroup is really destroyed it can be tagged
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // as so
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.isDestroyed = true;
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Auxiliary method that destroys the receiver and recursively all its
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subgroups if the receiver is a daemon ThreadGroup.
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #destroy
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #setDaemon
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #isDaemon
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void destroyIfEmptyDaemon() {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Has to be non-destroyed daemon to make sense
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (isDaemon && !isDestroyed && numThreads == 0) {
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                synchronized (this.childrenGroupsLock) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (numGroups == 0) {
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        destroy();
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Iterates over all active threads in this group (and its sub-groups) and
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * stores the threads in the given array. Returns when the array is full or
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * no more threads remain, whichever happens first.
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param threads the array into which the Threads will be copied
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of Threads that were copied
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int enumerate(Thread[] threads) {
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return enumerate(threads, true);
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Iterates over all active threads in this group (and, optionally, its
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sub-groups) and stores the threads in the given array. Returns when the
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * array is full or no more threads remain, whichever happens first.
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param threads the array into which the Threads will be copied
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param recurse indicates whether Threads in subgroups should be
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *        recursively copied as well
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of Threads that were copied
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int enumerate(Thread[] threads, boolean recurse) {
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return enumerateGeneric(threads, recurse, 0, true);
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Iterates over all thread groups in this group (and its sub-groups) and
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and stores the groups in the given array. Returns when the array is full
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * or no more groups remain, whichever happens first.
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param groups the array into which the ThreadGroups will be copied
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of ThreadGroups that were copied
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int enumerate(ThreadGroup[] groups) {
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return enumerate(groups, true);
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Iterates over all thread groups in this group (and, optionally, its
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sub-groups) and and stores the groups in the given array. Returns when
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the array is full or no more groups remain, whichever happens first.
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param groups the array into which the ThreadGroups will be copied
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param recurse indicates whether ThreadGroups in subgroups should be
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *        recursively copied as well or not
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of ThreadGroups that were copied
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int enumerate(ThreadGroup[] groups, boolean recurse) {
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return enumerateGeneric(groups, recurse, 0, false);
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Copies into <param>enumeration</param> starting at
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <param>enumerationIndex</param> all Threads or ThreadGroups in the
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * receiver. If <param>recurse</param> is true, recursively enumerate the
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * elements in subgroups.
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the array passed as parameter is too small no exception is thrown -
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the extra elements are simply not copied.
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param enumeration array into which the elements will be copied
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param recurse Indicates whether subgroups should be enumerated or not
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param enumerationIndex Indicates in which position of the enumeration
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *        array we are
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param enumeratingThreads Indicates whether we are enumerating Threads or
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *        ThreadGroups
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return How many elements were enumerated/copied over
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int enumerateGeneric(Object[] enumeration, boolean recurse, int enumerationIndex,
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            boolean enumeratingThreads) {
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object[] immediateCollection = enumeratingThreads ? (Object[]) childrenThreads
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                : (Object[]) childrenGroups;
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object syncLock = enumeratingThreads ? childrenThreadsLock : childrenGroupsLock;
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (syncLock) { // Lock this subpart of the tree as we walk
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = enumeratingThreads ? numThreads : numGroups; --i >= 0;) {
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (!enumeratingThreads || ((Thread) immediateCollection[i]).isAlive()) {
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (enumerationIndex >= enumeration.length) {
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        return enumerationIndex;
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    enumeration[enumerationIndex++] = immediateCollection[i];
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (recurse) { // Lock this subpart of the tree as we walk
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            synchronized (this.childrenGroupsLock) {
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (int i = 0; i < numGroups; i++) {
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (enumerationIndex >= enumeration.length) {
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        return enumerationIndex;
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    enumerationIndex = childrenGroups[i].enumerateGeneric(enumeration, recurse,
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            enumerationIndex, enumeratingThreads);
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return enumerationIndex;
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the maximum allowed priority for a Thread in the receiver.
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the maximum priority
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #setMaxPriority
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getMaxPriority() {
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return maxPriority;
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the name of the receiver.
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the receiver's name
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final String getName() {
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return name;
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the receiver's parent ThreadGroup. It can be {@code null}  if the
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * receiver is the the root ThreadGroup.
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the parent ThreadGroup
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final ThreadGroup getParent() {
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parent != null) {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parent.checkAccess();
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return parent;
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Interrupts every Thread in the receiver and recursively in all its
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subgroups.
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code this.checkAccess()} fails with
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         a SecurityException
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#interrupt
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void interrupt() {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.childrenThreads[i].interrupt();
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.childrenGroups[i].interrupt();
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Checks whether the receiver is a daemon ThreadGroup.
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if (and only if) the receiver is a daemon ThreadGroup
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #setDaemon
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #destroy
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final boolean isDaemon() {
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isDaemon;
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Checks whether the receiver has already been destroyed.
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if (and only if) the receiver has already been destroyed
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #destroy
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized boolean isDestroyed() {
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isDestroyed;
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Outputs to {@code System.out} a text representation of the
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * hierarchy of Threads and ThreadGroups in the receiver (and recursively).
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Proper indentation is done to suggest the nesting of groups inside groups
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and threads inside groups.
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void list() {
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // We start in a fresh line
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println();
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        list(0);
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Outputs to {@code System.out}a text representation of the
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * hierarchy of Threads and ThreadGroups in the receiver (and recursively).
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The indentation will be four spaces per level of nesting.
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param levels How many levels of nesting, so that proper indentation can
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * be output.
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void list(int levels) {
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < levels; i++) {
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.print("    "); // 4 spaces for each level
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Print the receiver
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println(this.toString());
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Print the children threads, with 1 extra indentation
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // children get an extra indentation, 4 spaces for each level
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (int j = 0; j <= levels; j++) {
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.out.print("    ");
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.println(this.childrenThreads[i]);
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.childrenGroups[i].list(levels + 1);
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Checks whether the receiver is a direct or indirect parent group of a
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * given ThreadGroup.
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param g the potential child ThreadGroup
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if (and only if) the receiver is parent of {@code g}
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final boolean parentOf(ThreadGroup g) {
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (g != null) {
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (this == g) {
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            g = g.parent;
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Removes a Thread from the receiver. This should only be visible to class
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * java.lang.Thread, and should only be called when a Thread dies.
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param thread Thread to remove from the receiver
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #add(Thread)
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    final void remove(java.lang.Thread thread) {
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (childrenThreads[i].equals(thread)) {
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    numThreads--;
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            .arraycopy(childrenThreads, i + 1, childrenThreads, i, numThreads
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    - i);
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenThreads[numThreads] = null;
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        destroyIfEmptyDaemon();
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Removes an immediate subgroup from the receiver.
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param g ThreadGroup to remove from the receiver
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #add(Thread)
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #add(ThreadGroup)
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void remove(ThreadGroup g) {
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (childrenGroups[i].equals(g)) {
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    numGroups--;
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.arraycopy(childrenGroups, i + 1, childrenGroups, i, numGroups - i);
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    childrenGroups[numGroups] = null;
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        destroyIfEmptyDaemon();
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Resumes every Thread in the receiver and recursively in all its
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subgroups.
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code this.checkAccess()} fails with
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         a SecurityException
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#resume
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #suspend
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Requires deprecated method Thread.resume().
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("deprecation")
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void resume() {
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.childrenThreads[i].resume();
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                this.childrenGroups[i].resume();
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Configures the receiver to be a daemon ThreadGroup or not. Daemon
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * ThreadGroups are automatically destroyed when they become empty.
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param isDaemon the new value defining if receiver should be daemon or
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *                 not
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code checkAccess()} for the parent
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         group fails with a SecurityException
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #isDaemon
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #destroy
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void setDaemon(boolean isDaemon) {
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.isDaemon = isDaemon;
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Configures the maximum allowed priority for a Thread in the receiver and
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * recursively in all its subgroups.
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * One can never change the maximum priority of a ThreadGroup to be higher
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * than it was. Such an attempt will not result in an exception, it will
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * simply leave the ThreadGroup with its current maximum priority.
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param newMax the new maximum priority to be set
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code checkAccess()} fails with a
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         SecurityException
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException if the new priority is greater than
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         Thread.MAX_PRIORITY or less than Thread.MIN_PRIORITY
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #getMaxPriority
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void setMaxPriority(int newMax) {
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newMax <= this.maxPriority) {
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (newMax < Thread.MIN_PRIORITY) {
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                newMax = Thread.MIN_PRIORITY;
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int parentPriority = parent == null ? newMax : parent.getMaxPriority();
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.maxPriority = parentPriority <= newMax ? parentPriority : newMax;
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Lock this subpart of the tree as we walk
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            synchronized (this.childrenGroupsLock) {
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // ??? why not maxPriority
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (int i = 0; i < numGroups; i++) {
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    this.childrenGroups[i].setMaxPriority(newMax);
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the parent ThreadGroup of the receiver, and adds the receiver to the
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parent's collection of immediate children (if {@code parent} is
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not {@code null}).
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param parent The parent ThreadGroup, or null if the receiver is to be
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *        the root ThreadGroup
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #getParent
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #parentOf
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void setParent(ThreadGroup parent) {
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parent != null) {
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parent.add(this);
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.parent = parent;
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Stops every Thread in the receiver and recursively in all its subgroups.
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code this.checkAccess()} fails with
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         a SecurityException
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#stop()
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#stop(Throwable)
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see ThreadDeath
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Requires deprecated method Thread.stop().
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("deprecation")
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void stop() {
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (stopHelper()) {
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Thread.currentThread().stop();
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Requires deprecated method Thread.suspend().
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("deprecation")
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final boolean stopHelper() {
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean stopCurrent = false;
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Thread current = Thread.currentThread();
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (this.childrenThreads[i] == current) {
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    stopCurrent = true;
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    this.childrenThreads[i].stop();
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                stopCurrent |= this.childrenGroups[i].stopHelper();
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return stopCurrent;
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Suspends every Thread in the receiver and recursively in all its
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subgroups.
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException if {@code this.checkAccess()} fails with
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         a SecurityException
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#suspend
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #resume
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Requires deprecated method Thread.suspend().
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("deprecation")
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void suspend() {
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (suspendHelper()) {
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Thread.currentThread().suspend();
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated Requires deprecated method Thread.suspend().
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("deprecation")
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final boolean suspendHelper() {
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkAccess();
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean suspendCurrent = false;
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenThreadsLock) {
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Thread current = Thread.currentThread();
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numThreads; i++) {
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (this.childrenThreads[i] == current) {
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    suspendCurrent = true;
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    this.childrenThreads[i].suspend();
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Lock this subpart of the tree as we walk
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized (this.childrenGroupsLock) {
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < numGroups; i++) {
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                suspendCurrent |= this.childrenGroups[i].suspendHelper();
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return suspendCurrent;
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a string containing a concise, human-readable description of the
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * receiver.
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a printable representation of the ThreadGroup
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toString() {
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getClass().getName() + "[name=" + this.getName() + ",maxpri="
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                + this.getMaxPriority() + "]";
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Handles uncaught exceptions. Any uncaught exception in any Thread
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is forwarded (by the VM) to the Thread's ThreadGroup by sending this
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * message (uncaughtException). This allows users to define custom
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * ThreadGroup classes and custom behavior for when a Thread has an
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * uncaughtException or when it does (ThreadDeath).
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param t the Thread that terminated with an uncaught exception
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param e the uncaught exception itself
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#stop()
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Thread#stop(Throwable)
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see ThreadDeath
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void uncaughtException(Thread t, Throwable e) {
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parent != null) {
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parent.uncaughtException(t, e);
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (Thread.getDefaultUncaughtExceptionHandler() != null) {
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // TODO The spec is unclear regarding this. What do we do?
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, e);
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (!(e instanceof ThreadDeath)) {
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // No parent group, has to be 'system' Thread Group
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            e.printStackTrace(System.err);
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-added
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Non-standard method for adding a thread to a group, required by Dalvik.
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param thread Thread to add to the receiver
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if the receiver has been destroyed
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         already
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #add(java.lang.Thread)
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #removeThread(java.lang.Thread)
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void addThread(Thread thread) throws IllegalThreadStateException {
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        add(thread);
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Non-standard method for adding a thread to a group, required by Dalvik.
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param thread Thread to add to the receiver
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalThreadStateException if the receiver has been destroyed
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         already
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #remove(java.lang.Thread)
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #addThread(java.lang.Thread)
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void removeThread(Thread thread) throws IllegalThreadStateException {
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        remove(thread);
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-added
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
927