99 lines
3.9 KiB
Java
99 lines
3.9 KiB
Java
// Copyright 2015 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package org.chromium.base;
|
|
|
|
import android.content.Context;
|
|
import android.provider.Settings;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import org.chromium.base.supplier.Supplier;
|
|
|
|
import java.io.File;
|
|
|
|
/** Provides implementation of command line initialization for Android. */
|
|
public final class CommandLineInitUtil {
|
|
/**
|
|
* The location of the command line file needs to be in a protected
|
|
* directory so requires root access to be tweaked, i.e., no other app in a
|
|
* regular (non-rooted) device can change this file's contents.
|
|
* See below for debugging on a regular (non-rooted) device.
|
|
*/
|
|
private static final String COMMAND_LINE_FILE_PATH = "/data/local";
|
|
|
|
/**
|
|
* This path (writable by the shell in regular non-rooted "user" builds) is used when:
|
|
* 1) The "debug app" is set to the application calling this.
|
|
* and
|
|
* 2) ADB is enabled.
|
|
* 3) Force enabled by the embedder.
|
|
*/
|
|
private static final String COMMAND_LINE_FILE_PATH_DEBUG_APP = "/data/local/tmp";
|
|
|
|
/** The name of the command line file to pull arguments from. */
|
|
private static String sFilenameOverrideForTesting;
|
|
|
|
private CommandLineInitUtil() {}
|
|
|
|
/** Set the filename to use. */
|
|
public static void setFilenameOverrideForTesting(String value) {
|
|
sFilenameOverrideForTesting = value;
|
|
}
|
|
|
|
/**
|
|
* Initializes the CommandLine class, pulling command line arguments from {@code fileName}.
|
|
* @param fileName The name of the command line file to pull arguments from.
|
|
*/
|
|
public static void initCommandLine(String fileName) {
|
|
initCommandLine(fileName, null);
|
|
}
|
|
|
|
/**
|
|
* Initializes the CommandLine class, pulling command line arguments from {@code fileName}.
|
|
* @param fileName The name of the command line file to pull arguments from.
|
|
* @param shouldUseDebugFlags If non-null, returns whether debug flags are allowed to be used.
|
|
*/
|
|
public static void initCommandLine(
|
|
String fileName, @Nullable Supplier<Boolean> shouldUseDebugFlags) {
|
|
if (sFilenameOverrideForTesting != null) {
|
|
fileName = sFilenameOverrideForTesting;
|
|
}
|
|
assert !CommandLine.isInitialized();
|
|
File commandLineFile = new File(COMMAND_LINE_FILE_PATH_DEBUG_APP, fileName);
|
|
// shouldUseDebugCommandLine() uses IPC, so don't bother calling it if no flags file exists.
|
|
boolean debugFlagsExist = commandLineFile.exists();
|
|
if (!debugFlagsExist || !shouldUseDebugCommandLine(shouldUseDebugFlags)) {
|
|
commandLineFile = new File(COMMAND_LINE_FILE_PATH, fileName);
|
|
}
|
|
CommandLine.initFromFile(commandLineFile.getPath());
|
|
}
|
|
|
|
/**
|
|
* Use an alternative path if:
|
|
* - The current build is "eng" or "userdebug", OR
|
|
* - adb is enabled and this is the debug app, OR
|
|
* - Force enabled by the embedder.
|
|
* @param shouldUseDebugFlags If non-null, returns whether debug flags are allowed to be used.
|
|
*/
|
|
private static boolean shouldUseDebugCommandLine(
|
|
@Nullable Supplier<Boolean> shouldUseDebugFlags) {
|
|
if (shouldUseDebugFlags != null && shouldUseDebugFlags.get()) return true;
|
|
Context context = ContextUtils.getApplicationContext();
|
|
// Check isDebugAndroid() last to get full code coverage when using userdebug devices.
|
|
return context.getPackageName().equals(getDebugApp(context)) || BuildInfo.isDebugAndroid();
|
|
}
|
|
|
|
private static String getDebugApp(Context context) {
|
|
boolean adbEnabled =
|
|
Settings.Global.getInt(context.getContentResolver(), Settings.Global.ADB_ENABLED, 0)
|
|
== 1;
|
|
if (adbEnabled) {
|
|
return Settings.Global.getString(
|
|
context.getContentResolver(), Settings.Global.DEBUG_APP);
|
|
}
|
|
return null;
|
|
}
|
|
}
|