1/* 2 * Copyright 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 17package androidx.core.app; 18 19import android.app.Activity; 20import android.app.AppComponentFactory; 21import android.app.Application; 22import android.app.Service; 23import android.content.BroadcastReceiver; 24import android.content.ContentProvider; 25import android.content.Intent; 26 27import androidx.annotation.RequiresApi; 28import androidx.annotation.RestrictTo; 29 30/** 31 * Instance of AppComponentFactory for support libraries. 32 * @see CompatWrapped 33 * @hide 34 */ 35@RequiresApi(api = 28) 36@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 37public class CoreComponentFactory extends AppComponentFactory { 38 private static final String TAG = "CoreComponentFactory"; 39 40 @Override 41 public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) 42 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 43 return checkCompatWrapper(super.instantiateActivity(cl, className, intent)); 44 } 45 46 @Override 47 public Application instantiateApplication(ClassLoader cl, String className) 48 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 49 return checkCompatWrapper(super.instantiateApplication(cl, className)); 50 } 51 52 @Override 53 public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, 54 Intent intent) 55 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 56 return checkCompatWrapper(super.instantiateReceiver(cl, className, intent)); 57 } 58 59 @Override 60 public ContentProvider instantiateProvider(ClassLoader cl, String className) 61 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 62 return checkCompatWrapper(super.instantiateProvider(cl, className)); 63 } 64 65 @Override 66 public Service instantiateService(ClassLoader cl, String className, Intent intent) 67 throws InstantiationException, IllegalAccessException, ClassNotFoundException { 68 return checkCompatWrapper(super.instantiateService(cl, className, intent)); 69 } 70 71 static <T> T checkCompatWrapper(T obj) { 72 if (obj instanceof CompatWrapped) { 73 T wrapper = (T) ((CompatWrapped) obj).getWrapper(); 74 if (wrapper != null) { 75 return wrapper; 76 } 77 } 78 return obj; 79 } 80 81 /** 82 * Implement this interface to allow a different class to be returned when instantiating 83 * on certain API levels. 84 * @hide 85 */ 86 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 87 public interface CompatWrapped { 88 /** 89 * Called while this class is being instantiated by the OS. 90 * 91 * If an object is returned then it will be used in place of the class. 92 * Note: this will not be called on API <= 27. 93 * 94 * Example: 95 * <pre class="prettyprint"> 96 * {@literal 97 * public AndroidXContentProvider extends ContentProvider implements CompatWrapped { 98 * ... 99 * 100 * public Object getWrapper() { 101 * if (SDK_INT >= 29) { 102 * return new AndroidXContentProviderV29(this); 103 * } 104 * return null; 105 * } 106 * } 107 * } 108 * </pre> 109 */ 110 Object getWrapper(); 111 } 112 113} 114