Diseño de una herramienta para la optimización de batería en teléfonos inteligentes
73
0
0
Texto completo
(2) Documento maquetado con TEXiS v.1.0+.. Este documento está preparado para ser impreso a doble cara..
(3) Trabajo Fin de Grado Título:. Diseño de una herramienta para la optimización de batería en teléfonos inteligentes. Autor:. José María del Pozo Alonso. Tutor:. Alvaro Araujo Pinto. Departamento:. Departamento de Ingeniería Electrónica. Miembros del tribunal Presidente:. D. OCTAVIO NIETO-TALADRIZ GARCÍA. Vocal:. D. ANDRÉS RODRÍGUEZ DOMÍNGUEZ. Secretario:. D. CARLOS ÁNGEL IGLESIAS FERNÁNDEZ. Suplente:. D. RUBÉN SAN SEGUNDO HERNÁNDEZ. CALIFICACIÓN:. Madrid, a. de. de.
(4)
(5) Diseño de una herramienta para la optimización de batería en teléfonos inteligentes AUTOR: José María del Pozo Alonso TUTOR: Alvaro Araujo Pinto. Departamento de Ingeniería Electrónica Escuela Técnica Superior de Ingenieros de Telecomunicación Universidad Politécnica de Madrid Julio 2016.
(6)
(7) Este proyecto está financiado por la empresa Mundo Reader S.L., propietaria de la marca comercial BQ, a través de la Cátedra BQ..
(8)
(9) A mis padres, a mi hermana, y a Cristina..
(10)
(11) Agradecimientos Tras cuatro años, el final de esta carrera no puede entenderse sin los agradecimientos necesarios a todas esas personas que ayudaron de alguna u otra forma a poder finalizar este proyecto. Gracias a Octavio, porque conocerle supuso un cambio en mi manera de enfrentarme a los retos que esta carrera nos propone día tras día. Gracias a Silvia, Álvaro y Ramiro por confíar en mí para la beca que ha dado lugar a este trabajo. Su apoyo, conocimiento, atención y trabajo han hecho todo un poco más fácil. Gracias a mis compañeros de la Cátedra BQ, dónde he encontrado unos buenos amigos y me lo he pasado genial trabajando estos nueve meses. Gracias a todos mis amigos, a los de siempre. A todos aquellos que han aguantado el “no puedo ir”, el “esta semana tampoco puedo quedar”, y aún así cuando quedamos parece que no ha pasado apenas tiempo. Gracias a mis compañeros de MILTEN FITNESS por ir partido a partido, asignatura a asignatura, curso a curso, y ya estamos ante el final de este gran proyecto que empezamos hace ya cuatro años. Gracias a Cristina, por todos estos años apoyándome en mis decisiones y compartiendo conmigo momentos únicos. Eres la mejor compañera para afrontar todos los retos que se proponen día a día. Gracias a mis abuelos, por todos los valores que nos han inculcado. Su cara de orgullo al hablar con ellos es impagable. Gracias a mis tíos, Jesús y Antonio por enseñarme muchas cosas que no se encuentran en un libro. Por su ayuda cuando la he necesitado, por mantener su mano tendida ante todo siempre, muchas gracias. Por último, y lo más importante. Gracias a mis padres y mi hermana. Gracias a mis padres porque son los que han hecho posible todo esto, y sus ganas muchas veces superan las mías propias. Gracias a mi padre, por su constancia, trabajo y valentía. Gracias a mi madre, por su amor, su espíritu de ser siempre mejor y su esfuerzo.. xi.
(12)
(13) Resumen La duración de la batería para los smartphones cada vez es más crítica. El aumento de las especificaciones de sus componentes hardware conlleva un aumento del consumo medio. Este aumento de la capacidad del hardware se puede ver en mayor memoria RAM, mayor pantalla ó mayor capacidad de las CPU. A pesar de este aumento de consumo, la batería debe mantener un tiempo de descarga razonablemente largo. El objetivo de este TFG es diseñar una herramienta que permita fiarnos del consumo calculado por el terminal móvil. Para ello se estudiará el framework de Android y su cálculo del consumo. A partir de las conclusiones de dicho estudio se propondrán soluciones que permitan que el cálculo del consumo se realice de una manera más correcta. Para el desarrollo de la herramienta es necesario el estudio de los componentes que más consumen en los teléfonos, y así poder alertar cuando su consumo se haya disparado o su comportamiento no sea el correcto. Se estudiarán las distintas plataformas y lenguajes en las que se puede desarrollar, y se eligirá la mejor opción siguiendo las condiciones exigidas por el cliente. Se establecerán umbrales para cada uno de los componentes, y se alertará si el consumo ha superado dicho umbral. PALABRAS CLAVE : Android, batería, consumo, smartphone, Java. xiii.
(14)
(15) Abstract Smartphones battery life is becoming more critical every day. The features of the hardware components are increasing, causing also an increase in the average battery consumption. This increase in hardware resources could be seen as a greater RAM memory, larger screen or higher CPU speed. Despite this consumption increase, the battery must maintain a reasonably large drain time. The aim of this TFG is to design a tool to optimize the consumption calculated by the mobile terminal. In order to accomplish this, the Android framework and its consumption calculation will be studied. From the results of this study, some solutions will be proposed in order to provide a better calculation of the battery consumption. The components with the biggest battery consumption will be studied for the development of the tool, to be able to alert when a consumption peak is detected or when they are not working as expected. Programming platforms and languages will be compared to choose the best option following the customer requirements. Some thresholds for each of the components will be established and an alert will be created if their consumption has exceeded those thresholds. KEY WORDS : Android, battery, consumption, smartphone, Java. xv.
(16)
(17) Índice Agradecimientos. xi. Resumen. xiii. Abstract. xv. 1. Introducción 1.1. Marco del trabajo . . . . . . 1.2. Motivación . . . . . . . . . . 1.3. Definición del problema . . . 1.4. Objetivos . . . . . . . . . . 1.5. Organización del documento. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. 1 1 1 2 2 3. 2. Fundamentos 2.1. Android . . . . . . . . . 2.1.1. Historia . . . . . 2.1.2. Arquitectura . . . 2.2. Android Framework . . . 2.2.1. Servicios . . . . . 2.2.1.1. Servicios 2.2.1.2. Servicios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . del sistema . . de aplicaciones. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. 5 5 5 5 6 6 6 7. 3. Estadísticas de batería 3.1. Situación actual . . . . . 3.2. BatteryStats . . . . . . . 3.3. Obtención de datos . . . 3.4. Consumos monitorizados 3.5. Realización del cálculo . 3.6. Herramientas . . . . . . 3.6.1. Dumpsys . . . . . 3.6.2. Battery Historian 3.6.3. FTrace . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. 9 9 9 10 10 12 13 13 14 14. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . . . . . .. . . . . . . . . .. 4. Mejoras de cálculo de consumo 15 4.1. Consumo de Bluetooth . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.2. Cálculo de tiempos de Wi-Fi y redes móviles . . . . . . . . . . . . . . . 16 xvii.
(18) xviii. 4.3. 4.4. 4.5. 4.6. 4.7. 4.8.. Índice. Consumo de Wi-Fi . . . . . . Flash tratado como sensor . . Consumo de Flash y Cámara . GPS tratado como sensor . . Consumo del motor . . . . . . Comparación con Android L .. 5. Diseño 5.1. Estudio de posibilidades 5.1.1. Dumpsys . . . . . 5.1.2. Battery Historian 5.2. Requisitos . . . . . . . . 5.3. Herramientas . . . . . . 5.3.1. Android Studio . 5.3.2. Gradle . . . . . . 5.3.3. Git . . . . . . . . 5.4. Code style . . . . . . . . 5.5. Continous integration . . 6. Implementación 6.1. Preparación del entorno 6.2. Apariencia . . . . . . . . 6.3. Detector de consumos . 6.4. Arquitectura . . . . . . . 6.4.1. MVP . . . . . . . 6.4.2. Interactor . . . . 6.4.3. Repository . . . . 6.4.4. Data Sources . . 6.5. Test . . . . . . . . . . . 6.6. Librerías . . . . . . . . . 6.6.1. Butter Knife . . 6.6.2. Dagger 2 . . . . 6.6.3. Mockito . . . . . 6.6.4. JUnit . . . . . . 6.6.5. Espresso . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . .. 17 17 18 18 18 19. . . . . . . . . . .. 21 21 21 22 22 23 23 24 24 24 25. . . . . . . . . . . . . . . .. 27 27 27 29 33 35 36 36 37 37 39 39 39 41 41 42. 7. Verificación y validación 43 7.1. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 7.2. Verificación de resultados . . . . . . . . . . . . . . . . . . . . . . . . . . 44 8. Conclusiones 45 8.1. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 8.2. Líneas futuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Bibliografía. 47.
(19) Índice. Lista de acrónimos. xix. 49.
(20)
(21) Índice de figuras 2.1. Arquitectura de Android . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Servicios del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 6 7. 3.1. Ejemplo de gráfica de Battery historian . . . . . . . . . . . . . . . . . .. 14. 6.1. 6.2. 6.3. 6.4. 6.5.. 28 29 32 33 34. Apariencia de la aplicación. . . . . . . . Apariencia de la Activity de detalle. . . . Detector de consumos . . . . . . . . . . Regla de dependencia Clean Architecture Arquitectura de la aplicación . . . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. xxi.
(22)
(23) Índice de Tablas 3.1. Consumos monitorizados por BatteryStats . . . . . . . . . . . . . . . . 3.2. Consumos Wi-Fi y Bluetooth . . . . . . . . . . . . . . . . . . . . . . .. 11 12. xxiii.
(24)
(25) Capítulo 1. Introducción El comienzo es la parte más importante de la obra. Platón. Resumen: En este capítulo se presenta la motivación, circunstancias y contexto en el que se desarrolla este TFG (Trabajo Fin de Grado). Seguidamente, definimos los objetivos generales y específicos del mismo. Para, finalmente, presentar la organización del presente documento con una breve explicación del contenido de cada capítulo que vamos a encontrar en él.. 1.1.. Marco del trabajo. BQ es una marca de la empresa Mundo Reader S.L que se dedica al diseño, desarrollo y distribución de smartphones, e-readers y tablets. También trabajan en el ámbito de la robótica, sobre todo orientada a niños, y en el de la impresión 3D con Mundo Reader 3D. Es una de las empresas que más ha crecido de España en los últimos años, además de expandirse fuera de nuestras fronteras. Este TFG se ha llevado a cabo en la empresa BQ a través de la Cátedra BQ que ésta tiene en la ETSIT (Escuela Técnica Superior de Ingenieros de Telecomunicación) de la UPM (Universidad Politécnica de Madrid ) desde el 2013. En ella se realizan actividades de colaboración en los campos de formación, investigación y prácticas en el área de las tecnologías de la información y comunicaciones. Están orientadas al diseño, desarrollo y análisis de productos de electrónica de consumo. Ésta cátedra pretende desarrollar programas conjuntos de I+D+i y de formación de la ETSIT-UPM.. 1.2.. Motivación. En los últimos años, la venta de teléfonos móviles se ha disparado, sólo en 2013 creció un 46 %. Desde entonces lo que más ha crecido ha sido la venta de teléfonos móviles libres en un 30 %. La gran mayoría de ellos fueron y son smartphones. Una de las partes más importantes de un teléfono inteligente es la batería, ya que su 1.
(26) 2. Capítulo 1. Introducción. duración es crítica para su uso. Los smartphones cada vez aumentan más la potencia de sus componentes, aumento de la memoria RAM (Random Access Memory), mayor capacidad de la CPU (Central Processing Unit, Unidad Central de Procesamiento) y más cantidad de memoria interna, entre otras especificaciones. La mejora de estos componentes hacen que su consumo sea bastante mayor. El aumento del tamaño de la pantalla hace que el consumo de la misma aumente en gran medida. Es necesario por tanto, que el consumo de batería del terminal esté lo más optimizado posible.. 1.3.. Definición del problema. Partiendo del planteamiento actual de que la batería es un aspecto crítico para un smartphone, su consumo debe estar monitorizado exhaustivamente para detectar posibles fallos que agoten la batería. La plataforma sobre la que se realizará el estudio es Android. Android es una plataforma para smartphones creada por Google en el año 2005. El crecimiento exponencial de los últimos años ha colocado a Android con un 90 % de cuota de mercado en el mundo, y el 92.9 % en España. El cálculo del consumo de la batería que realiza Android es una estimación a partir de datos que recoge de cada uno de los sistemas que consumen energía. Muchas veces estos datos no son correctos, o el trato posterior de éstos mismos no garantiza el consumo que ha sufrido la batería. Es muy importante para una empresa fabricante de teléfonos inteligentes que ese consumo se calcule correctamente, para así comprobar que el consumo es óptimo y la duración de la batería correcta.. 1.4.. Objetivos. Se definen los siguientes objetivos para este TFG: Objetivo general: Diseño de una herramienta para la optimización de batería en smartphones. Para desarrollar este objetivo se divide en objetivos específicos a cumplir. Objetivos específicos: • Estudio del framework de Android sobre el cálculo de consumo de batería. Se debe comprender qué componente se encarga de realizarlo, y cómo. • Mejoras en el cálculo del consumo. Tras el estudio del framework, en el caso de encontrar problemas o errores en el cálculo del consumo, se propondrá una solución. • Estudio de las herramientas para batería que existen actualmente. Se comprobará si cumplen con los requisitos especificados por el cliente, y se presentarán ventajas y desventajas de cada una de ellas..
(27) 1.5. Organización del documento. 3. • Se elegirá la plataforma y el lenguaje a desarrollar la herramienta.. 1.5.. Organización del documento. El presente documento está organizado de la siguiente forma: Capítulo 1: en él se presenta la motivación, circunstancias, contexto y objetivos a cumplir. Capítulo 2: se tratan conceptos necesarios para el posterior desarrollo del documento. Se explica la arquitectura de la plataforma Android, y en más detalle, la capa framework. Capítulo 3: se explica en detalle la situación actual de las estadísticas de batería en el framework de Android. Capítulo 4: tras el estudio del cálculo del consumo realizado en el capítulo 3, se enumeran posibles soluciones a los problemas encontrados. Capítulo 5: se presenta el estudio de herramientas para las estadísticas de batería, incluyendo sus ventajas y desventajas. Se toma la decisión de la plataforma y lenguaje a elegir para desarrollar la herramienta, y se presentan herramientas que se usarán para su desarrollo. Capítulo 6: se explica el proceso de desarrollo de la aplicación. Se presenta en detalle la arquitectura elegida, y los patrones software implementados. Capítulo 7: se expone el banco de pruebas de la aplicación y la verificación de las mismas. Capítulo 8: se exponen las conclusiones del proyecto y líneas futuras..
(28)
(29) Capítulo 2. Fundamentos Si buscas resultados distintos, no hagas siempre lo mismo. Albert Einstein. Resumen: En este capítulo, en primer lugar, se muestra el sistema operativo Android, sobre el que trabajaremos, y su arquitectura para después entrar a detallar conceptos importantes a tener en cuenta para entender las estadísticas de batería. Se define lo que es un servicio, se explican distintos tipos y se elige el tipo de servicio necesario para este proyecto.. 2.1.. Android. 2.1.1.. Historia. Android es una plataforma para smartphones basado en el núcleo Linux. Fue diseñado principalmente para dispositivos móviles con pantalla táctil, como teléfonos inteligentes, tablets y también para relojes inteligentes, televisores y automóviles. Inicialmente fue desarrollado por Android Inc., empresa que Google respaldó económicamente y más tarde, en 2005, la compró. Android fue presentado en 2007 junto la fundación del Open Handset Alliance (un consorcio de compañías de hardware, software y telecomunicaciones) para avanzar en los estándares abiertos de los dispositivos móviles. 2.1.2.. Arquitectura. Como se puede ver en la Figura 2.1, Android es un sistema operativo separado en capas. Su arquitectura está constituida por cuatro capas principales: Núcleo o Kernel, Librerías y Android Runtime, Framework y Aplicación. Esta separación es conocida como pila o stack, lo que permite que las funciones de una capa superior utilicen elementos de las capas inferiores de forma transparente. Esta abstracción permite desarrollar aplicaciones compatibles para dispositivos con hardware diferente. Es decir, facilita el desarrollo de las aplicaciones proporcionando 5.
(30) 6. Capítulo 2. Fundamentos. Figura 2.1: Arquitectura de Android. los medios necesarios para que el desarrollador no dependa del dispositivo en concreto. A continuación, se explica en detalle los detalles de la capa Framework necesarios para entender el funcionamiento del cálculo de consumo de batería. [1, 2]. 2.2.. Android Framework. La capa Framework de Android proporciona un conjunto de API (Application Programming Interface, Interfaz de Programación de Aplicaciones) para que los desarrolladores reutilicen componentes entre todos los recursos disponibles en el sistema. Estos componentes son reusables, intercambiables y fácilmente reemplazables. Android provee APIs en varias áreas como conexiones de red, interfaz de usuario o acceso a memoria [3]. Estas librerías están escritas en Java y se ejecutan sobre la máquina virtual Dalvik [4]. Este proyecto se centra en las estadísticas de batería, y para poder continuar explicando como funciona es necesario entender qué es un servicio, qué tipos de servicio hay y cuál es el más interesante para este proyecto. 2.2.1.. Servicios. Los servicios son un tipo de programa que pueden realizar operaciones de larga ejecución en segundo plano sin proporcionar interfaz de usuario. Hay varios tipos de servicios ejecutándose en el sistema simultáneamente. 2.2.1.1.. Servicios del sistema. Android define una serie de servicios necesarios para realizar tareas relacionadas con el funcionamiento del sistema. Estos sistemas se encargan, entre otras cosas, del Wi-Fi, del Bluetooth o el sistema de vibración. Dichos servicios se pueden listar desde la shell del sistema mediante la orden service list. Un resultado de dicha ejecución se.
(31) 2.2. Android Framework. 7. puede ver en la Figura 2.2. Estos servicios se llaman Servicios del sistema o en inglés System services, y se inician una vez se inicia el teléfono. Son servicios que nunca mueren, y que sin ellos el terminal no tendría un funcionamiento normal.. Figura 2.2: Servicios del sistema. En la Figura 2.2 aparecen algunos de estos servicios encargados de la cámara, el sonido o el encendido del terminal. Además, también aparece BatteryStats como un servicio del sistema. Este servicio es en el que se centra este proyecto, y más adelante se profundizará en su funcionamiento.. 2.2.1.2.. Servicios de aplicaciones. Existe otro tipo de servicio, en este caso, necesario para el funcionamiento normal de cada aplicación. Hay aplicaciones tipo Whatsapp que necesita realizar tareas en segundo plano para lanzar notificaciones cuando se detecta un evento. Estos servicios se llaman servicios definidos por aplicaciones y se encarga el desarrollador de definirlos en su aplicación. Para el objetivo de este proyecto son necesarios únicamente los servicios del sistema, por lo que nos centraremos en ellos a partir de ahora..
(32)
(33) Capítulo 3. Estadísticas de batería Llevo obteniendo resultados desde hace tiempo, pero aún no sé cómo llegué a ellos. Carl Friedrich Gauss. Resumen: En este capítulo, en primer lugar, se indican los ficheros que participan en el cálculo del consumo de la batería. Posteriormente, se explican los métodos de obtención de datos, los consumos monitorizados y la realización del cálculo del consumo. Finalmente, se presentan herramientas que facilitan la visualización del consumo.. 3.1.. Situación actual. La situación actual del cálculo de consumo de batería es un terreno poco transitado, es decir, hay muy poca documentación por parte de Android de como se realiza internamente en el terminal. A continuación se explica qué componente se encarga de almacenar datos relacionados con el consumo, qué datos se están monitorizando, qué componente obtiene y de dónde esos datos y finalmente cómo se calcula el consumo.. 3.2.. BatteryStats. Como se mencionó anteriormente en 2.2.1.1, el servicio del sistema encargado de las estadísticas de la batería es BatteryStats. Este servicio utiliza una serie de ficheros necesarios para el cálculo del consumo. BatteryStats.java: Clase abstracta que define todos los timers o contadores de tiempo que se encargarán de contabilizar el tiempo que ha estado corriendo cada componente que ha consumido batería. Estos timers son los encargados de contar el tiempo que el Wi-Fi, Flash o cualquier otro tipo de componente del sistema ha estado encendido para calcular posteriormente su consumo. Está situado en frameworks/base/core/java/android/os. BatteryStatsImpl.java: Implementación de BatteryStats.java. Situado en /frameworks/base/core/java/com/android/internal/os. 9.
(34) 10. Capítulo 3. Estadísticas de batería. BatteryStatsService.java: Servicio del sistema encargado de recibir eventos. Estos eventos activan o desactivan los timers definidos en BatteryStats.java. De esta forma, se puede contabilizar el tiempo que un componente del sistema ha estado activo. Dichos eventos son enviados por otros servicios del sistema como por ejemplo el de cámara o Wi-Fi. Situado en /frameworks/base/services/core/java/com/android/server/am. BatteryStatsHelper.java: Encargado de procesar los datos obtenidos a través de BatteryStatsService.java y almacenados por BatteryStats.java, para calcular el consumo por aplicación o servicio. Por cada aplicación o servicio que ha consumido, se genera un objeto BatterySipper.java que guarda información relacionada con el consumo. Situado en /frameworks/base/core/java/com/android/internal/os. BatterySipper.java: Objeto que almacena información de una aplicación o servicio que ha consumido batería. Hay distintos tipos de consumo, y una aplicación puede consumir por distintos motivos como por ejemplo uso de Wi-Fi, uso de redes móviles o de flash. Estos consumos se guardan diferenciados pudiendo obtenerlos de forma desgregada. Situado en /frameworks/base/core/java/com/android/internal/os.. 3.3.. Obtención de datos. El Framework de Android automáticamente determina el uso de batería contabilizando el tiempo que cada componente ha estado en los diferentes estados. Cuando los componentes(Wi-Fi, redes móviles, GPS, pantalla) cambian sus estados(encendido/apagado, bajo/alto brillo) su controlador, conocido como servicio del sistema, avisa a BatteryStatsService. [5] BatteryStats guarda información y la mantiene incluso tras apagar el terminal. El cálculo del consumo no se realiza directamente, sino que a partir de los datos almacenados cuando se necesite o se pida, se realiza dicho cálculo. Se utilizan los siguientes métodos para la obtención de estadísticas: Push: Los servicios de cada componente avisan de los cambios en sus estados a BatteryStatsService. Pull : Para componentes como la CPU usada por las aplicaciones, automáticamente se piden los datos en las transiciones de los procesos en ejecución para obtener una captura de dicho estado y poder comparar ante futuros cambios.. 3.4.. Consumos monitorizados. Cada fabricante debe generar un fichero llamado power_profile, que debe definir en /frameworks/base/core/res/res/xml/power_profile.xml. Este fichero contiene los consumos de cada uno de los componentes del teléfono. Las medidas de consumo.
(35) 3.4. Consumos monitorizados. 11. se dan en mA, y es el fabricante el que debe medirlas con el hardware de su dispositivo en las situaciones en las que la documentación de Android pide. Este fichero es de tipo xml, de forma que se pueden definir etiquetas específicas para cada consumo, además de permitir anidaciones de etiquetas en forma de array. Los consumos monitorizados por el framework de Android se muestran en la Tabla 3.1 [6]. Nombre screen.on screen.full wifi.on wifi.active wifi.scan camera.avg camera.flashlight gps.on radio.active radio.scanning radio.on. cpu.speeds cpu.idle cpu.awake cpu.active cpu.clusters.core. Descripción Consumo de la pantalla al mínimo brillo. Consumo de la pantalla al máximo brillo. Consumo Wi-Fi encendido, pero sin recibir, enviar o escanear. Consumo de Wi-Fi cuando se envían o reciben datos. Consumo de Wi-Fi cuando se escanea en busca de puntos de acceso. Consumo de cámara. Consumo de led flash. Consumo de GPS adquiriendo señal. Consumo de redes móviles cuando transmite o recibe. Consumo de redes móviles cuando escanea. Consumo de redes móviles cuando se encuentra encendido el chip. Entrada multivalor para cada uno de los tipos de calidad de señal. Entrada multivalor que lista las frecuencias de la CPU. Consumo de la CPU cuando el dispositivo se encuentra suspendido. Consumo de la CPU cuando el dispositivo se encuentra activo. Consumo de la CPU en cada frecuencia de funcionamiento. Entrada multivalor. Número de núcleos de cada CPU.. Ejemplo 200mA 300mA 2mA 30mA 100mA 600mA 200mA 50mA 300mA 1.2mA 1.2mA. 125000KHz 3mA 50mA 200mA 4. Tabla 3.1: Consumos monitorizados por BatteryStats. Adicionalmente, a partir de Android 6.0 los chips de Wi-Fi y Bluetooth son capaces de exportar estadísticas de batería. Es decir, el chip conoce información acerca de: Transmisión: Cantidad de tiempo que ha estado transmitiendo información, medido en milisegundos. Recepción: Cantidad de tiempo que ha estado recibiendo información, medido en milisegundos. Idle: Cantidad de tiempo que ha estado en reposo, medido en milisegundos. Es el fabricante del SoC (System on Chip) el encargado de definir la interfaz para obtener dichos datos. Esta interfaz se conoce como HCI (Host Controller Interface). El fabricante del teléfono, de nuevo, debe definir un fichero llamado config.xml situado en /frameworks/base/core/res/res/values/. En dicho fichero se deben definir una serie de variables definidas en la Tabla 3.2..
(36) 12. Capítulo 3. Estadísticas de batería Nombre config_bluetooth_idle_cur_ma config_bluetooth_active_rx_cur_ma config_bluetooth_active_tx_cur_ma config_bluetooth_operating_voltage_mv config_wifi_idle_cur_ma config_wifi_active_rx_cur_ma config_wifi_active_tx_cur_ma config_wifi_operating_voltage_mv. Descripción Consumo de bluetooth en estado de reposo. Consumo de bluetooth en estado de recepción. Consumo de bluetooth en estado de transmisión. Voltage de referencia del chip de bluetooth. Consumo de Wi-Fi en estado de reposo. Consumo de Fi-Fi en estado de recepción. Consumo de Wi-Fi en estado de transmisión. Voltage de referencia del chip de Wi-Fi.. Tabla 3.2: Consumos Wi-Fi y Bluetooth. 3.5.. Realización del cálculo. Como se comentó en 3.2, el encargado de calcular el consumo de batería es BatteryStatsHelper. Dicho fichero carga las estadísticas obtenidas por BatteryStats y realiza una serie de operaciones sobre ellas. Se diferencian distintos tipos de consumo: IDLE : Consumo del dispositivo en modo reposo. CELL: Consumo de redes móviles. WIFI : Consumo de Wi-Fi. BLUETOOTH : Consumo de Bluetooth. FLASHLIGHT : Consumo de flash de la cámara. SCREEN : Consumo de pantalla. APP: Consumo de aplicación. CAMERA: Consumo de cámara. UNNACOUNTED: Consumo infraestimado. OVERCOUNTED: Consumo sobreestimado. Antes de continuar explicando el proceso de cálculo del consumo, es importante explicar el concepto de UID (Unique identifier ). BatteryStats define una clase llamada UID, que representa lo que comúnmente se conoce como aplicación. El distintivo de UID es para especificar que cada aplicación instalada en el dispositivo se conoce por un número y que además es único. El primer paso en el cálculo de consumo, es obtener las estadísticas de cada UID. Una vez se tienen las estadísticas, se calcula su consumo de CPU, wakelocks, redes móviles, Wi-Fi, Bluetooth, sensores, cámara y flash. Estos consumos se añaden a un objeto BatterySipper en el que el tipo de consumo de los mencionados anteriormente será APP. Este paso se repite para todos los UID que hayan consumido batería. El siguiente paso es añadir los consumos de los componentes del sistema que no son usados por aplicaciones. En este caso, son los componentes de pantalla, idle,.
(37) 3.6. Herramientas. 13. redes móviles, Wi-Fi y Bluetooth. En el caso de redes móviles y Wi-Fi, cuyo consumo también está contemplado en las aplicaciones, Android distingue entre el uso de estos componentes por parte del sistema o por parte de las aplicaciones. Su consumo no se contabiliza dos veces. Para cada uno de estos componentes se genera un objeto BatterySipper en el que se específica su tipo de consumo. Los consumos que aparecen como UNNACOUNTED y OVERCOUNTED son debidos a una mala estimación del consumo real. Es decir, si la batería ha sufrido una descarga del 20 % y su capacidad es de 3000mAh, quiere decir que se han consumido 600mAh. Estos 600mAh son reales, ya que el porcentaje de batería ha disminuido del 100 % al 80 %. Sin embargo, a veces, el teléfono estima que ha consumido 500mAh, debido a la sucesión de errores en los timers. Esto supone que aparezca un consumo de UNNACOUNTED de 100mAh. En el caso contrario, si el teléfono cree que ha consumido 700mAh, aparecerá un consumo de OVERCOUNTED de 100mAh. La forma de calcular el consumo a partir de los valores definidos en power_profile es la siguiente. El valor de consumo se recoge en mA, y se divide por 3600 para hacer la conversión a mAh. Pongamos por ejemplo que el dispositivo ha estado con el Wi-Fi escaneando durante dos horas. Su consumo se calcularía de la siguiente manera: wifi.scan * 2 = 200mAh . El valor de wifi.scan ha sido extraído del valor de referencia de la Tabla 3.1.. 3.6.. Herramientas. Existen algunas herramientas para obtener feedback del consumo. Estas herramientas presentan información acerca del consumo, y del historial de eventos presente en el dispositivo.. 3.6.1.. Dumpsys. La herramienta más utilizada durante la realización de este TFG ha sido la salida de dumpsys batterystats. Dumpsys es una herramienta propia de Android cuya salida proporciona información relevante acerca de los servicios del sistema. En nuestro caso, de nuevo, nos interesa el servicio del sistema BatteryStats. Lo más sencillo es volcar la salida a un fichero con extensión txt para facilitar su lectura. Los datos que aporta son relevantes para las estadísticas de batería, ya que aparecen todos los tiempos que cada componente ha estado activo, además de los consumos detallados de cada aplicación. Muestra todos los wakelocks que han despertado al.
(38) 14. Capítulo 3. Estadísticas de batería. teléfono de su estado de reposo y que suponen un aumento significativo en el consumo.. 3.6.2.. Battery Historian. Otra herramienta interesante es el repositorio de Google en Github llamado BatteryHistorian [7]. Este repositorio está escrito en GO y al ejecutarlo genera un servidor local en el que permite subir la salida de dumpsys batterystats comentada anteriormente. Este servidor representa gráficamente los eventos que han ocurrido en el teléfono además de presentar los datos importantes de una manera más visual. Esto facilita enormemente el estudio de la salida de dumpsys que genera un fichero con más de mil líneas y su lectura es pesada.. Figura 3.1: Ejemplo de gráfica de Battery historian. 3.6.3.. FTrace. FTrace (Function Tracer ) es una herramienta que permite perseguir el flujo de ejecución en el kernel de Linux. Todas las interacciones del usuario con su smartphone suponen una llamada al kernel, por lo que esta herramienta facilita seguir la comunicación entre espacio de usuario y kernel. Esta herramienta es muy útil para perseguir los wakelocks que despiertan al teléfono de su modo de reposo y que suponen un aumento importante en el consumo..
(39) Capítulo 4. Mejoras de cálculo de consumo No podemos resolver problemas pensando de la misma manera que cuando los creamos. Albert Einstein. Resumen: En este capítulo se presentan los problemas detectados en la adquisición y en el cálculo del consumo. Se propone solución para algunos de ellos, y en otros se explica el porqué no ha sido posible resolver el problema. Por último se realiza una comparación de estos problemas con Android L.. Para el desarrollo de este capítulo se estudió el funcionamiento de las estadísticas de batería en Android. A lo largo del estudio se encontraron varias deficiencias que hacían que el consumo calculado fuera poco fiable. A continuación se analizan dichas deficiencias y se presentan soluciones en los casos en los que sea posible. Si no es posible encontrar una solución, se explica el porqué de esta decisión.. 4.1.. Consumo de Bluetooth. El funcionamiento del Bluetooth [8] es un poco diferente al resto de servicios del sistema. Google ha decidido que exista un servicio del sistema específico para el Bluetooth, pero por debajo ha implementado una aplicación que funciona como el servicio. Es decir, el servicio del sistema delega sus funciones en la aplicación. Esta aplicación es invisible para el usuario. Todo el consumo generado por el Bluetooth se le atribuye a esta aplicación. De este modo, cualquier aplicación que utilice el Bluetooth, como por ejemplo cualquiera encargada de comunicarse con un wearable, tendrá consumos muy bajos ya que no se le suma el consumo debido a la comunicación por Bluetooth. La solución a este problema es eliminar dicha aplicación y dejar que el Bluetooth funcione como servicio del sistema de manera similar al Wi-Fi. Eliminar la aplicación no es sencillo, ya que todo el código se encuentra en ésta y el servicio del sistema no implementa ninguna funcionalidad sin la aplicación. Por lo que se debería reescribir el 15.
(40) 16. Capítulo 4. Mejoras de cálculo de consumo. código del servicio del sistema, y esto depende de Google, ya que se intentó diferenciar el consumo por aplicaciones pero según está el framework no es posible.. 4.2.. Cálculo de tiempos de Wi-Fi y redes móviles. Para obtener el consumo tanto de Wi-Fi como de redes móviles es necesario tener los tiempos que dichos componentes han estado en cada uno de los estados en los que consumen. Como se puede ver en la Tabla 3.1, para ambos tipos de comunicaciones se definen tres tipos de consumo: active, scan y on. No se hace distinción entre transmisión y recepción por lo que se entiende que consume lo mismo para ambas transacciones. El problema es que no existe forma de saber cuando el chip ha terminado la transmisión o la recepción. Por tanto, la forma en la que Android ha decidido hacerlo es especificando unos temporizadores con una cuenta atrás hasta cero. Este temporizador se inicia una vez comienza una transmisión o una recepción. Si antes de que ese temporizador finalice se recibe o envía un nuevo paquete, este temporizador se reinicia. El tiempo indicado en los temporizadores es de 10 segundos para redes móviles y 15 segundos para Wi-Fi. Estos tiempos parecen demasiado altos, ya que con las velocidades de las redes actualmente un paquete tarda bastante menos en enviarse. Además hay que tener en cuenta que no todos los paquetes tienen la misma dimensión, y el valor del temporizador es constante. Imaginemos que se quiere enviar un ACK (Acknowledgement, Asentimiento) de pocos bytes, su transmisión por Wi-Fi puede durar unos pocos milisegundos, sin embargo, se avisará 15 segundos después de que la tranmisión ha terminado. Esto supone un error de varios segundos por cada paquete enviado o recibido. El problema se acentúa si antes de que finalice el temporizador se recibe otro ACK, que se volvería a reiniciar el temporizador y el error en este caso sería aún mayor. La solución a este problema no es trivial. Según [9], es la estación base o el AP (Access Point, Punto de acceso) el encargado de decidir si el chip debe dejar de enviar o recibir potencia. Debido a esto Google decidió implementarlo con los temporizadores. Una manera de mejorar la solución de Google es que el timeout de los temporizadores sea dinámico. Es decir, calcularlo en función del tamaño del paquete y de la velocidad a la que será enviado. El tamaño del paquete es inmediato de obtener, sin embargo, la velocidad a la que se envía no se puede obtener a nivel de código. A nivel de código se puede acceder hasta el transceiver, pero quién se encarga de la modulación y al final de la velocidad del envío es el modem. El modem se encuentra en el SoC y su funcionamiento está bastante protegido por el fabricante..
(41) 4.3. Consumo de Wi-Fi. 4.3.. 17. Consumo de Wi-Fi. El cálculo del consumo de Wi-Fi se basa en una estimación de consumo por paquete. Android calcula a partir de la siguiente fórmula lo que se consume cuando se envía un paquete:. wifi.active ) ( 60 ∗ 60 ) bit.rate ) ( 8 ) ( 2048 (60 ∗ 60) (. (4.1). El valor de wifi.active extraído de la Tabla 3.1 es 30mA. El valor de bit.rate, en el código aparece por defecto como 1Mbps. Realizando esta cuenta aparece un consumo por paquete del orden de 10−6 mA. Como se ha comentado en 4.2, el tamaño de los paquetes no es constante, por lo que su consumo tampoco lo debería ser. La estimación debería ser en función de bytes enviados y no por paquetes.. 4.4.. Flash tratado como sensor. Como se explica en 3.5, cuando se calcula el consumo por aplicación, se tiene en cuenta un consumo atribuido a los sensores. Estos sensores son el acelerómetro, el giroscopio, el sensor de proximidad o el sensor de temperatura. El consumo de estos sensores no se define en el archivo power_profile, ya que es el hardware el que emite este valor. A nivel de HAL (Hardware Abstraction Layer, Capa de Abstracción de Hardware) existe una estructura de datos con información importante de cada sensor. A nosotros nos interesa dos de esos parámetros, que son, su consumo y su identificador. El problema detectado es que el flash tenía el mismo identificador que el giroscopio. Como se puede ver en la Tabla 3.1, el consumo del flash es uno de los más altos mientras que el del giroscopio apenas supone 5mA. Esto hace que nuestras estadísticas de batería no sean fiables, ya que el consumo calculado era mucho menor que el real. A su vez, supone que aparezca un consumo alto detectado como UNNACOUNTED al tener encendido el flash durante varios minutos. Este problema fue resuelto por Google tras eliminar el trato del flash como un sensor, y abstraerlo al servicio del sistema encargado de la cámara que se encarga a su vez del flash..
(42) 18. 4.5.. Capítulo 4. Mejoras de cálculo de consumo. Consumo de Flash y Cámara. El flash y la cámara son dos de los componentes del teléfono que más batería consumen. Como se puede ver en la Tabla 3.1, sus consumos son 200mA y 600mA respectivamente. Estos consumos suponen un gasto importante de batería cuando se activan por separado, pero el consumo es enorme si se dan los dos a la vez. Supongamos una batería de 3000mAh, en el caso de que estos dos componentes estuvieran activos al mismo tiempo, su duración sería inferior a cuatro horas. Según Google ha desarrollado el framework de cámara, no se puede encender el flash sin encender la cámara. Es decir, si un usuario activa el flash en modo linterna, la cámara automáticamente se enciende y comienza a capturar frames que desechará. Esto supone un aumento de consumo enorme. En una de las últimas versiones de Android M actualizadas por Google permite encender el flash sin tener que encender la cámara. Una solución necesaria y que sólo ellos podían desarrollar.. 4.6.. GPS tratado como sensor. El GPS (Global Positioning System, Sistema global de navegación) a la hora de calcular el consumo también se tiene en cuenta como si fuera un sensor. En el código de BatteryStats definen un número mágico que será el identificador del GPS. En este caso para que no se confunda con ningún otro sensor, su identificador es -1000. Es necesario que sea negativo para evitar con seguridad la confusión. En el código tienen un comentario indicando que eso se debe arreglar en versiones futuras, pero de momento no se ha tenido en cuenta. La solución de este problema es relativamente sencilla, ya que bastaría con definir un nuevo timer dedicado exclusivamente para el GPS. Esto es inmediato ya que el servicio del sistema encargado del GPS se encarga de indicar cúando se ha iniciado y también que UID ó aplicación lo ha hecho.. 4.7.. Consumo del motor. En la clase UID definida en BatteryStats se tiene en cuenta el tiempo que cada aplicación ha estado vibrando, pero sin embargo, el consumo no se define en el fichero power_profile. La documentación de Android no pide ese dato, y por tanto el fabricante no lo calcula. Se realizó un estudio del tiempo que el motor estaba vibrando a lo largo del día en los smartphone de diferentes perfiles de personas. En el caso peor, en el que el teléfono había recibido muchas notificaciones, el tiempo vibrando rondaba los 2 ó 3 minutos..
(43) 4.8. Comparación con Android L. 19. Se calculó el consumo de dicho motor para intentar mejorar la estimación de batería, pero apenas esos tres minutos suponían 1mAh. Se consideró que no era lo suficientemente relevante como para tenerlo en cuenta.. 4.8.. Comparación con Android L. Android M es la última versión presentada por Google. Es la versión 6.0 y su nombre es Marshmallow. El comienzo de este TFG fue en la versión anterior, Android L. Esa versión era la 5.1.1 y su nombre Lollipop. A continuación se comentan los problemas anteriores desde el punto de vista de Android L: Consumo de Bluetooth: En este caso el problema ya estaba en Android L, y ha permanecido en Android M. Sin embargo, el consumo en Android M es más fiable ya que en vez de basarse en estimaciones de tiempo, la medida de consumo se exporta directamente desde el hardware. Cálculo de tiempos de Wi-Fi y redes móviles: El problema ya estaba en Android L, solo que el caso del Wi-Fi no estaba implementado. El método de los temporizadores solo estaba desarrollado para las redes móviles. El timeout definido para las redes móviles en Android L era de 5 segundos en vez de 10. Consumo de Wi-Fi: El problema es el mismo en Android L que en Android M. Flash tratado como sensor: El problema ocurría en Android L y hasta las últimas actualizaciones de Android M no se ha solucionado. Consumo de Flash y Cámara: Misma situación que el caso anterior. GPS tratado como sensor: El problema es el mismo en Android L que en Android M. Cabe destacar que el código en Android M está mejor estructurado. Muchas líneas se han extraído a otros ficheros, y de esta forma se repite menos código. Es más sencillo y se pueden producir menos errores..
(44)
(45) Capítulo 5. Diseño Si no lo puedes explicar con simplicidad, es que no lo entiendes bien. Albert Einstein. Resumen: En este capítulo se presenta el estudio de la herramientas existentes para la monitorización de batería, así como la elección de la plataforma para desarrollar una nueva herramienta propia. Se presentan herramientas necesarias para el desarrollo, y por último se presentan una serie de reglas que tiene que cumplir el código.. 5.1.. Estudio de posibilidades. En el Capítulo 3.6 se presentaron las herramientas que hay en el mercado para tratar y mostrar las estadísticas de batería. A continuación se especifican ventajas y desventajas de cada una: 5.1.1.. Dumpsys. Ventajas Muestra el historial de todos los eventos ocurridos en el teléfono desde su inicio. Se puede obtener mucha información del estado del terminal. Para obtener la salida de dupmsys solo se necesita el terminal, no tiene dependencia de otro software. Desventajas La lectura es muy pesada, ya que son más de mil líneas en un fichero con formato .txt. Desde el punto de vista de un usuario, la información que aporta es de un nivel técnico muy alto. Es necesario acceder a la consola del terminal para obtener la salida de dumpsys. 21.
(46) 22. Capítulo 5. Diseño. 5.1.2.. Battery Historian. Ventajas Ofrece mucha información y de una forma gráfica más visual. Muestra el historial de todos los eventos ocurridos en el teléfono desde su inicio mediante una gráfica, sobre la cual se puede pasar el ratón y se obtiene información detallada sobre el evento en el que se posó el ratón. Battery historian permite la lectura de otro informe extraído del teléfono, bugreport. El proceso de extracción de este informe es más sencillo que el de dumpsys, ya que no es necesario entrar en la consola del terminal, y es posible generarlo desde la aplicación de Ajustes. Desventajas El proceso de instalación es complejo. El programa está en un repositorio de Github que debes clonar. Además está escrito en GO, por lo que tienes que instalar su compilador, herramientas y librerías. Una vez instalado, debes correrlo como un servidor local en el puerto que tú elijas. Este proceso no es sencillo para un usuario final. El tiempo de lectura de la salida obtenida es bastante grande. La interpretación de la salida la debe realizar el que ejecute el programa, ya que Battery Historian únicamente parsea los datos obtenidos a través de la salida de dumpsys o bugreport.. 5.2.. Requisitos. Los requisitos definidos por BQ, actúando como cliente, son los siguientes: Mayor facilidad en la lectura de los datos que en las herramientas presentadas anteriormente. Presentar estadísticas y consumo por cada aplicación que haya consumido. Posibilidad de explicar a un cliente final el consumo de su batería. Obtener feedback de la descarga de batería. Para ello se estudiarán aspectos críticos que puedan afectar al consumo, y se establecerán umbrales a partir de los cuales se debe alertar de un consumo no esperado. El cliente permite la flexibilidad de desarrollar la herramienta para la plataforma y el lenguaje que se quiera. En primer lugar se estudió la posibilidad de clonar el repositorio de Battery Historian y añadir los cambios necesarios para cumplir los requisitos del cliente, pero debido a su complejidad y el lenguaje en el que está escrito se descartó. El requisito más restrictivo para la elección de plataforma es la posibilidad de explicar a un cliente final el consumo de su batería. La forma más sencilla es integrar.
(47) 5.3. Herramientas. 23. una aplicación en el dispositivo que muestre los aspectos reseñados en el resto de requisitos. Por tanto se acuerda que se realizará una aplicación para la plataforma Android y se desarrollará en lenguaje Java. El requisito más difícil de cumplir es el último. La descarga del terminal es un tema complejo y depende de muchos factores. Siguiendo la Tabla 3.1, se entiende que los consumos a tener más en cuenta deberían ser: Pantalla Wi-Fi Cámara Flash Redes móviles CPU A estos se les debe añadir el consumo del Bluetooth. Además, un consumo importante y que no aparece en las tablas como tal, es el consumo debido a los Wakelocks de Android. Los Wakelocks son procesos en ejecución que despiertan a la CPU de su modo reposo. Tampoco le permiten volver a dormirse, por lo que el uso de wakelocks debería ser controlado. Para cada uno de estos consumos se estudiará su funcionamiento normal y se establecerán umbrales a partir de los cuales se notificará al usuario. Este estudio se realizará a partir de bugreports reportados por personas que han usado un smartphone BQ.. 5.3.. Herramientas. 5.3.1.. Android Studio. Android Studio es un IDE (Integrated Development Environment, Entorno de Desarrollo Integrado) para la plataforma Android. Fue anunciado en el año 2013 y reemplazó el uso de Eclipse como IDE oficial para el desarrollo de Android. Está basado en el software del entorno de desarrollo IntelliJ IDEA de la empresa JetBrains. Se utilizará la última versión disponible, ya que aunque sea una versión preview, no se han encontrado bugs en el trabajo diario. Además, esta versión permite Instant Run, es decir, una ejecución rápida. Esto es posible porque tras realizar unos cambios en el código, no vuelve a compilar toda la aplicación sino que compila sólo los cambios realizados. Esto hace que el tiempo de compilación entre prueba y prueba sea mucho menor. La versión utilizada es la 2.2 Preview 3..
(48) 24. 5.3.2.. Capítulo 5. Diseño. Gradle. Gradle es una herramienta que permite automatizar la construcción del proyecto. Es decir, se encarga de las tareas de compilación, ejecución de test, gestión de dependencias y despliegue del proyecto. Gradle usa DSL (Domain Specific Language, Lenguaje específico del dominio) basado en Groovy para declarar la formas de construir el proyecto. Las tareas generales ya vienen definidas en el proyecto creado en Android Studio, ya que Gradle es el encargado de automatizar las compilaciones de los proyectos de Google. 5.3.3.. Git. Git es un software de control de versiones. Se desarrolló pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando éstas tienen un gran número de archivos de código fuente. Es una herramienta muy potente cuando se trabaja en equipo, ya que permite trabajar en paralelo en distintas ramas del mismo proyecto. Es necesario que los equipos de trabajo sigan una metodología a la hora de trabajar con git, ya que sin seguir unas directrices comunes, lo que puede ser una herramienta muy potente puede convertirse en un auténtico caos. Durante este TFG se ha seguido la metodología conocida como git-flow [10]. La principal característica de esta metodología es que nadie trabaja directamente sobre la rama master o rama principal para que el código de dicha rama siempre pueda ser sacado a producción. Esto hace que la probabilidad de bugs en la rama de producción disminuya. Existe otra rama llamada develop en la que está el código que conformará la siguiente entrega del proyecto. Es decir, en la fecha de entrega del proyecto, se mergeará la rama develop con la rama principal, y saldrá a producción. Cada nueva feature o funcionalidad de la aplicación irá en una nueva rama que una vez esté terminada se mergeará con la rama develop. Como se ha dicho anteriormente, una vez llegue la fecha de entrega, la rama develop que ya contiene las features desarrolladas, se mergeará con la rama master.. 5.4.. Code style. El estilo del código o code style es un aspecto fundamental cuando varias personas trabajan sobre el mismo código. Se deben guardar una serie de reglas comunes, para que el código sea lo más uniforme posible. Estas restricciones son comunes para todos los desarrolladores, y se suelen especificar para cada lenguaje de una manera distinta. En nuestro caso, las reglas para el código Android han sido definidas por Google [11]..
(49) 5.5. Continous integration. 25. Gradle ayuda a que las reglas definidas por Google se cumplan. Como se ha comentado anteriormente, Gradle usa DSL para definir las tareas a desarrollar una vez se lanza una compilación, por lo que se le puede añadir una nueva tarea que compruebe que las reglas de estilo se cumplan. Esta tarea carga un fichero llamado checkstyle.xml en el que se definen las reglas a tener en cuenta y comprueba que el código cumple con lo definido en ese fichero.. 5.5.. Continous integration. CI (Continuous Integration, Integración continua) es un modelo informático propuesto inicialmente por Martin Fowler que consiste en hacer integraciones automáticas de un proyecto lo más a menudo posible para así poder detectar fallos cuanto antes. Entendemos por integración la compilación y ejecución de pruebas de todo un proyecto. El proceso suele ser el siguiente: cada cierto tiempo, se descargan las fuentes desde el control de versiones Git, se compila, se ejecutan pruebas y se generan informes. Ventajas Los desarrolladores pueden detectar y solucionar problemas de integración de forma continua, evitando el caos de última hora cuando se acercan las fechas de entrega. Disponibilidad constante de una versión para pruebas, demos o lanzamientos anticipados. Ejecución inmediata de las pruebas unitarias. Monitorización continua de las métricas de calidad del proyecto. Para realizar estas tareas existen aplicaciones como Jenkins que lanzan una compilación y una ejecución de todos los tests con cada commit. Para ahorrarnos el uso de una aplicación como esta, se acuerda que con cada commit se lance en local una compilación y una ejecución de los tests unitarios del proyecto. Los tests de integración y de interfaz de usuario son más pesados, por lo que se lanzarán antes de mergear ramas para evitar posibles regresiones ..
(50)
(51) Capítulo 6. Implementación Casi todo lo que realice será insignificante, pero es muy importante que lo haga. Mahatma Gandhi. Resumen: Durante este capítulo se explica la apariencia de la aplicación, además de como se ha llegado a realizar el informe sobre la descarga de la batería. Se explica la arquitectura escogida, los patrones de diseño software utilizados y los test realizados. Por último se enumeran las librerías utilizadas en el proyecto.. 6.1.. Preparación del entorno. Android establece una serie permisos que los desarrolladores deben declarar en el archivo AndroidManifest.xml. Estos permisos son necesarios para que la aplicación pueda acceder a Internet, o a la cámara entre otros. En nuestro caso es necesario el permiso declarado por Android como BATTERY_STATS. Hasta Android KitKat este permiso era público y cualquier desarrollador podía declararlo en su aplicación para obtener las estadísticas de batería. A partir de la versión 4.4 de KitKat este permiso pasó a ser un permiso del sistema, por lo que sólo las aplicaciones firmadas por Google pueden obtener este permiso. Fue necesario cambiar el código comercial del teléfono para poderse saltar este permiso. Para poder implementar esto fue necesario buscar quién se encarga del control de los permisos en Android. La clase que se encarga de asegurar que el permiso se puede usar es ContextImpl. En esta clase hay un método llamado checkPermission que recibe un parámetro indicando qué permiso quiere ser comprobado, por lo que se introdujo que si el permiso era BATTERY_STATS se permitiera.. 6.2.. Apariencia. Siguiendo los principios de diseño de Google, la apariencia de la aplicación está basada en pestañas. La primera pestaña muestra todas las aplicaciones o servicios del 27.
(52) 28. Capítulo 6. Implementación. sistema que han consumido batería. De esta forma, se puede ver todos los consumos incluyendo los más pequeños que en la aplicación de Ajustes no aparecen. La aplicación de Ajustes solo muestra las aplicaciones que han superado un umbral, y si no se ha superado no aparecen. La segunda pestaña presenta las estadísticas generales de la batería. Es decir, el tiempo que ha estado el teléfono consumiendo batería, el tiempo que ha estado con Wi-Fi en cada uno de sus estados, estadísticas de Bluetooth, etc. Estos datos son generales del teléfono y no propios de cada aplicación. Cada una de estas pestañas son Fragments contenidos en un ViewPager. Se indica el nombre de la pestaña mediante dos Tabs en la parte superior que indica el Fragment en el que te encuentras. Estos Fragment se encuentran contenidos en la Activity principal de la aplicación. Esta Activity tiene un menú en su parte superior en el que se puede ejecutar la acción de realizar el test automático de lectura de batería. En la Figura 6.1 se puede ver la interfaz de la aplicación.. (a) Consumos. (b) Estadísticas. Figura 6.1: Apariencia de la aplicación.. Para obtener más información acerca del consumo de una aplicación o un servicio del sistema en concreto, el usuario puede hacer click sobre la lista de consumos en el.
(53) 6.3. Detector de consumos. 29. item que quiera ver en detalle. Este click hace que se abra una nueva Activity con el consumo total desgregado en los distintos tipos de consumo, además de estadísticas propias de esa aplicación. En la barra superior aparecerá el nombre de la aplicación sobre la que se ha hecho click. Al lado del tipo de consumo aparece un símbolo de interrogación en el que el usuario puede hacer click, y de esta forma le salta un aviso explicando el tipo de consumo. Un ejemplo se puede ver en la Figura 6.2. (a) Detalle. (b) Alerta. Figura 6.2: Apariencia de la Activity de detalle.. 6.3.. Detector de consumos. Uno de los requisitos especificados por el cliente era la posibilidad de obtener feedback de la descarga de la batería. La primera fase de este proceso se comentó en el apartado de Diseño 5.2, y consistió en el estudio de los informes bugreport reportados por usuarios de los terminales de BQ. Este estudio buscaba encontrar patrones en los informes que permitiera decidir cuando un ciclo de descarga de batería se podía considerar normal. La estimación de si la batería ha durado lo que debería no es trivial, y sobre todo, es muy ambigua..
(54) 30. Capítulo 6. Implementación. Existen muchos factores que participan en que el teléfono consuma. Por tanto, se desestimó que la aplicación tuviera la capacidad de decidir sobre si la descarga había sido correcta. Sin embargo, se procedió a estudiar los factores que más afectan y a establecer unos umbrales mínimos por encima de los cuales se considera demasiado su consumo. Estos umbrales se han definido para cada uno de los componentes que más consumen. Se han declarado tres tipos de umbrales debido a la naturaleza de algunos componentes: Umbral de tiempo: Se define el tiempo máximo que debe estar ese componente funcionando para considerarse excesivo su consumo. Umbral de número de ocurrencia: Se define el número de veces máximo que ese componente puede iniciarse para considerarse excesivo su consumo. Umbral de información intercambiada: Se define el número de MB (Mega Byte) intercambiado por Wi-Fi considerado normal en un cierto tiempo. A continuación se enumeran los consumos que se ha decidido alertar sobre su uso: Pantalla: Es el componente que más consume, y el que los usuarios más tienen en cuenta. Su uso depende directamente del uso del terminal. A partir de los informes, se ha estimado que para una descarga de 24 horas de duración, la pantalla debería estar encendida entre 3 y 4 horas. Si en una descarga de 24 horas las horas de pantalla son inferiores a 2 horas, quiere decir que ha existido un consumo muy alto cuando el dispositivo se encontraba en reposo, algo que no debería ocurrir. Si esto ha ocurrido debería aparecer una alerta sobre aplicaciones actuando en segundo plano durante largo tiempo ó wakelocks que no han permitido entrar en reposo a la CPU. Wakelocks: Como se comentó en 5.2, un wakelock es un proceso que despierta a las CPU de su estado de reposo, y no le permite volver a dormirse hasta que no se libere. A partir de los informes, se ha llegado a la conclusión de que hay dos casos en los que los wakelocks suponen un consumo muy alto. El primero tiene que ver con wakelocks que ocurren muchas veces pero duran muy poco tiempo. Esto supone un consumo muy alto, ya que cuando la CPU se despierta debe alimentar a la memoria RAM, actualizar los registros, en definitiva, recomponer el contexto, y eso supone mucho esfuerzo. Estos picos de consumo ocurren solo durante milisegundos, pero repetidas veces por minuto hace que su consumo sea importante. El segundo es justo al revés. Es decir, hay otros wakelocks que ocurren muy pocas veces pero que duran mucho tiempo y por tanto no permiten a la CPU entrar en.
(55) 6.3. Detector de consumos. 31. modo reposo. Según funciona Android, se diferencia dos orígenes de wakelocks. Los wakelocks de espacio de usuario y los del kernel. Ambos tienen el funcionamiento presentado anteriormente, y por tanto, se deben establecer umbrales tanto en términos de tiempo como en número de ocurrencias. Redes móviles: Aunque es conocido el problema de Android con el cálculo del consumo en redes móviles, como se explicó en 4.2, se ha establecido un umbral de tiempo para avisar si una aplicación ha estado mucho tiempo transmitiendo o recibiendo información. Wi-Fi: Debido al problema en el cálculo del consumo Wi-Fi de Android explicado en 4.3, aunque una aplicación intercambie muchos datos vía Wi-Fi es difícil saberlo en términos de su consumo. Por tanto, no se puede abordar el umbral en base al consumo y se decide establecer un umbral en términos de información intercambiada. Además se establece un umbral para el tiempo que cada aplicación ha estado escaneando en busca de AP. GPS: Se establece un umbral de tiempo para indicar que ha habido un consumo elevado de GPS. Cámara: Se establece un umbral de tiempo para indicar que ha habido un consumo elevado de cámara. Flash: Se establece un umbral de tiempo para indicar que ha habido un consumo elevado de flash de la cámara. Los umbrales de cada uno de los consumos se deben definir para cada smartphone en el que se vaya a usar la aplicación. Esto es debido a que el firmware y el hardware de cada uno es distinto, y los umbrales pueden variar. Por tanto, se debe realizar un estudio anterior a la instalación de la aplicación en el dispositivo. Para la realización de este TFG se han calculado los umbrales para el smartphone BQ Aquaris M5. La ejecución de este detector de consumos se ejecuta desde el menú de la MainActivity. Un ejemplo de la salida que produce se puede ver en la Figura 6.3. Esta salida se muestra mediante un Dialog que presenta el informe sobre el consumo de la batería. El informe presentado al usuario en la Figura 6.3 informa acerca de los consumos que han superado los umbrales definidos. Cabe destacar los siguientes puntos a partir de dicho informe: No aparece el consumo debido a la pantalla, por lo que se puede considerar correcto..
(56) 32. Capítulo 6. Implementación. La aparición del consumo de redes móviles indica que ha superado el umbral de estar intercambiando información durante más de una hora. Las aplicaciones Servicios de Google Play y Whatsapp son las únicas que han estado intercambiando información durante más de veinte minutos. Ha habido un Kernel wakelock que ha durado más del umbral definido de una hora de duración. Este wakelock ha sido PowerManagerService y ha ocurrido 7795 veces. Ha habido un Kernel wakelock que ha ocurrido más veces que el umbral definido de 25000 veces. Este wakelock ha sido eventpoll y ha ocurrido 40133 veces. Su duración no es de cero segundos, sino de algunos milisegundos. Ha habido un User space wakelock que ha durado más del umbral definido de cuarenta minutos de duración. Este wakelock ha ocurrido seis veces y su identificador es AutoSignInAndSyncJobService.. Figura 6.3: Detector de consumos. Estos resultados del informe nos avisan de que el usuario ha usado durante varias horas la aplicación Whatsapp y que la aplicación de Servicios de Google Play no está optimizada como debería. Los wakelocks emitidos por el Kernel en principio son normales, superan el umbral pero no suponen un consumo elevado. PowerManagerService es el encargado de bloquear y desbloquear el terminal, por lo que si el usuario constantemente bloquea y desbloquea es normal que aparezca. Por.
(57) 6.4. Arquitectura. 33. otra parte, eventpoll ha ocurrido un número bastante alto de veces, pero es un wakelock que se encarga de las redes móviles, y como hemos podido ver el usuario ha utilizado bastante dicha conectividad. AutoSignInAndSyncJobService ha estado activo durante bastante tiempo, ya que su principal función es verificar la identidad del usuario, y eso no debería llevar más que milisegundos.. 6.4.. Arquitectura. La tarea de escribir software de calidad es una tarea dura y compleja. No solo debe cumplir con los requisitos pedidos por el cliente, también debe ser robusto, mantenible, testable, y lo suficientemente flexible para adaptarse a cambios y crecimiento en la aplicación. Existen muchas arquitecturas que se adaptan a estos principios fundamentales. Algunos ejemplos pueden ser la Arquitectura Hexagonal [12], Onion Architecture [13] ó Clean Architecture [14]. Todas estas arquitecturas siguen unos principios comunes: Independencia del Framework. No depender del código de la plataforma para la que estés desarrollando. Código testable. Independencia de la interfaz de usuario. Independencia del origen de datos. Independencia de librerías de terceros. La arquitectura elegida para implementar en la aplicación es Clean Architecture. La elección de usar Clean Architecture es porque dentro de las arquitecturas presentadas anteriormente es la más sencilla, y su implementación más rápida. Los principios fundamentales de ésta se deben explicar siguiendo la Figura 6.4.. Figura 6.4: Regla de dependencia Clean Architecture. Las dependencias en el código fuente sólo pueden apuntar hacia adentro. Los círculos interiores no pueden saber nada de los círculos exteriores. Así se consigue una.
(58) 34. Capítulo 6. Implementación. independencia del framework y total independencia entre las distintas capas. El código se apoya en abstracciones y no en concrecciones, lo que hace posible la separación entre capas. Esto hace posible que se cumplan los principios comentados anteriormente. Un claro ejemplo es que la capa de UI (User Interface, Interfaz de Usuario) depende de la capa presenter, pero no al revés. De esa forma, si se quiere cambiar la interfaz de usuario, el resto de capas no tiene porque enterarse, ya que para ellos es invisible. La capa del presenter avisará a la de UI sobre lo que debe pintar, pero a éste le da igual como lo haga. La arquitectura de la aplicación se puede ver en la Figura 6.5. El color azul representa la capa de UI, el verde la capa de los presenter y el rojo es la capa de los casos de uso o use case. La capa entities se ha separado en dos capas distintas, la primera en morado es la capa repository y la segunda en amarillo es la capa del origen de datos o data source. Como se ha comentado anteriormente, la comunicación entre capas es siempre hacia dentro. La forma más visual de entender esto, siguiendo la Figura 6.5, es que todas las líneas entre capas van hacia la derecha, es decir, hacia capas interiores. El código está desacoplado y permite depender de abstracciones que pueden ser sustituidas fácilmente. Las únicas líneas que no van hacia la derecha son las de la capa de UI. Esto es permisible porque están en la misma capa, y además, como se ha comentado antes, los Fragment se encuentra contenidos en la Activity principal por lo que tiene sentido que exista esa dependencia. Siendo purista con la teoría de The Clean Architecture, por cada vista presentada al usuario (Activity, Fragment) debe haber al menos un presenter. En el caso de la MainActivity como la lógica es muy sencilla, se ha obviado y se ha saltado una capa que en este caso no suponía una ayuda.. Figura 6.5: Arquitectura de la aplicación. La separación de la capa entities en dos distintas permite aislarnos del origen de los.
Documento similar