File: chrome_main_delegate_android.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (132 lines) | stat: -rw-r--r-- 5,812 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/android/chrome_main_delegate_android.h"

#include <memory>
#include <variant>

#include "base/android/jni_android.h"
#include "base/base_paths_android.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/android/chrome_startup_flags.h"
#include "chrome/browser/android/metrics/uma_utils.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/common/profiler/main_thread_stack_sampling_profiler.h"
#include "components/policy/core/common/android/android_combined_policy_provider.h"
#include "components/startup_metric_utils/common/startup_metric_utils.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_switches.h"

namespace {
// Whether to use the process start time for startup metrics.
BASE_FEATURE(kUseProcessStartTimeForMetrics,
             "UseProcessStartTimeForMetrics",
             base::FEATURE_DISABLED_BY_DEFAULT);
}  // namespace

// ChromeMainDelegateAndroid is created when the library is loaded. It is always
// done in the process' main Java thread. But for a non-browser process, e.g.
// renderer process, it is not the native Chrome's main thread.
ChromeMainDelegateAndroid::ChromeMainDelegateAndroid() = default;
ChromeMainDelegateAndroid::~ChromeMainDelegateAndroid() = default;

std::optional<int> ChromeMainDelegateAndroid::BasicStartupComplete() {
  TRACE_EVENT0("startup", "ChromeMainDelegateAndroid::BasicStartupComplete");
  policy::android::AndroidCombinedPolicyProvider::SetShouldWaitForPolicy(true);
  SetChromeSpecificCommandLineFlags();

  return ChromeMainDelegate::BasicStartupComplete();
}

void ChromeMainDelegateAndroid::PreSandboxStartup() {
  ChromeMainDelegate::PreSandboxStartup();

  // PoissonAllocationSampler's TLS slots need to be set up before
  // MainThreadStackSamplingProfiler, which can allocate TLS slots of its own.
  // On some platforms pthreads can malloc internally to access higher-numbered
  // TLS slots, which can cause reentry in the heap profiler. (See the comment
  // on ReentryGuard::InitTLSSlot().)
  // TODO(crbug.com/40062835): Clean up other paths that call this Init()
  // function, which are now redundant.
  base::PoissonAllocationSampler::Init();

  // We only create a MainThreadStackSamplingProfiler for the browser process.
  // `ChromeContentGpuClient` and `ChromeContentRendererClient` create their own
  // `ThreadProfiler` for the child processes.
  auto type = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
      switches::kProcessType);
  if (type.empty()) {
    CHECK(chrome_content_browser_client_);
    // Start the sampling profiler after crashpad initialization.
    chrome_content_browser_client_->SetSamplingProfiler(
        std::make_unique<MainThreadStackSamplingProfiler>());
  }
}

void ChromeMainDelegateAndroid::SecureDataDirectory() {
  // By default, Android creates the directory accessible by others.
  // We'd like to tighten security and make it accessible only by
  // the browser process.
  // TODO(crbug.com/41382891): Remove this once minsdk >= 21,
  // at which point this will be handled by PathUtils.java.
  base::FilePath data_path;
  bool ok = base::PathService::Get(base::DIR_ANDROID_APP_DATA, &data_path);
  if (ok) {
    ok = base::SetPosixFilePermissions(data_path,
                                       base::FILE_PERMISSION_USER_MASK);
  }
  if (!ok) {
    LOG(ERROR) << "Failed to set data directory permissions";
  }
}

std::variant<int, content::MainFunctionParams>
ChromeMainDelegateAndroid::RunProcess(
    const std::string& process_type,
    content::MainFunctionParams main_function_params) {
  TRACE_EVENT0("startup", "ChromeMainDelegateAndroid::RunProcess");
  // Defer to the default main method outside the browser process.
  if (!process_type.empty())
    return std::move(main_function_params);

  SecureDataDirectory();

  // Because the browser process can be started asynchronously as a series of
  // UI thread tasks a second request to start it can come in while the
  // first request is still being processed. Chrome must keep the same
  // browser runner for the second request.
  // Also only record the start time the first time round, since this is the
  // start time of the application, and will be same for all requests.
  if (!browser_runner_) {
    base::TimeTicks process_start_time = chrome::android::GetProcessStartTime();
    base::TimeTicks application_start_time =
        chrome::android::GetApplicationStartTime();
    if (!process_start_time.is_null()) {
      startup_metric_utils::GetCommon().RecordStartupProcessCreationTime(
          process_start_time);
      // TODO(crbug.com/40719075): Perf bots should add support for measuring
      // Startup.LoadTime.ProcessCreateToApplicationStart, then the
      // kUseProcessStartTimeForMetrics feature can be removed.
      if (base::FeatureList::IsEnabled(kUseProcessStartTimeForMetrics))
        application_start_time = process_start_time;
    }
    startup_metric_utils::GetCommon().RecordApplicationStartTime(
        application_start_time);
    browser_runner_ = content::BrowserMainRunner::Create();
  }

  int exit_code = browser_runner_->Initialize(std::move(main_function_params));
  // On Android we do not run BrowserMain(), so the above initialization of a
  // BrowserMainRunner is all we want to occur. Preserve any error codes > 0.
  if (exit_code > 0)
    return exit_code;
  return 0;
}