Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: build/android/pylib/android_commands.py

Issue 276813002: Make it harder to leak temp files on devices (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | build/android/pylib/android_commands_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/android_commands.py
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index 0a710f9e0ef2cc237996c360940df8265a927f01..37e8f4e6959e47c9bef63d315958cfe42c26a157 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -14,6 +14,7 @@ import inspect
import json
import logging
import os
+import random
import re
import shlex
import signal
@@ -82,6 +83,35 @@ CONTROL_USB_CHARGING_COMMANDS = [
},
]
+class DeviceTempFile(object):
+ def __init__(self, android_commands, prefix="temp_file", suffix=""):
jbudorick 2014/05/09 15:57:03 nit: single quotes
cjhopman 2014/05/09 18:55:14 Done.
+ """Find an unused temporary file path in the devices external directory.
+
+ When this object is closed, the file will be deleted on the device.
+ """
+ self.android_commands = android_commands
+ while True:
+ # TODO(cjhopman): This could actually return the same file in multiple
+ # calls if the caller doesn't write to the files immediately.
+ i = random.randint(0, 1000000)
+ self.name = '%s/%s-%010d%s' % (
+ android_commands.GetExternalStorage(), prefix, i, suffix)
+ if not android_commands.FileExistsOnDevice(self.name):
+ break
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+ def Name(self):
jbudorick 2014/05/09 15:57:03 nit: unused?
cjhopman 2014/05/09 18:55:14 Done.
+ return self.name
+
+ def close(self):
+ self.android_commands.RunShellCommand('rm ' + self.name)
+
+
def GetAVDs():
"""Returns a list of AVDs."""
re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE)
@@ -1093,16 +1123,6 @@ class AndroidCommands(object):
f.flush()
self._adb.Push(f.name, filename)
- _TEMP_FILE_BASE_FMT = 'temp_file_%d'
- _TEMP_SCRIPT_FILE_BASE_FMT = 'temp_script_file_%d.sh'
-
- def _GetDeviceTempFileName(self, base_name):
- i = 0
- while self.FileExistsOnDevice(
- self.GetExternalStorage() + '/' + base_name % i):
- i += 1
- return self.GetExternalStorage() + '/' + base_name % i
-
def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)
@@ -1160,25 +1180,22 @@ class AndroidCommands(object):
This is less efficient than SetFileContents.
"""
- temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
- temp_script = self._GetDeviceTempFileName(
- AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
-
- # Put the contents in a temporary file
- self.SetFileContents(temp_file, contents)
- # Create a script to copy the file contents to its final destination
- self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
-
- command = 'sh %s' % temp_script
- command_runner = self._GetProtectedFileCommandRunner()
- if command_runner:
- return command_runner(command)
- else:
- logging.warning('Could not set contents of protected file: %s' % filename)
+ with DeviceTempFile(self) as temp_file:
craigdh 2014/05/09 16:02:40 I don't think we need to support pre-2.7 Python, s
cjhopman 2014/05/09 18:55:14 Done.
cjhopman 2014/05/16 01:15:19 Undone. So, making this one with statement means t
+ with DeviceTempFile(self, suffix=".sh") as temp_script:
+ # Put the contents in a temporary file
+ self.SetFileContents(temp_file.name, contents)
+ # Create a script to copy the file contents to its final destination
+ self.SetFileContents(temp_script.name,
+ 'cat %s > %s' % (temp_file.name, filename))
+
+ command = 'sh %s' % temp_script.name
+ command_runner = self._GetProtectedFileCommandRunner()
+ if command_runner:
+ return command_runner(command)
+ else:
+ logging.warning(
+ 'Could not set contents of protected file: %s' % filename)
- # And remove the temporary files
- self.RunShellCommand('rm ' + temp_file)
- self.RunShellCommand('rm ' + temp_script)
def RemovePushedFiles(self):
"""Removes all files pushed with PushIfNeeded() from the device."""
@@ -1884,24 +1901,23 @@ class AndroidCommands(object):
dest: absolute path of destination directory
"""
logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest)
- temp_script_file = self._GetDeviceTempFileName(
- AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
- host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
- 'build',
- 'android',
- 'pylib',
- 'efficient_android_directory_copy.sh')
- self._adb.Push(host_script_path, temp_script_file)
- self.EnableAdbRoot
- out = self.RunShellCommand('sh %s %s %s' % (temp_script_file, source, dest),
- timeout_time=120)
- if self._device:
- device_repr = self._device[-4:]
- else:
- device_repr = '????'
- for line in out:
- logging.info('[%s]> %s', device_repr, line)
- self.RunShellCommand('rm %s' % temp_script_file)
+ with DeviceTempFile(self, suffix=".sh") as temp_script_file:
+ host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
+ 'build',
+ 'android',
+ 'pylib',
+ 'efficient_android_directory_copy.sh')
+ self._adb.Push(host_script_path, temp_script_file.name)
+ self.EnableAdbRoot
+ out = self.RunShellCommand(
+ 'sh %s %s %s' % (temp_script_file.name, source, dest),
+ timeout_time=120)
+ if self._device:
+ device_repr = self._device[-4:]
+ else:
+ device_repr = '????'
+ for line in out:
+ logging.info('[%s]> %s', device_repr, line)
def _GetControlUsbChargingCommand(self):
if self._control_usb_charging_command['cached']:
« no previous file with comments | « no previous file | build/android/pylib/android_commands_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698