1package com.bumptech.glide.signature;
2
3import android.content.Context;
4import android.content.pm.PackageInfo;
5import android.content.pm.PackageManager;
6
7import com.bumptech.glide.load.Key;
8
9import java.util.UUID;
10import java.util.concurrent.ConcurrentHashMap;
11
12/**
13 * A utility class for obtaining a {@link com.bumptech.glide.load.Key} signature containing the application version
14 * name using {@link android.content.pm.PackageInfo#versionCode}.
15 */
16public final class ApplicationVersionSignature {
17    private static final ConcurrentHashMap<String, Key> PACKAGE_NAME_TO_KEY = new ConcurrentHashMap<String, Key>();
18
19    /**
20     * Returns the signature {@link com.bumptech.glide.load.Key} for version code of the Application of the given
21     * Context.
22     */
23    public static Key obtain(Context context) {
24        String packageName = context.getPackageName();
25        Key result = PACKAGE_NAME_TO_KEY.get(packageName);
26        if (result == null) {
27            Key toAdd = obtainVersionSignature(context);
28            result = PACKAGE_NAME_TO_KEY.putIfAbsent(packageName, toAdd);
29            // There wasn't a previous mapping, so toAdd is now the Key.
30            if (result == null) {
31                result = toAdd;
32            }
33        }
34
35        return result;
36    }
37
38    // Visible for testing.
39    static void reset() {
40        PACKAGE_NAME_TO_KEY.clear();
41    }
42
43    private static Key obtainVersionSignature(Context context) {
44        PackageInfo pInfo = null;
45        try {
46            pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
47        } catch (PackageManager.NameNotFoundException e) {
48            // Should never happen.
49            e.printStackTrace();
50        }
51        final String versionCode;
52        if (pInfo != null) {
53            versionCode = String.valueOf(pInfo.versionCode);
54        } else {
55            versionCode = UUID.randomUUID().toString();
56        }
57        return new StringSignature(versionCode);
58    }
59
60    private ApplicationVersionSignature() {
61        // Empty for visibility.
62    }
63}
64