summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/icons/IconDescriptorComparator.java
blob: 3c6064825aebea1e8675879fc5d9ced9001403dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko.icons;

import java.util.Comparator;

/**
 * This comparator implementation compares IconDescriptor objects in order to determine which icon
 * to load first.
 *
 * In general this comparator will try touch icons before favicons (they usually have a higher resolution)
 * and prefers larger icons over smaller ones.
 */
/* package-private */ class IconDescriptorComparator implements Comparator<IconDescriptor> {
    @Override
    public int compare(final IconDescriptor lhs, final IconDescriptor rhs) {
        if (lhs.getUrl().equals(rhs.getUrl())) {
            // Two descriptors pointing to the same URL are always referencing the same icon. So treat
            // them as equal.
            return 0;
        }

        // First compare the types. We prefer touch icons because they tend to have a higher resolution
        // than ordinary favicons.
        if (lhs.getType() != rhs.getType()) {
            return compareType(lhs, rhs);
        }

        // If one of them is larger than pick the larger icon.
        if (lhs.getSize() != rhs.getSize()) {
            return compareSizes(lhs, rhs);
        }

        // If there's no other way to choose, we prefer container types. They *might* contain
        // an image larger than the size given in the <link> tag.
        final boolean lhsContainer = IconsHelper.isContainerType(lhs.getMimeType());
        final boolean rhsContainer = IconsHelper.isContainerType(rhs.getMimeType());

        if (lhsContainer != rhsContainer) {
            return lhsContainer ? -1 : 1;
        }

        // There's no way to know which icon might be better. However we need to pick a consistent
        // one to avoid breaking the TreeSet implementation (See Bug 1331808). Therefore we are
        // picking one by just comparing the URLs.
        return lhs.getUrl().compareTo(rhs.getUrl());
    }

    private int compareType(IconDescriptor lhs, IconDescriptor rhs) {
        if (lhs.getType() > rhs.getType()) {
            return -1;
        } else {
            return 1;
        }
    }

    private int compareSizes(IconDescriptor lhs, IconDescriptor rhs) {
        if (lhs.getSize() > rhs.getSize()) {
            return -1;
        } else {
            return 1;
        }
    }
}