1 /*
2  * Copyright 2020 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 androidx.startup;
18 
19 import android.app.Application;
20 import android.content.ContentProvider;
21 import android.content.ContentValues;
22 import android.content.Context;
23 import android.database.Cursor;
24 import android.net.Uri;
25 
26 import org.jspecify.annotations.NonNull;
27 import org.jspecify.annotations.Nullable;
28 
29 /**
30  * The {@link ContentProvider} which discovers {@link Initializer}s in an application and
31  * initializes them before {@link Application#onCreate()}.
32  */
33 public class InitializationProvider extends ContentProvider {
34 
35     @Override
onCreate()36     public final boolean onCreate() {
37         Context context = getContext();
38         if (context != null) {
39             // Many Initializer's expect the `applicationContext` to be non-null. This
40             // typically happens when `android:sharedUid` is used. In such cases, we postpone
41             // initialization altogether, and rely on lazy init.
42             // More context: b/196959015
43             Context applicationContext = context.getApplicationContext();
44             if (applicationContext != null) {
45                 // Pass the class context so the right metadata can be read.
46                 // This is especially important in the context of apps that want to use
47                 // InitializationProvider in multiple processes.
48                 // b/183136596#comment18
49                 AppInitializer.getInstance(context).discoverAndInitialize(getClass());
50             } else {
51                 StartupLogger.w("Deferring initialization because `applicationContext` is null.");
52             }
53         } else {
54             throw new StartupException("Context cannot be null");
55         }
56         return true;
57     }
58 
59     @Override
query( @onNull Uri uri, String @Nullable [] projection, @Nullable String selection, String @Nullable [] selectionArgs, @Nullable String sortOrder)60     public final @Nullable Cursor query(
61             @NonNull Uri uri,
62             String @Nullable [] projection,
63             @Nullable String selection,
64             String @Nullable [] selectionArgs,
65             @Nullable String sortOrder) {
66         throw new IllegalStateException("Not allowed.");
67     }
68 
69     @Override
getType(@onNull Uri uri)70     public final @Nullable String getType(@NonNull Uri uri) {
71         throw new IllegalStateException("Not allowed.");
72     }
73 
74     @Override
insert(@onNull Uri uri, @Nullable ContentValues values)75     public final @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
76         throw new IllegalStateException("Not allowed.");
77     }
78 
79     @Override
delete( @onNull Uri uri, @Nullable String selection, String @Nullable [] selectionArgs)80     public final int delete(
81             @NonNull Uri uri,
82             @Nullable String selection,
83             String @Nullable [] selectionArgs) {
84         throw new IllegalStateException("Not allowed.");
85     }
86 
87     @Override
update( @onNull Uri uri, @Nullable ContentValues values, @Nullable String selection, String @Nullable [] selectionArgs)88     public final int update(
89             @NonNull Uri uri,
90             @Nullable ContentValues values,
91             @Nullable String selection,
92             String @Nullable [] selectionArgs) {
93         throw new IllegalStateException("Not allowed.");
94     }
95 }
96