Home | History | Annotate | Download | only in model
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may 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 implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.work.impl.model;
     18 
     19 import static androidx.work.BackoffPolicy.EXPONENTIAL;
     20 import static androidx.work.BackoffPolicy.LINEAR;
     21 import static androidx.work.State.BLOCKED;
     22 import static androidx.work.State.CANCELLED;
     23 import static androidx.work.State.ENQUEUED;
     24 import static androidx.work.State.FAILED;
     25 import static androidx.work.State.RUNNING;
     26 import static androidx.work.State.SUCCEEDED;
     27 
     28 import android.arch.persistence.room.TypeConverter;
     29 import android.net.Uri;
     30 
     31 import androidx.work.BackoffPolicy;
     32 import androidx.work.ContentUriTriggers;
     33 import androidx.work.NetworkType;
     34 import androidx.work.State;
     35 
     36 import java.io.ByteArrayInputStream;
     37 import java.io.ByteArrayOutputStream;
     38 import java.io.IOException;
     39 import java.io.ObjectInputStream;
     40 import java.io.ObjectOutputStream;
     41 
     42 /**
     43  * TypeConverters for WorkManager enums and classes.
     44  */
     45 
     46 public class WorkTypeConverters {
     47 
     48     /**
     49      * Integer identifiers that map to {@link State}.
     50      */
     51     public interface StateIds {
     52         int ENQUEUED = 0;
     53         int RUNNING = 1;
     54         int SUCCEEDED = 2;
     55         int FAILED = 3;
     56         int BLOCKED = 4;
     57         int CANCELLED = 5;
     58 
     59         String COMPLETED_STATES = "(" + SUCCEEDED + ", " + FAILED + ", " + CANCELLED + ")";
     60     }
     61 
     62     /**
     63      * Integer identifiers that map to {@link BackoffPolicy}.
     64      */
     65     public interface BackoffPolicyIds {
     66         int EXPONENTIAL = 0;
     67         int LINEAR = 1;
     68     }
     69 
     70     /**
     71      * Integer identifiers that map to {@link NetworkType}.
     72      */
     73     public interface NetworkTypeIds {
     74         int NOT_REQUIRED = 0;
     75         int CONNECTED = 1;
     76         int UNMETERED = 2;
     77         int NOT_ROAMING = 3;
     78         int METERED = 4;
     79     }
     80 
     81     /**
     82      * TypeConverter for a State to an int.
     83      *
     84      * @param state The input State
     85      * @return The associated int constant
     86      */
     87     @TypeConverter
     88     public static int stateToInt(State state) {
     89         switch (state) {
     90             case ENQUEUED:
     91                 return StateIds.ENQUEUED;
     92 
     93             case RUNNING:
     94                 return StateIds.RUNNING;
     95 
     96             case SUCCEEDED:
     97                 return StateIds.SUCCEEDED;
     98 
     99             case FAILED:
    100                 return StateIds.FAILED;
    101 
    102             case BLOCKED:
    103                 return StateIds.BLOCKED;
    104 
    105             case CANCELLED:
    106                 return StateIds.CANCELLED;
    107 
    108             default:
    109                 throw new IllegalArgumentException(
    110                         "Could not convert " + state + " to int");
    111         }
    112     }
    113 
    114     /**
    115      * TypeConverter for an int to a State.
    116      *
    117      * @param value The input integer
    118      * @return The associated State enum value
    119      */
    120     @TypeConverter
    121     public static State intToState(int value) {
    122         switch (value) {
    123             case StateIds.ENQUEUED:
    124                 return ENQUEUED;
    125 
    126             case StateIds.RUNNING:
    127                 return RUNNING;
    128 
    129             case StateIds.SUCCEEDED:
    130                 return SUCCEEDED;
    131 
    132             case StateIds.FAILED:
    133                 return FAILED;
    134 
    135             case StateIds.BLOCKED:
    136                 return BLOCKED;
    137 
    138             case StateIds.CANCELLED:
    139                 return CANCELLED;
    140 
    141             default:
    142                 throw new IllegalArgumentException(
    143                         "Could not convert " + value + " to State");
    144         }
    145     }
    146 
    147     /**
    148      * TypeConverter for a BackoffPolicy to an int.
    149      *
    150      * @param backoffPolicy The input BackoffPolicy
    151      * @return The associated int constant
    152      */
    153     @TypeConverter
    154     public static int backoffPolicyToInt(BackoffPolicy backoffPolicy) {
    155         switch (backoffPolicy) {
    156             case EXPONENTIAL:
    157                 return BackoffPolicyIds.EXPONENTIAL;
    158 
    159             case LINEAR:
    160                 return BackoffPolicyIds.LINEAR;
    161 
    162             default:
    163                 throw new IllegalArgumentException(
    164                         "Could not convert " + backoffPolicy + " to int");
    165         }
    166     }
    167 
    168     /**
    169      * TypeConverter for an int to a BackoffPolicy.
    170      *
    171      * @param value The input integer
    172      * @return The associated BackoffPolicy enum value
    173      */
    174     @TypeConverter
    175     public static BackoffPolicy intToBackoffPolicy(int value) {
    176         switch (value) {
    177             case BackoffPolicyIds.EXPONENTIAL:
    178                 return EXPONENTIAL;
    179 
    180             case BackoffPolicyIds.LINEAR:
    181                 return LINEAR;
    182 
    183             default:
    184                 throw new IllegalArgumentException(
    185                         "Could not convert " + value + " to BackoffPolicy");
    186         }
    187     }
    188 
    189     /**
    190      * TypeConverter for a NetworkType to an int.
    191      *
    192      * @param networkType The input NetworkType
    193      * @return The associated int constant
    194      */
    195     @TypeConverter
    196     public static int networkTypeToInt(NetworkType networkType) {
    197         switch (networkType) {
    198             case NOT_REQUIRED:
    199                 return NetworkTypeIds.NOT_REQUIRED;
    200 
    201             case CONNECTED:
    202                 return NetworkTypeIds.CONNECTED;
    203 
    204             case UNMETERED:
    205                 return NetworkTypeIds.UNMETERED;
    206 
    207             case NOT_ROAMING:
    208                 return NetworkTypeIds.NOT_ROAMING;
    209 
    210             case METERED:
    211                 return NetworkTypeIds.METERED;
    212 
    213             default:
    214                 throw new IllegalArgumentException(
    215                         "Could not convert " + networkType + " to int");
    216         }
    217     }
    218 
    219     /**
    220      * TypeConverter for an int to a NetworkType.
    221      *
    222      * @param value The input integer
    223      * @return The associated NetworkType enum value
    224      */
    225     @TypeConverter
    226     public static NetworkType intToNetworkType(int value) {
    227         switch (value) {
    228             case NetworkTypeIds.NOT_REQUIRED:
    229                 return NetworkType.NOT_REQUIRED;
    230 
    231             case NetworkTypeIds.CONNECTED:
    232                 return NetworkType.CONNECTED;
    233 
    234             case NetworkTypeIds.UNMETERED:
    235                 return NetworkType.UNMETERED;
    236 
    237             case NetworkTypeIds.NOT_ROAMING:
    238                 return NetworkType.NOT_ROAMING;
    239 
    240             case NetworkTypeIds.METERED:
    241                 return NetworkType.METERED;
    242 
    243             default:
    244                 throw new IllegalArgumentException(
    245                         "Could not convert " + value + " to NetworkType");
    246         }
    247     }
    248 
    249     /**
    250      * Converts a list of {@link ContentUriTriggers.Trigger}s to byte array representation
    251      * @param triggers the list of {@link ContentUriTriggers.Trigger}s to convert
    252      * @return corresponding byte array representation
    253      */
    254     @TypeConverter
    255     public static byte[] contentUriTriggersToByteArray(ContentUriTriggers triggers) {
    256         if (triggers.size() == 0) {
    257             // Return null for no triggers. Needed for SQL query check in ForegroundProcessor
    258             return null;
    259         }
    260         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    261         ObjectOutputStream objectOutputStream = null;
    262         try {
    263             objectOutputStream = new ObjectOutputStream(outputStream);
    264             objectOutputStream.writeInt(triggers.size());
    265             for (ContentUriTriggers.Trigger trigger : triggers) {
    266                 objectOutputStream.writeUTF(trigger.getUri().toString());
    267                 objectOutputStream.writeBoolean(trigger.shouldTriggerForDescendants());
    268             }
    269         } catch (IOException e) {
    270             e.printStackTrace();
    271         } finally {
    272             if (objectOutputStream != null) {
    273                 try {
    274                     objectOutputStream.close();
    275                 } catch (IOException e) {
    276                     e.printStackTrace();
    277                 }
    278             }
    279             try {
    280                 outputStream.close();
    281             } catch (IOException e) {
    282                 e.printStackTrace();
    283             }
    284         }
    285         return outputStream.toByteArray();
    286     }
    287 
    288     /**
    289      * Converts a byte array to list of {@link ContentUriTriggers.Trigger}s
    290      * @param bytes byte array representation to convert
    291      * @return list of {@link ContentUriTriggers.Trigger}s
    292      */
    293     @TypeConverter
    294     public static ContentUriTriggers byteArrayToContentUriTriggers(byte[] bytes) {
    295         ContentUriTriggers triggers = new ContentUriTriggers();
    296         if (bytes == null) {
    297             // bytes will be null if there are no Content Uri Triggers
    298             return triggers;
    299         }
    300         ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    301         ObjectInputStream objectInputStream = null;
    302         try {
    303             objectInputStream = new ObjectInputStream(inputStream);
    304             for (int i = objectInputStream.readInt(); i > 0; i--) {
    305                 Uri uri = Uri.parse(objectInputStream.readUTF());
    306                 boolean triggersForDescendants = objectInputStream.readBoolean();
    307                 triggers.add(uri, triggersForDescendants);
    308             }
    309         } catch (IOException e) {
    310             e.printStackTrace();
    311         } finally {
    312             if (objectInputStream != null) {
    313                 try {
    314                     objectInputStream.close();
    315                 } catch (IOException e) {
    316                     e.printStackTrace();
    317                 }
    318             }
    319             try {
    320                 inputStream.close();
    321             } catch (IOException e) {
    322                 e.printStackTrace();
    323             }
    324         }
    325         return triggers;
    326     }
    327 
    328     private WorkTypeConverters() {
    329     }
    330 }
    331