summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStream.java
blob: d1c3f591691d60bd6af74e498c2a4d5f16ffa98d (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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* -*- 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.activitystream;

import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.text.TextUtils;

import com.keepsafe.switchboard.SwitchBoard;

import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.Experiments;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.publicsuffix.PublicSuffix;

import java.util.Arrays;
import java.util.List;

public class ActivityStream {
    /**
     * List of undesired prefixes for labels based on a URL.
     *
     * This list is by no means complete and is based on those sources:
     * - https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
     * - https://github.com/mozilla/activity-stream/issues/1311
     */
    private static final List<String> UNDESIRED_LABEL_PREFIXES = Arrays.asList(
            "index.",
            "home."
    );

    /**
     * Undesired labels for labels based on a URL.
     *
     * This list is by no means complete and is based on those sources:
     * - https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
     * - https://github.com/mozilla/activity-stream/issues/1311
     */
    private static final List<String> UNDESIRED_LABELS = Arrays.asList(
            "render",
            "login",
            "edit"
    );

    public static boolean isEnabled(Context context) {
        if (!isUserEligible(context)) {
            // If the user is not eligible then disable activity stream. Even if it has been
            //  enabled before.
            return false;
        }

        return GeckoSharedPrefs.forApp(context)
                .getBoolean(GeckoPreferences.PREFS_ACTIVITY_STREAM, false);
    }

    /**
     * Is the user eligible to use activity stream or should we hide it from settings etc.?
     */
    public static boolean isUserEligible(Context context) {
        if (AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
            // If the build flag is enabled then just show the option to the user.
            return true;
        }

        if (AppConstants.NIGHTLY_BUILD && SwitchBoard.isInExperiment(context, Experiments.ACTIVITY_STREAM)) {
            // If this is a nightly build and the user is part of the activity stream experiment then
            // the option should be visible too. The experiment is limited to Nightly too but I want
            // to make really sure that this isn't riding the trains accidentally.
            return true;
        }

        // For everyone else activity stream is not available yet.
        return false;
    }

    /**
     * Query whether we want to display Activity Stream as a Home Panel (within the HomePager),
     * or as a HomePager replacement.
     */
    public static boolean isHomePanel() {
        return true;
    }

    /**
     * Extract a label from a URL to use in Activity Stream.
     *
     * This method implements the proposal from this desktop AS issue:
     * https://github.com/mozilla/activity-stream/issues/1311
     *
     * @param usePath Use the path of the URL to extract a label (if suitable)
     */
    public static void extractLabel(final Context context, final String url, final boolean usePath, final LabelCallback callback) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                if (TextUtils.isEmpty(url)) {
                    return "";
                }

                final Uri uri = Uri.parse(url);

                // Use last path segment if suitable
                if (usePath) {
                    final String segment = uri.getLastPathSegment();
                    if (!TextUtils.isEmpty(segment)
                            && !UNDESIRED_LABELS.contains(segment)
                            && !segment.matches("^[0-9]+$")) {

                        boolean hasUndesiredPrefix = false;
                        for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
                            if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
                                hasUndesiredPrefix = true;
                                break;
                            }
                        }

                        if (!hasUndesiredPrefix) {
                            return segment;
                        }
                    }
                }

                // If no usable path segment was found then use the host without public suffix and common subdomains
                final String host = uri.getHost();
                if (TextUtils.isEmpty(host)) {
                    return url;
                }

                return StringUtils.stripCommonSubdomains(
                        PublicSuffix.stripPublicSuffix(context, host));
            }

            @Override
            protected void onPostExecute(String label) {
                callback.onLabelExtracted(label);
            }
        }.execute();
    }

    public abstract static class LabelCallback {
        public abstract void onLabelExtracted(String label);
    }
}