OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Provides a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
6 | 6 |
7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
8 """ | 8 """ |
9 # pylint: disable=unused-argument | 9 # pylint: disable=unused-argument |
10 | 10 |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 package: Name of the package. | 372 package: Name of the package. |
373 | 373 |
374 Returns: | 374 Returns: |
375 List of paths to the apks on the device for the given package. | 375 List of paths to the apks on the device for the given package. |
376 """ | 376 """ |
377 return self._GetApplicationPathsInternal(package) | 377 return self._GetApplicationPathsInternal(package) |
378 | 378 |
379 def _GetApplicationPathsInternal(self, package, skip_cache=False): | 379 def _GetApplicationPathsInternal(self, package, skip_cache=False): |
380 cached_result = self._cache['package_apk_paths'].get(package) | 380 cached_result = self._cache['package_apk_paths'].get(package) |
381 if cached_result is not None and not skip_cache: | 381 if cached_result is not None and not skip_cache: |
382 return list(cached_result) | 382 if package in self._cache['package_apk_paths_to_verify']: |
| 383 self._cache['package_apk_paths_to_verify'].remove(package) |
| 384 # Don't verify an app that is not thought to be installed. We are |
| 385 # concerned only with apps we think are installed having been |
| 386 # uninstalled manually. |
| 387 if cached_result and not self.PathExists(cached_result): |
| 388 cached_result = None |
| 389 self._cache['package_apk_checksums'].pop(package, 0) |
| 390 if cached_result is not None: |
| 391 return list(cached_result) |
383 # 'pm path' is liable to incorrectly exit with a nonzero number starting | 392 # 'pm path' is liable to incorrectly exit with a nonzero number starting |
384 # in Lollipop. | 393 # in Lollipop. |
385 # TODO(jbudorick): Check if this is fixed as new Android versions are | 394 # TODO(jbudorick): Check if this is fixed as new Android versions are |
386 # released to put an upper bound on this. | 395 # released to put an upper bound on this. |
387 should_check_return = (self.build_version_sdk < version_codes.LOLLIPOP) | 396 should_check_return = (self.build_version_sdk < version_codes.LOLLIPOP) |
388 output = self.RunShellCommand( | 397 output = self.RunShellCommand( |
389 ['pm', 'path', package], check_return=should_check_return) | 398 ['pm', 'path', package], check_return=should_check_return) |
390 apks = [] | 399 apks = [] |
391 for line in output: | 400 for line in output: |
392 if not line.startswith('package:'): | 401 if not line.startswith('package:'): |
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1942 self._client_caches[client_name] = {} | 1951 self._client_caches[client_name] = {} |
1943 return self._client_caches[client_name] | 1952 return self._client_caches[client_name] |
1944 | 1953 |
1945 def _ClearCache(self): | 1954 def _ClearCache(self): |
1946 """Clears all caches.""" | 1955 """Clears all caches.""" |
1947 for client in self._client_caches: | 1956 for client in self._client_caches: |
1948 self._client_caches[client].clear() | 1957 self._client_caches[client].clear() |
1949 self._cache = { | 1958 self._cache = { |
1950 # Map of packageId -> list of on-device .apk paths | 1959 # Map of packageId -> list of on-device .apk paths |
1951 'package_apk_paths': {}, | 1960 'package_apk_paths': {}, |
| 1961 # Set of packageId that were loaded from LoadCacheData and not yet |
| 1962 # verified. |
| 1963 'package_apk_paths_to_verify': set(), |
1952 # Map of packageId -> set of on-device .apk checksums | 1964 # Map of packageId -> set of on-device .apk checksums |
1953 'package_apk_checksums': {}, | 1965 'package_apk_checksums': {}, |
1954 # Map of property_name -> value | 1966 # Map of property_name -> value |
1955 'getprop': {}, | 1967 'getprop': {}, |
1956 # Map of device_path -> [ignore_other_files, map of path->checksum] | 1968 # Map of device_path -> [ignore_other_files, map of path->checksum] |
1957 'device_path_checksums': {}, | 1969 'device_path_checksums': {}, |
1958 } | 1970 } |
1959 | 1971 |
1960 def LoadCacheData(self, data): | 1972 def LoadCacheData(self, data): |
1961 """Initializes the cache from data created using DumpCacheData.""" | 1973 """Initializes the cache from data created using DumpCacheData.""" |
1962 obj = json.loads(data) | 1974 obj = json.loads(data) |
1963 self._cache['package_apk_paths'] = obj.get('package_apk_paths', {}) | 1975 self._cache['package_apk_paths'] = obj.get('package_apk_paths', {}) |
| 1976 # When using a cache across script invokations, verify that apps have |
| 1977 # not been uninstalled. |
| 1978 self._cache['package_apk_paths_to_verify'] = set( |
| 1979 self._cache['package_apk_paths'].iterkeys()) |
| 1980 |
1964 package_apk_checksums = obj.get('package_apk_checksums', {}) | 1981 package_apk_checksums = obj.get('package_apk_checksums', {}) |
1965 for k, v in package_apk_checksums.iteritems(): | 1982 for k, v in package_apk_checksums.iteritems(): |
1966 package_apk_checksums[k] = set(v) | 1983 package_apk_checksums[k] = set(v) |
1967 self._cache['package_apk_checksums'] = package_apk_checksums | 1984 self._cache['package_apk_checksums'] = package_apk_checksums |
1968 device_path_checksums = obj.get('device_path_checksums', {}) | 1985 device_path_checksums = obj.get('device_path_checksums', {}) |
1969 self._cache['device_path_checksums'] = device_path_checksums | 1986 self._cache['device_path_checksums'] = device_path_checksums |
1970 | 1987 |
1971 def DumpCacheData(self): | 1988 def DumpCacheData(self): |
1972 """Dumps the current cache state to a string.""" | 1989 """Dumps the current cache state to a string.""" |
1973 obj = {} | 1990 obj = {} |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2039 if ('android.permission.WRITE_EXTERNAL_STORAGE' in permissions | 2056 if ('android.permission.WRITE_EXTERNAL_STORAGE' in permissions |
2040 and 'android.permission.READ_EXTERNAL_STORAGE' not in permissions): | 2057 and 'android.permission.READ_EXTERNAL_STORAGE' not in permissions): |
2041 permissions.append('android.permission.READ_EXTERNAL_STORAGE') | 2058 permissions.append('android.permission.READ_EXTERNAL_STORAGE') |
2042 cmd = ';'.join('pm grant %s %s' %(package, p) for p in permissions) | 2059 cmd = ';'.join('pm grant %s %s' %(package, p) for p in permissions) |
2043 if cmd: | 2060 if cmd: |
2044 output = self.RunShellCommand(cmd) | 2061 output = self.RunShellCommand(cmd) |
2045 if output: | 2062 if output: |
2046 logging.warning('Possible problem when granting permissions. Blacklist ' | 2063 logging.warning('Possible problem when granting permissions. Blacklist ' |
2047 'may need to be updated.') | 2064 'may need to be updated.') |
2048 logging.warning(output) | 2065 logging.warning(output) |
OLD | NEW |