Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2017 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.utils;
     18 
     19 import android.content.Context;
     20 import android.content.SharedPreferences;
     21 import android.support.annotation.RestrictTo;
     22 
     23 /**
     24  * Generates unique IDs that are persisted in {@link SharedPreferences}.
     25  *
     26  * @hide
     27  */
     28 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     29 public class IdGenerator {
     30 
     31     /** The initial id used for JobInfos, Firebase Jobs & and Alarms. */
     32     public static final int INITIAL_ID = 0;
     33 
     34     static final String PREFERENCE_FILE_KEY = "androidx.work.util.id";
     35     static final String NEXT_JOB_SCHEDULER_ID_KEY = "next_job_scheduler_id";
     36     static final String NEXT_FIREBASE_ALARM_ID_KEY = "next_firebase_alarm_id";
     37     static final String NEXT_ALARM_MANAGER_ID_KEY = "next_alarm_manager_id";
     38 
     39     private SharedPreferences mSharedPrefs;
     40 
     41     /**
     42      * Constructs a {@link IdGenerator}.
     43      *
     44      * @param context {@link Context} to get the {@link SharedPreferences} from.
     45      */
     46     public IdGenerator(Context context) {
     47         mSharedPrefs = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
     48     }
     49 
     50     /**
     51      * Generates IDs for {@link android.app.job.JobInfo} jobs given a reserved range.
     52      */
     53     public int nextJobSchedulerIdWithRange(int minInclusive, int maxInclusive) {
     54         synchronized (IdGenerator.class) {
     55             int id = nextId(NEXT_JOB_SCHEDULER_ID_KEY);
     56             if (id < minInclusive || id > maxInclusive) {
     57                 // outside the range, re-start at minInclusive.
     58                 id = minInclusive;
     59                 update(NEXT_JOB_SCHEDULER_ID_KEY, id + 1);
     60             }
     61             return id;
     62         }
     63     }
     64 
     65     /**
     66      * Generates IDs for Firebase Delayed Alarm Receiver jobs.
     67      */
     68     public int nextFirebaseAlarmId() {
     69         synchronized (IdGenerator.class) {
     70             return nextId(NEXT_FIREBASE_ALARM_ID_KEY);
     71         }
     72     }
     73 
     74     /**
     75      * Generates IDs for {@link android.app.AlarmManager} work.
     76      */
     77     public int nextAlarmManagerId() {
     78         synchronized (IdGenerator.class) {
     79             return nextId(NEXT_ALARM_MANAGER_ID_KEY);
     80         }
     81     }
     82 
     83     /**
     84      * Returns the next available ID based on a persisted counter.
     85      * Resets ID counter to 0 when the ID exceeded {@link Integer#MAX_VALUE}.
     86      * @param key String matching the particular counter to retrieve
     87      * @return next available id
     88      */
     89     private int nextId(String key) {
     90         int id = mSharedPrefs.getInt(key, INITIAL_ID);
     91         int nextId = (id == Integer.MAX_VALUE) ? INITIAL_ID : id + 1;
     92         update(key, nextId);
     93         return id;
     94     }
     95 
     96     private void update(String key, int value) {
     97         mSharedPrefs.edit().putInt(key, value).apply();
     98     }
     99 }
    100