#!/bin/sh
# This script is a wrapper around Chromium designed to reduce the amount of
# network traffic that is not the result of explicit user interaction. It
# accepts all of the flags that Chromium does but changes some of the default
# values of the flags and also pre-configures the browser's settings if the
# user data directory does not contain a "./Default/Preferences" file.
#
# Normally the script executes the command "chromium" to launch the browser,
# but this can be overridden by passing a command name or executable file as
# the first argument to this script, e.g.:
#
#   ./chromium.sh /opt/development/chromium
#
# Metadata:
# - Author: Eric Pruitt (https://www.codevat.com)
# - License: 2-Clause BSD
set -e -u -o noclobber

# Generate a UUID using "/dev/urandom" and write it to standard output. A
# newline is not added to the end of the UUID.
#
generate_uuid()
{
    for length in 8 4 4 4 12; do
        tr -c -d "0-9a-f" < /dev/urandom | head -c "$length"
        test "$length" -eq "12" || printf "%s" "-"
    done
}

# Dump a preconfigured Chromium preferences file to standard output.
#
preferences()
{
    default_search_provider_guid="$(generate_uuid)"

    cat << ____PREFERENCES_JSON
    {
        "alternate_error_pages": {
            "enabled": false
        },
        "app_launcher": {
            "show_promo": false
        },
        "autofill": {
            "enabled": false
        },
        "browser": {
            "enable_spellchecking": false,
            "has_seen_welcome_page": true
        },
        "default_apps_install_state": 2,
        "default_search_provider": {
            "synced_guid": "$default_search_provider_guid"
        },
        "default_search_provider_data": {
            "template_url_data": {
                "alternate_urls": [],
                "contextual_search_url": "",
                "created_by_policy": false,
                "date_created": "0",
                "favicon_url": "",
                "id": "7",
                "image_url": "",
                "image_url_post_params": "",
                "input_encodings": [],
                "instant_url": "",
                "instant_url_post_params": "",
                "keyword": "file",
                "last_modified": "0",
                "last_visited": "0",
                "new_tab_url": "",
                "originating_url": "",
                "prepopulate_id": 0,
                "safe_for_autoreplace": false,
                "search_terms_replacement_key": "",
                "search_url_post_params": "",
                "short_name": "File",
                "suggestions_url": "",
                "suggestions_url_post_params": "",
                "synced_guid": "$default_search_provider_guid",
                "url": "file:///{searchTerms}/",
                "usage_count": 0
            }
        },
        "extensions": {
            "settings": {
                "nmmhkkegccagdldgiimedpiccmgmieda": {
                    "from_bookmark": false,
                    "location": 10,
                    "manifest": {
                        "description": "Chrome Web Store Payments",
                        "display_in_launcher": false,
                        "display_in_new_tab_page": false,
                        "key": "[payload removed: 216 characters]",
                        "manifest_version": 2,
                        "minimum_chrome_version": "1",
                        "name": "Chrome Web Store Payments",
                        "update_url": "http://0.0.0.1/",
                        "version": "0"
                    },
                    "never_activated_since_loaded": true,
                    "path": "/dev/null",
                    "running": false,
                    "state": 1,
                    "was_installed_by_default": true,
                    "was_installed_by_oem": false
                }
            }
        },
        "net": {
            "network_prediction_options": 2
        },
        "policy": {
            "url_blacklist": [
            ]
        },
        "profile": {
            "block_third_party_cookies": true
        },
        "safebrowsing": {
            "enabled": false
        },
        "search": {
            "suggest_enabled": false
        },
        "spellcheck": {
            "dictionaries": [],
            "dictionary": ""
        },
        "translate": {
            "enabled": false
        }
    }
____PREFERENCES_JSON
}

main()
{
    chromium="chromium"
    user_data_dir="$HOME/.config/chromium"

    if command -v "${1:-}" > /dev/null 2>&1; then
        chromium="$1"
        shift
    fi

    # Chromium requires that flags that accept values have the values
    # immediately after the flag (e.g. "--flag=value" is OK, but "--flag value"
    # is not) which simplifies getting the value of "--user-data-dir" so the
    # script knows where to write the preferences.
    for argument in "$@"; do
        case "$argument" in
          # The "?" is used because Chromium considers treats an empty string
          # as the default directory.
          --user-data-dir=?*)
            user_data_dir="${argument#*=}"
          ;;
          # Stop parsing arguments after encountering "--".
          --)
            break
          ;;
        esac
    done

    if ! [ -e "$user_data_dir/Default/Preferences" ]; then
        mkdir -p "$user_data_dir/Default/"
        preferences > "$user_data_dir/Default/Preferences"
    fi

    exec \
      "${chromium:-chromium}" \
         --disable-background-networking \
         --disable-client-side-phishing-detection \
         --disable-features="NetworkTimeServiceQuerying" \
         --disable-suggestions-service \
         --disable-translate \
         --no-default-browser-check \
         --no-first-run \
         --safebrowsing-disable-download-protection \
         --test-type \
         --translate-security-origin="http://255.255.255.255/" \
         "${@:-}"
}

main "${@:-}"
