• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 package com.android.adservices.topics;
17 
18 import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_API_CALLED__API_CLASS__TARGETING;
19 import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__TOPICS_API_DISABLED;
20 import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__TOPICS;
21 
22 import android.app.Service;
23 import android.content.Intent;
24 import android.os.Build;
25 import android.os.IBinder;
26 
27 import androidx.annotation.RequiresApi;
28 
29 import com.android.adservices.LoggerFactory;
30 import com.android.adservices.data.enrollment.EnrollmentDao;
31 import com.android.adservices.download.MddJobService;
32 import com.android.adservices.download.MobileDataDownloadFactory;
33 import com.android.adservices.errorlogging.ErrorLogUtil;
34 import com.android.adservices.service.FlagsFactory;
35 import com.android.adservices.service.MaintenanceJobService;
36 import com.android.adservices.service.common.AppImportanceFilter;
37 import com.android.adservices.service.common.PackageChangedReceiver;
38 import com.android.adservices.service.common.Throttler;
39 import com.android.adservices.service.consent.AdServicesApiType;
40 import com.android.adservices.service.consent.ConsentManager;
41 import com.android.adservices.service.stats.AdServicesLoggerImpl;
42 import com.android.adservices.service.stats.Clock;
43 import com.android.adservices.service.topics.CacheManager;
44 import com.android.adservices.service.topics.EpochJobService;
45 import com.android.adservices.service.topics.EpochManager;
46 import com.android.adservices.service.topics.TopicsServiceImpl;
47 import com.android.adservices.service.topics.TopicsWorker;
48 
49 import java.io.FileDescriptor;
50 import java.io.PrintWriter;
51 import java.util.Objects;
52 
53 /** Topics Service */
54 // TODO(b/269798827): Enable for R.
55 @RequiresApi(Build.VERSION_CODES.S)
56 public class TopicsService extends Service {
57     private static final LoggerFactory.Logger sLogger = LoggerFactory.getTopicsLogger();
58 
59     /** The binder service. This field must only be accessed on the main thread. */
60     private TopicsServiceImpl mTopicsService;
61 
62     @Override
onCreate()63     public void onCreate() {
64         super.onCreate();
65 
66         if (FlagsFactory.getFlags().getTopicsKillSwitch()) {
67             sLogger.e("onCreate(): Topics API is disabled");
68             ErrorLogUtil.e(
69                     AD_SERVICES_ERROR_REPORTED__ERROR_CODE__TOPICS_API_DISABLED,
70                     AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__TOPICS,
71                     "TopicsService",
72                     "onCreate");
73             return;
74         }
75 
76         AppImportanceFilter appImportanceFilter =
77                 AppImportanceFilter.create(
78                         this,
79                         AD_SERVICES_API_CALLED__API_CLASS__TARGETING,
80                         () -> FlagsFactory.getFlags().getForegroundStatuslLevelForValidation());
81 
82         if (mTopicsService == null) {
83             mTopicsService =
84                     new TopicsServiceImpl(
85                             this,
86                             TopicsWorker.getInstance(this),
87                             ConsentManager.getInstance(this),
88                             AdServicesLoggerImpl.getInstance(),
89                             Clock.SYSTEM_CLOCK,
90                             FlagsFactory.getFlags(),
91                             Throttler.getInstance(FlagsFactory.getFlags()),
92                             EnrollmentDao.getInstance(this),
93                             appImportanceFilter);
94             mTopicsService.init();
95         }
96         if (hasUserConsent()) {
97             PackageChangedReceiver.enableReceiver(this, FlagsFactory.getFlags());
98             schedulePeriodicJobs();
99         }
100     }
101 
schedulePeriodicJobs()102     private void schedulePeriodicJobs() {
103         MaintenanceJobService.scheduleIfNeeded(this, /* forceSchedule */ false);
104         EpochJobService.scheduleIfNeeded(this, /* forceSchedule */ false);
105         MddJobService.scheduleIfNeeded(this, /* forceSchedule */ false);
106     }
107 
hasUserConsent()108     private boolean hasUserConsent() {
109         if (FlagsFactory.getFlags().getGaUxFeatureEnabled()) {
110             return ConsentManager.getInstance(this).getConsent(AdServicesApiType.TOPICS).isGiven();
111         } else {
112             return ConsentManager.getInstance(this).getConsent().isGiven();
113         }
114     }
115 
116     @Override
onBind(Intent intent)117     public IBinder onBind(Intent intent) {
118         if (FlagsFactory.getFlags().getTopicsKillSwitch()) {
119             sLogger.e("onBind(): Topics API is disabled, return nullBinding.");
120             ErrorLogUtil.e(
121                     AD_SERVICES_ERROR_REPORTED__ERROR_CODE__TOPICS_API_DISABLED,
122                     AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__TOPICS,
123                     "TopicsService",
124                     "onBind");
125             // Return null so that clients can not bind to the service.
126             return null;
127         }
128         return Objects.requireNonNull(mTopicsService);
129     }
130 
131     // TODO(b/246316128): Add dump() in Consent Manager.
132     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)133     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
134         super.dump(fd, writer, args);
135         FlagsFactory.getFlags().dump(writer, args);
136         if (Build.isDebuggable()) {
137             writer.println("Build is Debuggable, dumping information for TopicsService");
138             EpochManager.getInstance(this).dump(writer, args);
139             CacheManager.getInstance(this).dump(writer, args);
140             MobileDataDownloadFactory.dump(this, writer);
141             writer.println("=== User Consent State For Topics Service ===");
142             writer.println("User Consent is given: " + hasUserConsent());
143         } else {
144             writer.println("Build is not Debuggable");
145         }
146     }
147 }
148