1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dalvik.system; 18 19 import dalvik.system.ThreadPrioritySetter; 20 21 import java.util.Objects; 22 import java.util.TimeZone; 23 import java.util.function.Supplier; 24 25 import libcore.util.NonNull; 26 import libcore.util.Nullable; 27 28 /** 29 * Provides lifecycle methods and other hooks for an Android runtime "container" to call into the 30 * runtime and core libraries during initialization. For example, from 31 * {@link com.android.internal.os.RuntimeInit}. 32 * 33 * <p>Having a facade class helps to limit the container's knowledge of runtime and core libraries 34 * internal details. All methods assume the container initialization is single threaded. 35 * 36 * @hide 37 */ 38 @libcore.api.CorePlatformApi 39 public final class RuntimeHooks { 40 41 private static Supplier<String> zoneIdSupplier; 42 43 // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784 44 private static volatile ThreadPrioritySetter threadPrioritySetter; 45 // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784 46 RuntimeHooks()47 private RuntimeHooks() { 48 // No need to construct an instance. All methods are static. 49 } 50 51 /** 52 * Sets the {@link Supplier} that is used by {@link TimeZone} to retrieve the current time zone 53 * ID iff the cached default is {@code null}. 54 * 55 * <p>This method also clears the current {@link TimeZone} default ensuring that the supplier 56 * will be used next time {@link TimeZone#getDefault()} is called (unless 57 * {@link TimeZone#setDefault(TimeZone)} is called with a non-null value in the interim). 58 * 59 * <p>Once set the supplier cannot be changed. 60 */ 61 @libcore.api.CorePlatformApi setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier)62 public static void setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier) { 63 if (RuntimeHooks.zoneIdSupplier != null) { 64 throw new UnsupportedOperationException("zoneIdSupplier instance already set"); 65 } 66 RuntimeHooks.zoneIdSupplier = Objects.requireNonNull(zoneIdSupplier); 67 TimeZone.setDefault(null); 68 } 69 70 /** 71 * Returns the {@link Supplier} that should be used to discover the time zone. 72 */ getTimeZoneIdSupplier()73 public static Supplier<String> getTimeZoneIdSupplier() { 74 return RuntimeHooks.zoneIdSupplier; 75 } 76 77 /** 78 * Sets an {@link Thread.UncaughtExceptionHandler} that will be called before any 79 * returned by {@link Thread#getUncaughtExceptionHandler()}. To allow the standard 80 * handlers to run, this handler should never terminate this process. Any 81 * throwables thrown by the handler will be ignored by 82 * {@link Thread#dispatchUncaughtException(Throwable)}. 83 */ 84 @libcore.api.CorePlatformApi setUncaughtExceptionPreHandler( Thread.UncaughtExceptionHandler uncaughtExceptionHandler)85 public static void setUncaughtExceptionPreHandler( 86 Thread.UncaughtExceptionHandler uncaughtExceptionHandler) { 87 Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); 88 } 89 90 // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784 91 /** 92 * Sets a {@link ThreadPrioritySetter} that will be invoked instead of 93 * the default implementation during {@link Thread.setPriority(int)}. 94 * @hide 95 */ 96 @libcore.api.CorePlatformApi setThreadPrioritySetter(@onNull ThreadPrioritySetter threadPrioritySetter)97 public static void setThreadPrioritySetter(@NonNull ThreadPrioritySetter threadPrioritySetter) { 98 RuntimeHooks.threadPrioritySetter = Objects.requireNonNull(threadPrioritySetter); 99 } 100 101 /** 102 * Returns the last {@code ThreadPrioritySetter} that has been 103 * {@code #setThreadPrioritySetter(ThreadPrioritySetter) set}, or 104 * null if the setter has not yet been called. 105 * @hide 106 */ getThreadPrioritySetter()107 public static @Nullable ThreadPrioritySetter getThreadPrioritySetter() { 108 return threadPrioritySetter; 109 } 110 // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784 111 } 112