Skip to content

Commit

Permalink
reproduction of envs and events
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanchun-li committed Jul 7, 2015
1 parent ca1326b commit 36978bc
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 24 deletions.
65 changes: 55 additions & 10 deletions droidbot/app_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ class ContactAppEnv(StaticAppEnv):
"""
This class describes a contact inside device
"""
def __init__(self, name='Lynn', phone="1234567890", email="droidbot@honeynet.com"):
def __init__(self, name='Lynn', phone="1234567890", email="droidbot@honeynet.com", env_dict=None):
if env_dict is not None:
self.__dict__ = env_dict
return
self.name = name
self.phone = phone
self.email = email
Expand All @@ -86,7 +89,10 @@ class SettingsAppEnv(StaticAppEnv):
"""
This class describes settings of device
"""
def __init__(self, table_name="system", name="screen_brightness", value="50"):
def __init__(self, table_name="system", name="screen_brightness", value="50", env_dict=None):
if env_dict is not None:
self.__dict__ = env_dict
return
self.table_name = table_name
self.name = name
self.value = value
Expand All @@ -100,13 +106,16 @@ class CallLogEnv(StaticAppEnv):
"""
call log
"""
def __init__(self, phone="1234567890", call_in=True, accepted=True):
def __init__(self, phone="1234567890", call_in=True, accepted=True, env_dict=None):
"""
a call log
:param phone: str, phone number of contact
:param call_in: bool, True for call in, False for call out
:param accepted: whether the call is accepted
"""
if env_dict is not None:
self.__dict__ = env_dict
return
self.phone = phone
self.call_in = call_in
self.accepted = accepted
Expand Down Expand Up @@ -143,13 +152,17 @@ class SMSLogEnv(StaticAppEnv):
"""
SMS log
"""
def __init__(self, phone="1234567890", sms_in=True, content="Hello world"):
def __init__(self, phone="1234567890", sms_in=True, content="Hello world", env_dict=None):
"""
a call log
:param phone: str, phone number of contact
:param sms_in: bool, True for income message, False for outcome
:param content: content of message
"""
if env_dict is not None:
self.__dict__ = env_dict
return

self.phone = phone
self.sms_in = sms_in
self.content = content
Expand All @@ -166,7 +179,10 @@ class GPSAppEnv(DynamicAppEnv):
"""
This class describes the continuous updating GPS data inside device
"""
def __init__(self, center_x=50, center_y=50, delta_x=1, delta_y=1):
def __init__(self, center_x=50, center_y=50, delta_x=1, delta_y=1, env_dict=None):
if env_dict is not None:
self.__dict__ = env_dict
return
self.center_x = center_x
self.center_y = center_y
self.delta_x = delta_x
Expand All @@ -177,6 +193,15 @@ def deploy(self, device):
device.set_continuous_gps(self.center_x, self.center_y, self.delta_x, self.delta_y)


ENV_TYPES = {
'contact': ContactAppEnv,
'settings': SettingsAppEnv,
'calllog': CallLogEnv,
'smslog': SMSLogEnv,
'gps': GPSAppEnv
}


class AppEnvManager(object):
"""
AppEnvManager manages the environment of device in which an app will run.
Expand Down Expand Up @@ -237,7 +262,12 @@ def dump(self, file):
:param file: the file path to output the environment
:return:
"""
# TODO implement this method
f = open(file, 'w')
env_array = []
for env in self.envs:
env_array.append(env.to_dict())
env_json = json.dumps(env_array)
f.write(env_json)

def generateFromFactory(self, app_env_factory):
"""
Expand Down Expand Up @@ -317,13 +347,28 @@ def __init__(self, file):
create a FileEnvFactory from a json file
:param file path string
"""
envs = []
self.envs = []
self.file = file
f = open(file, 'r')
env_json = f.readall()
env_array = json.loads(env_json)
for env_dict in env_array:
if not isinstance(env_dict, dict):
raise UnknownEnvException
if not env_dict.has_key('env_type'):
raise UnknownEnvException
env_type = env_dict['env_type']
if not ENV_TYPES.has_key('env_type'):
raise UnknownEnvException
EnvType = ENV_TYPES[env_type]
env = EnvType(dict=env_dict)
self.envs.append(env)
self.index = 0

