Home | History | Annotate | Download | only in entity
      1 /*
      2  * Copyright (c) 2017 Google Inc. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you
      5  * may not use this file except in compliance with the License. You may
      6  * obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
     13  * implied. See the License for the specific language governing
     14  * permissions and limitations under the License.
     15  */
     16 
     17 package com.android.vts.entity;
     18 
     19 import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage;
     20 import com.google.appengine.api.datastore.Entity;
     21 import com.google.appengine.api.datastore.Key;
     22 import java.util.logging.Level;
     23 import java.util.logging.Logger;
     24 
     25 /** Class describing a device used for a test run. */
     26 public class DeviceInfoEntity implements DashboardEntity {
     27     protected static final Logger logger = Logger.getLogger(DeviceInfoEntity.class.getName());
     28 
     29     public static final String KIND = "DeviceInfo";
     30 
     31     // Property keys
     32     public static final String BRANCH = "branch";
     33     public static final String PRODUCT = "product";
     34     public static final String BUILD_FLAVOR = "buildFlavor";
     35     public static final String BUILD_ID = "buildId";
     36     public static final String ABI_BITNESS = "abiBitness";
     37     public static final String ABI_NAME = "abiName";
     38 
     39     private final Key parentKey;
     40 
     41     public final String branch;
     42     public final String product;
     43     public final String buildFlavor;
     44     public final String buildId;
     45     public final String abiBitness;
     46     public final String abiName;
     47 
     48     /**
     49      * Create a DeviceInfoEntity object.
     50      *
     51      * @param parentKey The key for the parent entity in the database.
     52      * @param branch The build branch.
     53      * @param product The device product.
     54      * @param buildFlavor The device build flavor.
     55      * @param buildID The device build ID.
     56      * @param abiBitness The abi bitness of the device.
     57      * @param abiName The name of the abi.
     58      */
     59     public DeviceInfoEntity(Key parentKey, String branch, String product, String buildFlavor,
     60             String buildID, String abiBitness, String abiName) {
     61         this.parentKey = parentKey;
     62         this.branch = branch;
     63         this.product = product;
     64         this.buildFlavor = buildFlavor;
     65         this.buildId = buildID;
     66         this.abiBitness = abiBitness;
     67         this.abiName = abiName;
     68     }
     69 
     70     @Override
     71     public Entity toEntity() {
     72         Entity deviceEntity = new Entity(KIND, this.parentKey);
     73         deviceEntity.setProperty(BRANCH, this.branch.toLowerCase());
     74         deviceEntity.setProperty(PRODUCT, this.product.toLowerCase());
     75         deviceEntity.setProperty(BUILD_FLAVOR, this.buildFlavor.toLowerCase());
     76         deviceEntity.setProperty(BUILD_ID, this.buildId.toLowerCase());
     77         if (this.abiBitness != null && this.abiName != null) {
     78             deviceEntity.setUnindexedProperty(ABI_BITNESS, this.abiBitness.toLowerCase());
     79             deviceEntity.setUnindexedProperty(ABI_NAME, this.abiName.toLowerCase());
     80         }
     81 
     82         return deviceEntity;
     83     }
     84 
     85     /**
     86      * Convert an Entity object to a DeviceInfoEntity.
     87      *
     88      * @param e The entity to process.
     89      * @return DeviceInfoEntity object with the properties from e, or null if incompatible.
     90      */
     91     public static DeviceInfoEntity fromEntity(Entity e) {
     92         if (!e.getKind().equals(KIND) || !e.hasProperty(BRANCH) || !e.hasProperty(PRODUCT)
     93                 || !e.hasProperty(BUILD_FLAVOR) || !e.hasProperty(BUILD_ID)
     94                 || !e.hasProperty(ABI_BITNESS) || !e.hasProperty(ABI_NAME)) {
     95             logger.log(Level.WARNING, "Missing device info attributes in entity: " + e.toString());
     96             return null;
     97         }
     98         try {
     99             Key parentKey = e.getKey().getParent();
    100             String branch = (String) e.getProperty(BRANCH);
    101             String product = (String) e.getProperty(PRODUCT);
    102             String buildFlavor = (String) e.getProperty(BUILD_FLAVOR);
    103             String buildId = (String) e.getProperty(BUILD_ID);
    104             String abiBitness = null;
    105             String abiName = null;
    106             if (e.hasProperty(ABI_BITNESS) && e.hasProperty(ABI_NAME)) {
    107                 abiBitness = (String) e.getProperty(ABI_BITNESS);
    108                 abiName = (String) e.getProperty(ABI_NAME);
    109             }
    110             return new DeviceInfoEntity(
    111                     parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName);
    112         } catch (ClassCastException exception) {
    113             // Invalid cast
    114             logger.log(Level.WARNING, "Error parsing device info entity.", exception);
    115         }
    116         return null;
    117     }
    118 
    119     /**
    120      * Convert a device info message to a DeviceInfoEntity.
    121      *
    122      * @param parentKey The ancestor key for the device entity.
    123      * @param device The device info report describing the target Android device.
    124      * @return The DeviceInfoEntity for the target device, or null if incompatible
    125      */
    126     public static DeviceInfoEntity fromDeviceInfoMessage(
    127             Key parentKey, AndroidDeviceInfoMessage device) {
    128         if (!device.hasBuildAlias() || !device.hasBuildFlavor() || !device.hasProductVariant()
    129                 || !device.hasBuildId()) {
    130             return null;
    131         }
    132         String branch = device.getBuildAlias().toStringUtf8();
    133         String buildFlavor = device.getBuildFlavor().toStringUtf8();
    134         String product = device.getProductVariant().toStringUtf8();
    135         String buildId = device.getBuildId().toStringUtf8();
    136         String abiBitness = device.getAbiBitness().toStringUtf8();
    137         String abiName = device.getAbiName().toStringUtf8();
    138         return new DeviceInfoEntity(
    139                 parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName);
    140     }
    141 
    142     @Override
    143     public boolean equals(Object obj) {
    144         if (!(obj instanceof DeviceInfoEntity)) {
    145             return false;
    146         }
    147         DeviceInfoEntity device2 = (DeviceInfoEntity) obj;
    148         if (!this.branch.equals(device2.branch) || !this.product.equals(device2.product)
    149                 || !this.buildFlavor.equals(device2.buildFlavor)
    150                 || !this.buildId.equals(device2.buildId)) {
    151             return false;
    152         }
    153         return true;
    154     }
    155 
    156     @Override
    157     public int hashCode() {
    158         String deviceId = this.branch + this.product + this.buildFlavor + this.buildId;
    159         return deviceId.hashCode();
    160     }
    161 
    162     /**
    163      * Create a copy of the device info under a near parent.
    164      * @param parentKey The new parent key.
    165      * @return A copy of the DeviceInfoEntity with the specified parent.
    166      */
    167     public DeviceInfoEntity copyWithParent(Key parentKey) {
    168         return new DeviceInfoEntity(parentKey, this.branch, this.product, this.buildFlavor,
    169                 this.buildId, this.abiBitness, this.abiName);
    170     }
    171 
    172     /**
    173      * Create a string representation of the device build information.
    174      * @return A String fingerprint of the format: branch/buildFlavor (build ID)
    175      */
    176     public String getFingerprint() {
    177         return this.branch + "/" + this.buildFlavor + " (" + this.buildId + ")";
    178     }
    179 }
    180