blob: 6d38ee504875c57a9e3ddc3d8adfd32cf2e8cb70 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2016 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from acts.controllers.android_device import AndroidDevice
from acts.controllers.utils_lib import host_utils
import acts.controllers.native as native
from subprocess import call
import logging
import time
#TODO(tturney): Merge this into android device
MOBLY_CONTROLLER_CONFIG_NAME = "NativeAndroidDevice"
ACTS_CONTROLLER_REFERENCE_NAME = "native_android_devices"
def create(configs):
logger = logging
ads = get_instances(configs)
for ad in ads:
try:
ad.get_droid()
except:
logger.exception("Failed to start sl4n on %s" % ad.serial)
return ads
def destroy(ads):
pass
def get_instances(serials, ):
"""Create AndroidDevice instances from a list of serials.
Args:
serials: A list of android device serials.
logger: A logger to be passed to each instance.
Returns:
A list of AndroidDevice objects.
"""
results = []
for s in serials:
results.append(NativeAndroidDevice(s))
return results
class NativeAndroidDeviceError(Exception):
pass
class NativeAndroidDevice(AndroidDevice):
def __del__(self):
if self.h_port:
self.adb.forward("--remove tcp:%d" % self.h_port)
def get_droid(self, handle_event=True):
"""Create an sl4n connection to the device.
Return the connection handler 'droid'. By default, another connection
on the same session is made for EventDispatcher, and the dispatcher is
returned to the caller as well.
If sl4n server is not started on the device, try to start it.
Args:
handle_event: True if this droid session will need to handle
events.
Returns:
droid: Android object useds to communicate with sl4n on the android
device.
ed: An optional EventDispatcher to organize events for this droid.
Examples:
Don't need event handling:
>>> ad = NativeAndroidDevice()
>>> droid = ad.get_droid(False)
Need event handling:
>>> ad = NativeAndroidDevice()
>>> droid, ed = ad.get_droid()
"""
if not self.h_port or not host_utils.is_port_available(self.h_port):
self.h_port = host_utils.get_available_host_port()
self.adb.tcp_forward(self.h_port, self.d_port)
pid = self.adb.shell("pidof -s sl4n", ignore_status=True)
while (pid):
self.adb.shell("kill {}".format(pid))
pid = self.adb.shell("pidof -s sl4n", ignore_status=True)
call(
["adb -s " + self.serial + " shell sh -c \"/system/bin/sl4n\" &"],
shell=True)
try:
time.sleep(3)
droid = self.start_new_session()
except:
droid = self.start_new_session()
return droid
def start_new_session(self):
"""Start a new session in sl4n.
Also caches the droid in a dict with its uid being the key.
Returns:
An Android object used to communicate with sl4n on the android
device.
Raises:
sl4nException: Something is wrong with sl4n and it returned an
existing uid to a new session.
"""
droid = native.NativeAndroid(port=self.h_port)
droid.open()
if droid.uid in self._droid_sessions:
raise bt.SL4NException(("SL4N returned an existing uid for a "
"new session. Abort."))
return droid
self._droid_sessions[droid.uid] = [droid]
return droid