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.Trace;
21 import android.support.annotation.NonNull;
22 import android.support.v4.os.BuildCompat;
23 import com.android.dialer.blocking.BlockedNumbersAutoMigrator;
24 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
25 import com.android.dialer.calllog.CallLogComponent;
26 import com.android.dialer.calllog.CallLogFramework;
27 import com.android.dialer.calllog.config.CallLogConfig;
28 import com.android.dialer.calllog.config.CallLogConfigComponent;
29 import com.android.dialer.common.LogUtil;
30 import com.android.dialer.common.concurrent.DialerExecutorComponent;
31 import com.android.dialer.inject.HasRootComponent;
32 import com.android.dialer.notification.NotificationChannelManager;
33 import com.android.dialer.persistentlog.PersistentLogger;
34 import com.android.dialer.strictmode.StrictModeComponent;
35 
36 /** A common application subclass for all Dialer build variants. */
37 public abstract class DialerApplication extends Application implements HasRootComponent {
38 
39   private volatile Object rootComponent;
40 
41   @Override
onCreate()42   public void onCreate() {
43     Trace.beginSection("DialerApplication.onCreate");
44     StrictModeComponent.get(this).getDialerStrictMode().onApplicationCreate(this);
45     super.onCreate();
46     new BlockedNumbersAutoMigrator(
47             this.getApplicationContext(),
48             new FilteredNumberAsyncQueryHandler(this),
49             DialerExecutorComponent.get(this).dialerExecutorFactory())
50         .asyncAutoMigrate();
51     initializeAnnotatedCallLog();
52     PersistentLogger.initialize(this);
53 
54     if (BuildCompat.isAtLeastO()) {
55       NotificationChannelManager.initChannels(this);
56     }
57     Trace.endSection();
58   }
59 
initializeAnnotatedCallLog()60   private void initializeAnnotatedCallLog() {
61     CallLogConfig callLogConfig = CallLogConfigComponent.get(this).callLogConfig();
62     callLogConfig.schedulePollingJob();
63 
64     if (callLogConfig.isCallLogFrameworkEnabled()) {
65       CallLogFramework callLogFramework = CallLogComponent.get(this).callLogFramework();
66       callLogFramework.registerContentObservers();
67     } else {
68       LogUtil.i("DialerApplication.initializeAnnotatedCallLog", "framework not enabled");
69     }
70   }
71 
72   /**
73    * Returns a new instance of the root component for the application. Sub classes should define a
74    * root component that extends all the sub components "HasComponent" intefaces. The component
75    * should specify all modules that the application supports and provide stubs for the remainder.
76    */
77   @NonNull
buildRootComponent()78   protected abstract Object buildRootComponent();
79 
80   /** Returns a cached instance of application's root component. */
81   @Override
82   @NonNull
component()83   public final Object component() {
84     Object result = rootComponent;
85     if (result == null) {
86       synchronized (this) {
87         result = rootComponent;
88         if (result == null) {
89           rootComponent = result = buildRootComponent();
90         }
91       }
92     }
93     return result;
94   }
95 }
96