| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 # Copyright (c) 2012 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 import traceback |  | 
| 6 import warnings |  | 
| 7 |  | 
| 8 |  | 
| 9 # Location where chrome reads command line flags from |  | 
| 10 CHROME_COMMAND_FILE = '/data/local/tmp/chrome-command-line' |  | 
| 11 |  | 
| 12 class FlagChanger(object): |  | 
| 13   """Changes the flags Chrome runs with. |  | 
| 14 |  | 
| 15   There are two different use cases for this file: |  | 
| 16   * Flags are permanently set by calling Set(). |  | 
| 17   * Flags can be temporarily set for a particular set of unit tests.  These |  | 
| 18     tests should call Restore() to revert the flags to their original state |  | 
| 19     once the tests have completed. |  | 
| 20   """ |  | 
| 21 |  | 
| 22   def __init__(self, android_cmd): |  | 
| 23     self._android_cmd = android_cmd |  | 
| 24 |  | 
| 25     # Save the original flags. |  | 
| 26     self._orig_line = self._android_cmd.GetFileContents(CHROME_COMMAND_FILE) |  | 
| 27     if self._orig_line: |  | 
| 28       self._orig_line = self._orig_line[0].strip() |  | 
| 29 |  | 
| 30     # Parse out the flags into a list to facilitate adding and removing flags. |  | 
| 31     self._current_flags = self._TokenizeFlags(self._orig_line) |  | 
| 32 |  | 
| 33   def Get(self): |  | 
| 34     """Returns list of current flags.""" |  | 
| 35     return self._current_flags |  | 
| 36 |  | 
| 37   def Set(self, flags): |  | 
| 38     """Replaces all flags on the current command line with the flags given. |  | 
| 39 |  | 
| 40     Args: |  | 
| 41       flags: A list of flags to set, eg. ['--single-process']. |  | 
| 42     """ |  | 
| 43     if flags: |  | 
| 44       assert flags[0] != 'chrome' |  | 
| 45 |  | 
| 46     self._current_flags = flags |  | 
| 47     self._UpdateCommandLineFile() |  | 
| 48 |  | 
| 49   def AddFlags(self, flags): |  | 
| 50     """Appends flags to the command line if they aren't already there. |  | 
| 51 |  | 
| 52     Args: |  | 
| 53       flags: A list of flags to add on, eg. ['--single-process']. |  | 
| 54     """ |  | 
| 55     if flags: |  | 
| 56       assert flags[0] != 'chrome' |  | 
| 57 |  | 
| 58     # Avoid appending flags that are already present. |  | 
| 59     for flag in flags: |  | 
| 60       if flag not in self._current_flags: |  | 
| 61         self._current_flags.append(flag) |  | 
| 62     self._UpdateCommandLineFile() |  | 
| 63 |  | 
| 64   def RemoveFlags(self, flags): |  | 
| 65     """Removes flags from the command line, if they exist. |  | 
| 66 |  | 
| 67     Args: |  | 
| 68       flags: A list of flags to remove, eg. ['--single-process'].  Note that we |  | 
| 69              expect a complete match when removing flags; if you want to remove |  | 
| 70              a switch with a value, you must use the exact string used to add |  | 
| 71              it in the first place. |  | 
| 72     """ |  | 
| 73     if flags: |  | 
| 74       assert flags[0] != 'chrome' |  | 
| 75 |  | 
| 76     for flag in flags: |  | 
| 77       if flag in self._current_flags: |  | 
| 78         self._current_flags.remove(flag) |  | 
| 79     self._UpdateCommandLineFile() |  | 
| 80 |  | 
| 81   def Restore(self): |  | 
| 82     """Restores the flags to their original state.""" |  | 
| 83     self._current_flags = self._TokenizeFlags(self._orig_line) |  | 
| 84     self._UpdateCommandLineFile() |  | 
| 85 |  | 
| 86   def _UpdateCommandLineFile(self): |  | 
| 87     """Writes out the command line to the file, or removes it if empty.""" |  | 
| 88     print "Current flags: ", self._current_flags |  | 
| 89 |  | 
| 90     if self._current_flags: |  | 
| 91       self._android_cmd.SetFileContents(CHROME_COMMAND_FILE, |  | 
| 92                                         'chrome ' + |  | 
| 93                                         ' '.join(self._current_flags)) |  | 
| 94     else: |  | 
| 95       self._android_cmd.RunShellCommand('rm ' + CHROME_COMMAND_FILE) |  | 
| 96 |  | 
| 97   def _TokenizeFlags(self, line): |  | 
| 98     """Changes the string containing the command line into a list of flags. |  | 
| 99 |  | 
| 100     Follows similar logic to CommandLine.java::tokenizeQuotedArguments: |  | 
| 101     * Flags are split using whitespace, unless the whitespace is within a |  | 
| 102       pair of quotation marks. |  | 
| 103     * Unlike the Java version, we keep the quotation marks around switch |  | 
| 104       values since we need them to re-create the file when new flags are |  | 
| 105       appended. |  | 
| 106 |  | 
| 107     Args: |  | 
| 108       line: A string containing the entire command line.  The first token is |  | 
| 109             assumed to be the program name. |  | 
| 110     """ |  | 
| 111     if not line: |  | 
| 112       return [] |  | 
| 113 |  | 
| 114     tokenized_flags = [] |  | 
| 115     current_flag = "" |  | 
| 116     within_quotations = False |  | 
| 117 |  | 
| 118     # Move through the string character by character and build up each flag |  | 
| 119     # along the way. |  | 
| 120     for c in line.strip(): |  | 
| 121       if c is '"': |  | 
| 122         if len(current_flag) > 0 and current_flag[-1] == '\\': |  | 
| 123           # Last char was a backslash; pop it, and treat this " as a literal. |  | 
| 124           current_flag = current_flag[0:-1] + '"' |  | 
| 125         else: |  | 
| 126           within_quotations = not within_quotations |  | 
| 127           current_flag += c |  | 
| 128       elif not within_quotations and (c is ' ' or c is '\t'): |  | 
| 129         if current_flag is not "": |  | 
| 130           tokenized_flags.append(current_flag) |  | 
| 131           current_flag = "" |  | 
| 132       else: |  | 
| 133         current_flag += c |  | 
| 134 |  | 
| 135     # Tack on the last flag. |  | 
| 136     if not current_flag: |  | 
| 137       if within_quotations: |  | 
| 138         warnings.warn("Unterminated quoted string: " + current_flag) |  | 
| 139     else: |  | 
| 140       tokenized_flags.append(current_flag) |  | 
| 141 |  | 
| 142     # Return everything but the program name. |  | 
| 143     return tokenized_flags[1:] |  | 
| OLD | NEW | 
|---|