146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.core.backends.chrome import crx_id
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ExtensionPathNonExistentException(Exception):
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pass
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MissingPublicKeyException(Exception):
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pass
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ExtensionToLoad(object):
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  def __init__(self, path, browser_type, is_component=False):
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if not os.path.isdir(path):
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      raise ExtensionPathNonExistentException(
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          'Extension path not a directory %s' % path)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._path = path
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._local_path = path
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._is_component = is_component
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if is_component and not crx_id.HasPublicKey(path):
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      raise MissingPublicKeyException(
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         'Component extension %s must have a public key' % path)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    # It is possible that we are running telemetry on Windows targeting
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    # a remote CrOS or Android device. In this case, we need the
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    # browser_type argument to determine how we should encode
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    # the extension path.
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    self._is_win = (os.name == 'nt'
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        and not (browser_type.startswith('android')
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 or browser_type.startswith('cros')))
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @property
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def extension_id(self):
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Unique extension id of this extension."""
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if crx_id.HasPublicKey(self._path):
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Calculate extension id from the public key.
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return crx_id.GetCRXAppID(os.path.realpath(self._path))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else:
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Calculate extension id based on the path on the device.
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return crx_id.GetCRXAppID(
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          os.path.realpath(self._local_path),
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          from_file_path=True,
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          is_win_path=self._is_win)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @property
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def path(self):
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Path to extension source directory."""
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return self._path
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @property
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def local_path(self):
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Path to extension destination directory, for remote instances of
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome"""
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return self._local_path
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @local_path.setter
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def local_path(self, local_path):
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._local_path = local_path
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @property
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def is_component(self):
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    """Whether this extension should be loaded as a component extension."""
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return self._is_component
67