1 /*
2  * Copyright (C) 2013 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 com.android.dialer.binary.common;
18 
19 import android.app.Application;
20 import android.os.StrictMode;
21 import android.os.Trace;
22 import android.support.annotation.NonNull;
23 import com.android.dialer.blocking.BlockedNumbersAutoMigrator;
24 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
25 import com.android.dialer.buildtype.BuildType;
26 import com.android.dialer.calllog.CallLogComponent;
27 import com.android.dialer.common.concurrent.DefaultDialerExecutorFactory;
28 import com.android.dialer.inject.HasRootComponent;
29 import com.android.dialer.notification.NotificationChannelManager;
30 import com.android.dialer.persistentlog.PersistentLogger;
31 
32 /** A common application subclass for all Dialer build variants. */
33 public abstract class DialerApplication extends Application implements HasRootComponent {
34 
35   private volatile Object rootComponent;
36 
37   @Override
onCreate()38   public void onCreate() {
39     Trace.beginSection("DialerApplication.onCreate");
40     if (BuildType.get() == BuildType.BUGFOOD) {
41       enableStrictMode();
42     }
43     super.onCreate();
44     new BlockedNumbersAutoMigrator(
45             this.getApplicationContext(),
46             new FilteredNumberAsyncQueryHandler(this),
47             new DefaultDialerExecutorFactory())
48         .asyncAutoMigrate();
49     CallLogComponent.get(this).callLogFramework().registerContentObservers(getApplicationContext());
50     PersistentLogger.initialize(this);
51 
52     NotificationChannelManager.getInstance().firstInitIfNeeded(this);
53     Trace.endSection();
54   }
55 
enableStrictMode()56   private void enableStrictMode() {
57     StrictMode.setThreadPolicy(
58         new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build());
59     StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
60   }
61 
62   /**
63    * Returns a new instance of the root component for the application. Sub classes should define a
64    * root component that extends all the sub components "HasComponent" intefaces. The component
65    * should specify all modules that the application supports and provide stubs for the remainder.
66    */
67   @NonNull
buildRootComponent()68   protected abstract Object buildRootComponent();
69 
70   /** Returns a cached instance of application's root component. */
71   @Override
72   @NonNull
component()73   public final Object component() {
74     Object result = rootComponent;
75     if (result == null) {
76       synchronized (this) {
77         result = rootComponent;
78         if (result == null) {
79           rootComponent = result = buildRootComponent();
80         }
81       }
82     }
83     return result;
84   }
85 }
86