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 java.util.Objects; 20 import java.util.TimeZone; 21 import java.util.function.Supplier; 22 23 /** 24 * Provides lifecycle methods and other hooks for an Android runtime "container" to call into the 25 * runtime and core libraries during initialization. For example, from 26 * {@link com.android.internal.os.RuntimeInit}. 27 * 28 * <p>Having a facade class helps to limit the container's knowledge of runtime and core libraries 29 * internal details. All methods assume the container initialization is single threaded. 30 * 31 * @hide 32 */ 33 @libcore.api.CorePlatformApi 34 public final class RuntimeHooks { 35 36 private static Supplier<String> zoneIdSupplier; 37 RuntimeHooks()38 private RuntimeHooks() { 39 // No need to construct an instance. All methods are static. 40 } 41 42 /** 43 * Sets the {@link Supplier} that is used by {@link TimeZone} to retrieve the current time zone 44 * ID iff the cached default is {@code null}. 45 * 46 * <p>This method also clears the current {@link TimeZone} default ensuring that the supplier 47 * will be used next time {@link TimeZone#getDefault()} is called (unless 48 * {@link TimeZone#setDefault(TimeZone)} is called with a non-null value in the interim). 49 * 50 * <p>Once set the supplier cannot be changed. 51 */ 52 @libcore.api.CorePlatformApi setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier)53 public static void setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier) { 54 if (RuntimeHooks.zoneIdSupplier != null) { 55 throw new UnsupportedOperationException("zoneIdSupplier instance already set"); 56 } 57 RuntimeHooks.zoneIdSupplier = Objects.requireNonNull(zoneIdSupplier); 58 TimeZone.setDefault(null); 59 } 60 61 /** 62 * Returns the {@link Supplier} that should be used to discover the time zone. 63 */ getTimeZoneIdSupplier()64 public static Supplier<String> getTimeZoneIdSupplier() { 65 return RuntimeHooks.zoneIdSupplier; 66 } 67 68 /** 69 * Sets an {@link Thread.UncaughtExceptionHandler} that will be called before any 70 * returned by {@link Thread#getUncaughtExceptionHandler()}. To allow the standard 71 * handlers to run, this handler should never terminate this process. Any 72 * throwables thrown by the handler will be ignored by 73 * {@link Thread#dispatchUncaughtException(Throwable)}. 74 */ 75 @libcore.api.CorePlatformApi setUncaughtExceptionPreHandler( Thread.UncaughtExceptionHandler uncaughtExceptionHandler)76 public static void setUncaughtExceptionPreHandler( 77 Thread.UncaughtExceptionHandler uncaughtExceptionHandler) { 78 Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); 79 } 80 } 81