def produce_envs(self):
"""
generate envs from file
"""
# TODO generate envs from file
envs = []
return envs
env = self.envs[self.index]
self.index += 1
return env
116 changes: 102 additions & 14 deletions droidbot/app_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ class KeyEvent(AppEvent):
"""
a key pressing event
"""
def __init__(self, name):
def __init__(self, name, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
self.event_type = 'key'
self.name = name

Expand Down Expand Up @@ -218,7 +221,10 @@ class TouchEvent(UIEvent):
"""
a touch on screen
"""
def __init__(self, x, y):
def __init__(self, x, y, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
self.event_type = 'touch'
self.x = x
self.y = y
Expand All @@ -238,7 +244,10 @@ class LongTouchEvent(UIEvent):
"""
a long touch on screen
"""
def __init__(self, x, y, duration=2000):
def __init__(self, x, y, duration=2000, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
self.event_type = 'long_touch'
self.x = x
self.y = y
Expand All @@ -259,7 +268,10 @@ class DragEvent(UIEvent):
"""
a drag gesture on screen
"""
def __init__(self, start_x, start_y, end_x, end_y, duration=1000):
def __init__(self, start_x, start_y, end_x, end_y, duration=1000, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
self.event_type = 'drag'
self.start_x = start_x
self.start_y = start_y
Expand All @@ -286,7 +298,10 @@ class TypeEvent(UIEvent):
"""
type some word
"""
def __init__(self, text):
def __init__(self, text, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
self.event_type = 'type'
self.text = text

Expand All @@ -301,7 +316,10 @@ class IntentEvent(AppEvent):
"""
An event describing an intent
"""
def __init__(self, intent):
def __init__(self, intent, event_dict=None):
if event_dict is not None:
self.__dict__ = event_dict
return
assert isinstance(intent, Intent)
self.type = 'intent'
self.intent = intent.get_cmd()
Expand All @@ -321,11 +339,15 @@ class EmulatorEvent(AppEvent):
"""
build-in emulator event, including incoming call and incoming SMS
"""
def __init__(self, event_name, event_data={}):
def __init__(self, event_name, event_data={}, event_dict=None):
"""
:param event_name: name of event
:param event_data: data of event
"""
if event_dict is not None:
self.__dict__ = event_dict
return
self.type = 'emulator'
self.event_name = event_name
self.event_data = event_data

Expand Down Expand Up @@ -368,12 +390,30 @@ class ContextEvent(AppEvent):
An extended event, which knows the device context in which it is performing
This is reproducable
"""
def __init__(self, context, event):
def __init__(self, context, event, event_dict=None):
"""
construct an event which knows its context
:param context: the context where the event happens
:param event: the event to perform
"""
if event_dict is not None:
assert event_dict.has_key('type')
assert event_dict.has_key('context')
assert event_dict.has_key('event')
assert event_dict['type'] == 'context'
self.type = event_dict['type']

context_dict = event_dict['context']
context_type = context_dict['type']
ContextType = CONTEXT_TYPES[context_type]
self.context = ContextType(context_dict=context_dict)

sub_event_dict = event_dict['event']
sub_event_type = sub_event_dict['type']
SubEventType = EVENT_TYPES[sub_event_type]
self.event = SubEventType(dict=sub_event_dict)
return

assert isinstance(event, AppEvent)
self.type = 'context'
self.context = context
Expand All @@ -389,7 +429,7 @@ def send(self, device):
self.event.send(device)

def to_dict(self):
return {'context' : self.context.__dict__, 'event' : self.event.__dict__}
return {'type': self.type, 'context': self.context.__dict__, 'event': self.event.__dict__}


class Context(object):
Expand All @@ -407,7 +447,11 @@ class ActivityNameContext(Context):
"""
use activity name as context
"""
def __init__(self, activity_name):
def __init__(self, activity_name, context_dict=None):
if context_dict is not None:
self.__dict__ = context_dict
return
self.type = 'activity'
self.activity_name = activity_name

def __eq__(self, other):
Expand All @@ -423,9 +467,13 @@ def assert_in_device(self, device):

class WindowNameContext(Context):
"""
use activity name and window name as context
use window name as context
"""
def __init__(self, window_name):
def __init__(self, window_name, context_dict=None):
if context_dict is not None:
self.__dict__ = context_dict
return
self.type = 'window'
self.window_name = window_name

def __eq__(self, other):
Expand All @@ -439,6 +487,12 @@ def assert_in_device(self, device):
return self.window_name == current_focused_window


CONTEXT_TYPES = {
'activity': ActivityNameContext,
'window': WindowNameContext
}


class UniqueView(object):
"""
use view unique id and its text to identify a view
Expand Down Expand Up @@ -509,7 +563,12 @@ def dump(self, file):
:param file: the file path to output the events
:return:
"""
# TODO implement this method
f = open(file, 'w')
event_array = []
for event in self.events:
event_array.append(event.to_dict())
event_json = json.dumps(event_array)
f.write(event_json)

def on_state_update(self, old_state, new_state):
"""
Expand Down Expand Up @@ -775,6 +834,17 @@ def find_events(self):
return event


EVENT_TYPES = {
'key': KeyEvent,
'touch': TouchEvent,
'long_touch': LongTouchEvent,
'drag': DragEvent,
'type': TypeEvent,
'emulator': EmulatorEvent,
'context': ContextEvent
}


class FileEventFactory(EventFactory):
"""
factory which produces events from file
Expand All @@ -785,10 +855,28 @@ def __init__(self, device, app, file):
:param file path string
"""
super(FileEventFactory, self).__init__(device, app)
self.events = []
self.file = file
f = open(file, 'r')
events_json = f.readall()
events_array = json.loads(events_json)
for event_dict in events_array:
if not isinstance(event_dict, dict):
raise UnknownEventException
if not event_dict.has_key('event_type'):
raise UnknownEventException
event_type = event_dict['event_type']
if not EVENT_TYPES.has_key('event_type'):
raise UnknownEventException
EventType = EVENT_TYPES[event_type]
event = EventType(dict=event_dict)
self.events.append(event)
self.index = 0

def generate_event(self):
"""
generate a event
"""
pass
event = self.events[self.index]
self.index += 1
return event

0 comments on commit 36978bc

Please sign in to comment.