Home | History | Annotate | Download | only in service
      1 /*
      2  * Copyright (C) 2019 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 #include "src/traced/service/lazy_producer.h"
     18 
     19 #include "perfetto/base/build_config.h"
     20 
     21 #include "perfetto/tracing/core/data_source_config.h"
     22 #include "perfetto/tracing/core/data_source_descriptor.h"
     23 
     24 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
     25 #include <sys/system_properties.h>
     26 #endif
     27 
     28 namespace perfetto {
     29 
     30 LazyProducer::LazyProducer(base::TaskRunner* task_runner,
     31                            uint32_t delay_ms,
     32                            std::string data_source_name,
     33                            std::string property_name)
     34     : task_runner_(task_runner),
     35       delay_ms_(delay_ms),
     36       data_source_name_(data_source_name),
     37       property_name_(property_name),
     38       weak_factory_(this) {}
     39 
     40 void LazyProducer::ConnectInProcess(TracingService* svc) {
     41   endpoint_ = svc->ConnectProducer(this, geteuid(), "lazy_producer",
     42                                    /*shm_hint_kb*/ 16, /*in_process*/ true);
     43 }
     44 
     45 void LazyProducer::OnConnect() {
     46   DataSourceDescriptor dsd;
     47   dsd.set_name(data_source_name_);
     48   endpoint_->RegisterDataSource(dsd);
     49 }
     50 
     51 void LazyProducer::SetupDataSource(DataSourceInstanceID,
     52                                    const DataSourceConfig&) {
     53   SetAndroidProperty(property_name_, "1");
     54   active_sessions_++;
     55   generation_++;
     56 }
     57 
     58 void LazyProducer::StopDataSource(DataSourceInstanceID) {
     59   if (--active_sessions_)
     60     return;
     61 
     62   uint64_t cur_generation = generation_;
     63   auto weak_this = weak_factory_.GetWeakPtr();
     64   task_runner_->PostDelayedTask(
     65       [weak_this, cur_generation] {
     66         if (!weak_this)
     67           return;
     68         if (weak_this->generation_ == cur_generation)
     69           weak_this->SetAndroidProperty(weak_this->property_name_, "0");
     70       },
     71       delay_ms_);
     72 }
     73 
     74 bool LazyProducer::SetAndroidProperty(const std::string& name,
     75                                       const std::string& value) {
     76 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
     77   return __system_property_set(name.c_str(), value.c_str()) == 0;
     78 #else
     79   // Allow this to be mocked out for tests on other platforms.
     80   base::ignore_result(name);
     81   base::ignore_result(value);
     82   return true;
     83 #endif
     84 }
     85 
     86 LazyProducer::~LazyProducer() {
     87   if (active_sessions_)
     88     SetAndroidProperty(property_name_, "0");
     89 }
     90 
     91 }  // namespace perfetto
     92