• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base;
6 
7 import android.annotation.SuppressLint;
8 import android.content.Context;
9 import android.os.Build;
10 import android.provider.Settings;
11 
12 import org.chromium.base.annotations.SuppressFBWarnings;
13 
14 import java.io.File;
15 
16 /**
17  * Provides implementation of command line initialization for Android.
18  */
19 public final class CommandLineInitUtil {
20 
21     private static final String TAG = "CommandLineInitUtil";
22 
23     /**
24      * The location of the command line file needs to be in a protected
25      * directory so requires root access to be tweaked, i.e., no other app in a
26      * regular (non-rooted) device can change this file's contents.
27      * See below for debugging on a regular (non-rooted) device.
28      */
29     private static final String COMMAND_LINE_FILE_PATH = "/data/local";
30 
31     /**
32      * This path (writable by the shell in regular non-rooted "user" builds) is used when:
33      * 1) The "debug app" is set to the application calling this.
34      * and
35      * 2) ADB is enabled.
36      *
37      */
38     private static final String COMMAND_LINE_FILE_PATH_DEBUG_APP = "/data/local/tmp";
39 
CommandLineInitUtil()40     private CommandLineInitUtil() {
41     }
42 
43     /**
44      * Initializes the CommandLine class, pulling command line arguments from {@code fileName}.
45      * @param context  The {@link Context} to use to query whether or not this application is being
46      *                 debugged, and whether or not the publicly writable command line file should
47      *                 be used.
48      * @param fileName The name of the command line file to pull arguments from.
49      */
50     @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
initCommandLine(Context context, String fileName)51     public static void initCommandLine(Context context, String fileName) {
52         if (!CommandLine.isInitialized()) {
53             File commandLineFile = getAlternativeCommandLinePath(context, fileName);
54             if (commandLineFile == null) {
55                 commandLineFile = new File(COMMAND_LINE_FILE_PATH, fileName);
56             }
57             CommandLine.initFromFile(commandLineFile.getPath());
58         }
59     }
60 
61     /**
62      * Use an alternative path if adb is enabled and this is the debug app.
63      */
64     @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
getAlternativeCommandLinePath(Context context, String fileName)65     private static File getAlternativeCommandLinePath(Context context, String fileName) {
66         File alternativeCommandLineFile =
67                 new File(COMMAND_LINE_FILE_PATH_DEBUG_APP, fileName);
68         if (!alternativeCommandLineFile.exists()) return null;
69         try {
70             String debugApp = Build.VERSION.SDK_INT < 17
71                     ? getDebugAppPreJBMR1(context) : getDebugAppJBMR1(context);
72 
73             if (debugApp != null
74                     && debugApp.equals(context.getApplicationContext().getPackageName())) {
75                 Log.i(TAG, "Using alternative command line file in "
76                         + alternativeCommandLineFile.getPath());
77                 return alternativeCommandLineFile;
78             }
79         } catch (RuntimeException e) {
80             Log.e(TAG, "Unable to detect alternative command line file");
81         }
82 
83         return null;
84     }
85 
86     @SuppressLint("NewApi")
87     private static String getDebugAppJBMR1(Context context) {
88         boolean adbEnabled = Settings.Global.getInt(context.getContentResolver(),
89                 Settings.Global.ADB_ENABLED, 0) == 1;
90         if (adbEnabled) {
91             return Settings.Global.getString(context.getContentResolver(),
92                     Settings.Global.DEBUG_APP);
93         }
94         return null;
95     }
96 
97     @SuppressWarnings("deprecation")
98     private static String getDebugAppPreJBMR1(Context context) {
99         boolean adbEnabled = Settings.System.getInt(context.getContentResolver(),
100                 Settings.System.ADB_ENABLED, 0) == 1;
101         if (adbEnabled) {
102             return Settings.System.getString(context.getContentResolver(),
103                     Settings.System.DEBUG_APP);
104         }
105         return null;
106     }
107 }
108