summary refs log tree commit diff
path: root/pkgs/applications/networking
diff options
context:
space:
mode:
authorsqualus <squalus@tuta.io>2020-04-13 13:17:05 -0700
committersqualus <squalus@tuta.io>2020-04-13 13:17:05 -0700
commit7205bd64a38d73ff8c46a5bb9d4732da1a26ac02 (patch)
treeef7ef0b1b584256938df23ec8bf94eab339060df /pkgs/applications/networking
parent180ae3d371b5248d6122625758f811796c84207f (diff)
downloadnixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar.gz
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar.bz2
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar.lz
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar.xz
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.tar.zst
nixpkgs-7205bd64a38d73ff8c46a5bb9d4732da1a26ac02.zip
ungoogled-chromium: init at 81.0.4044.92-2
Diffstat (limited to 'pkgs/applications/networking')
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/browser.nix94
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/common.nix361
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/default.nix205
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/dont-use-ANGLE-by-default.patch26
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/nix_plugin_paths_68.patch61
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/no-build-timestamps.patch17
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/remove-webp-include-69.patch11
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/vaapi-fix.patch74
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/patches/widevine-79.patch13
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/plugins.nix93
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled-src.nix6
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled.nix42
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/update.nix271
-rwxr-xr-xpkgs/applications/networking/browsers/ungoogled-chromium/update.sh4
-rw-r--r--pkgs/applications/networking/browsers/ungoogled-chromium/upstream-info.nix18
15 files changed, 1296 insertions, 0 deletions
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/browser.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/browser.nix
new file mode 100644
index 00000000000..87248013a9a
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/browser.nix
@@ -0,0 +1,94 @@
+{ stdenv, mkChromiumDerivation, channel, enableWideVine }:
+
+with stdenv.lib;
+
+mkChromiumDerivation (base: rec {
+  name = "chromium-browser";
+  packageName = "chromium";
+  buildTargets = [ "mksnapshot" "chrome_sandbox" "chrome" ];
+
+  outputs = ["out" "sandbox"];
+
+  sandboxExecutableName = "__chromium-suid-sandbox";
+
+  installPhase = ''
+    mkdir -p "$libExecPath"
+    cp -v "$buildPath/"*.pak "$buildPath/"*.bin "$libExecPath/"
+    cp -v "$buildPath/icudtl.dat" "$libExecPath/"
+    cp -vLR "$buildPath/locales" "$buildPath/resources" "$libExecPath/"
+    cp -v "$buildPath/chrome" "$libExecPath/$packageName"
+
+    # Swiftshader
+    # See https://stackoverflow.com/a/4264351/263061 for the find invocation.
+    if [ -n "$(find "$buildPath/swiftshader/" -maxdepth 1 -name '*.so' -print -quit)" ]; then
+      echo "Swiftshader files found; installing"
+      mkdir -p "$libExecPath/swiftshader"
+      cp -v "$buildPath/swiftshader/"*.so "$libExecPath/swiftshader/"
+    else
+      echo "Swiftshader files not found"
+    fi
+
+    mkdir -p "$sandbox/bin"
+    cp -v "$buildPath/chrome_sandbox" "$sandbox/bin/${sandboxExecutableName}"
+
+    mkdir -vp "$out/share/man/man1"
+    cp -v "$buildPath/chrome.1" "$out/share/man/man1/$packageName.1"
+
+    for icon_file in chrome/app/theme/chromium/product_logo_*[0-9].png; do
+      num_and_suffix="''${icon_file##*logo_}"
+      icon_size="''${num_and_suffix%.*}"
+      expr "$icon_size" : "^[0-9][0-9]*$" || continue
+      logo_output_prefix="$out/share/icons/hicolor"
+      logo_output_path="$logo_output_prefix/''${icon_size}x''${icon_size}/apps"
+      mkdir -vp "$logo_output_path"
+      cp -v "$icon_file" "$logo_output_path/$packageName.png"
+    done
+
+    # Install Desktop Entry
+    install -D chrome/installer/linux/common/desktop.template \
+      $out/share/applications/chromium-browser.desktop
+
+    substituteInPlace $out/share/applications/chromium-browser.desktop \
+      --replace "@@MENUNAME@@" "Chromium" \
+      --replace "@@PACKAGE@@" "chromium" \
+      --replace "Exec=/usr/bin/@@USR_BIN_SYMLINK_NAME@@" "Exec=chromium"
+
+    # Append more mime types to the end
+    sed -i '/^MimeType=/ s,$,x-scheme-handler/webcal;x-scheme-handler/mailto;x-scheme-handler/about;x-scheme-handler/unknown,' \
+      $out/share/applications/chromium-browser.desktop
+
+    # See https://github.com/NixOS/nixpkgs/issues/12433
+    sed -i \
+      -e '/\[Desktop Entry\]/a\' \
+      -e 'StartupWMClass=chromium-browser' \
+      $out/share/applications/chromium-browser.desktop
+  '';
+
+  passthru = { inherit sandboxExecutableName; };
+
+  requiredSystemFeatures = [ "big-parallel" ];
+
+  meta = {
+    description = "An open source web browser from Google, with dependencies on Google web services removed";
+    longDescription = ''
+      Chromium is an open source web browser from Google that aims to build a
+      safer, faster, and more stable way for all Internet users to experience
+      the web. It has a minimalist user interface and provides the vast majority
+      of source code for Google Chrome (which has some additional features).
+    '';
+    homepage = https://github.com/Eloston/ungoogled-chromium;
+    maintainers = with maintainers; [ squalus ];
+    # Overview of the maintainer roles:
+    # nixos-unstable:
+    # - TODO: Need a new maintainer for x86_64 [0]
+    # - @thefloweringash: aarch64
+    # - @primeos: Provisional maintainer (x86_64)
+    # Stable channel:
+    # - TODO (need someone to test backports [0])
+    # [0]: https://github.com/NixOS/nixpkgs/issues/78450
+    license = if enableWideVine then licenses.unfree else licenses.bsd3;
+    platforms = platforms.linux;
+    hydraPlatforms = if channel == "stable" then ["aarch64-linux" "x86_64-linux"] else [];
+    timeout = 172800; # 48 hours
+  };
+})
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/common.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/common.nix
new file mode 100644
index 00000000000..d07da2b3b07
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/common.nix
@@ -0,0 +1,361 @@
+{ stdenv, llvmPackages, gnChromium, ninja, which, nodejs, fetchpatch, gnutar
+
+# default dependencies
+, bzip2, flac, speex, libopus
+, libevent, expat, libjpeg, snappy
+, libpng, libcap
+, xdg_utils, yasm, minizip, libwebp
+, libusb1, pciutils, nss, re2, zlib
+
+, python2Packages, perl, pkgconfig
+, nspr, systemd, kerberos
+, utillinux, alsaLib
+, bison, gperf
+, glib, gtk3, dbus-glib
+, glibc
+, libXScrnSaver, libXcursor, libXtst, libGLU, libGL
+, protobuf, speechd, libXdamage, cups
+, ffmpeg, libxslt, libxml2, at-spi2-core
+, jre
+
+# optional dependencies
+, libgcrypt ? null # gnomeSupport || cupsSupport
+, libva ? null # useVaapi
+, libdrm ? null, wayland ? null, mesa_drivers ? null, libxkbcommon ? null # useOzone
+
+# package customization
+, useVaapi ? false
+, useOzone ? false
+, gnomeSupport ? false, gnome ? null
+, gnomeKeyringSupport ? false, libgnome-keyring3 ? null
+, proprietaryCodecs ? true
+, cupsSupport ? true
+, pulseSupport ? false, libpulseaudio ? null
+, ungoogled-chromium
+, ungoogled ? false
+
+, upstream-info
+}:
+
+buildFun:
+
+with stdenv.lib;
+
+# see http://www.linuxfromscratch.org/blfs/view/cvs/xsoft/chromium.html
+
+let
+  # The additional attributes for creating derivations based on the chromium
+  # source tree.
+  extraAttrs = buildFun base;
+
+  githubPatch = commit: sha256: fetchpatch {
+    url = "https://github.com/chromium/chromium/commit/${commit}.patch";
+    inherit sha256;
+  };
+
+  mkGnFlags =
+    let
+      # Serialize Nix types into GN types according to this document:
+      # https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/language.md
+      mkGnString = value: "\"${escape ["\"" "$" "\\"] value}\"";
+      sanitize = value:
+        if value == true then "true"
+        else if value == false then "false"
+        else if isList value then "[${concatMapStringsSep ", " sanitize value}]"
+        else if isInt value then toString value
+        else if isString value then mkGnString value
+        else throw "Unsupported type for GN value `${value}'.";
+      toFlag = key: value: "${key}=${sanitize value}";
+    in attrs: concatStringsSep " " (attrValues (mapAttrs toFlag attrs));
+
+  gnSystemLibraries = [
+    "flac" "libwebp" "libxslt" "yasm" "opus" "snappy" "libpng"
+    # "zlib" # version 77 reports unresolved dependency on //third_party/zlib:zlib_config
+    # "libjpeg" # fails with multiple undefined references to chromium_jpeg_*
+    # "re2" # fails with linker errors
+    # "ffmpeg" # https://crbug.com/731766
+    # "harfbuzz-ng" # in versions over 63 harfbuzz and freetype are being built together
+                    # so we can't build with one from system and other from source
+  ];
+
+  opusWithCustomModes = libopus.override {
+    withCustomModes = true;
+  };
+
+  defaultDependencies = [
+    bzip2 flac speex opusWithCustomModes
+    libevent expat libjpeg snappy
+    libpng libcap
+    xdg_utils yasm minizip libwebp
+    libusb1 re2 zlib
+    ffmpeg libxslt libxml2
+    # harfbuzz # in versions over 63 harfbuzz and freetype are being built together
+               # so we can't build with one from system and other from source
+  ];
+
+  # build paths and release info
+  packageName = extraAttrs.packageName or extraAttrs.name;
+  buildType = "Release";
+  buildPath = "out/${buildType}";
+  libExecPath = "$out/libexec/${packageName}";
+
+  versionRange = min-version: upto-version:
+    let inherit (upstream-info) version;
+        result = versionAtLeast version min-version && versionOlder version upto-version;
+        stable-version = (import ./upstream-info.nix).stable.version;
+    in if versionAtLeast stable-version upto-version
+       then warn "chromium: stable version ${stable-version} is newer than a patchset bounded at ${upto-version}. You can safely delete it."
+            result
+       else result;
+
+  ungoogler =
+    let versionEntry = (import ./ungoogled-src.nix)."${upstream-info.version}";
+    in ungoogled-chromium {
+      inherit (versionEntry) rev sha256;
+    };
+  base = rec {
+    name = "${packageName}-unwrapped-${version}";
+    inherit (upstream-info) channel version;
+    inherit packageName buildType buildPath;
+
+    src = upstream-info.main;
+
+    nativeBuildInputs = [
+      ninja which python2Packages.python perl pkgconfig
+      python2Packages.ply python2Packages.jinja2 nodejs
+      gnutar
+    ] ++ optional (versionAtLeast version "83") python2Packages.setuptools;
+
+    buildInputs = defaultDependencies ++ [
+      nspr nss systemd
+      utillinux alsaLib
+      bison gperf kerberos
+      glib gtk3 dbus-glib
+      libXScrnSaver libXcursor libXtst libGLU libGL
+      pciutils protobuf speechd libXdamage at-spi2-core
+      jre
+    ] ++ optional gnomeKeyringSupport libgnome-keyring3
+      ++ optionals gnomeSupport [ gnome.GConf libgcrypt ]
+      ++ optionals cupsSupport [ libgcrypt cups ]
+      ++ optional useVaapi libva
+      ++ optional pulseSupport libpulseaudio
+      ++ optionals useOzone [ libdrm wayland mesa_drivers libxkbcommon ];
+
+    patches = [
+      ./patches/nix_plugin_paths_68.patch
+      ./patches/remove-webp-include-69.patch
+      ./patches/no-build-timestamps.patch
+      ./patches/widevine-79.patch
+      ./patches/dont-use-ANGLE-by-default.patch
+      # Unfortunately, chromium regularly breaks on major updates and
+      # then needs various patches backported in order to be compiled with GCC.
+      # Good sources for such patches and other hints:
+      # - https://gitweb.gentoo.org/repo/gentoo.git/plain/www-client/chromium/
+      # - https://git.archlinux.org/svntogit/packages.git/tree/trunk?h=packages/chromium
+      # - https://github.com/chromium/chromium/search?q=GCC&s=committer-date&type=Commits
+      #
+      # ++ optionals (channel == "dev") [ ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" ) ]
+      # ++ optional (versionRange "68" "72") ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" )
+    ] ++ optionals (useVaapi) ([
+      # source: https://aur.archlinux.org/cgit/aur.git/tree/vaapi-fix.patch?h=chromium-vaapi
+      ./patches/vaapi-fix.patch
+    ] ++ optionals (versionRange "81" "82") [
+      (githubPatch "5b2ff215473e0526b5b24aeff4ad90d369b21c75" "0n00vh8wfpn2ay5fqsxcsx0zadnv7mihm72bcvnrfzh75nzbg902")
+      (githubPatch "98e343ab369e4262511b5fce547728e3e5eefba8" "00wwp653jk0k0yvix00vr7ymgck9dj7fxjwx4nc67ynn84dh6064")
+    ]);
+
+    postPatch = ''
+      # We want to be able to specify where the sandbox is via CHROME_DEVEL_SANDBOX
+      substituteInPlace sandbox/linux/suid/client/setuid_sandbox_host.cc \
+        --replace \
+          'return sandbox_binary;' \
+          'return base::FilePath(GetDevelSandboxPath());'
+
+      substituteInPlace services/audio/audio_sandbox_hook_linux.cc \
+        --replace \
+          '/usr/share/alsa/' \
+          '${alsaLib}/share/alsa/' \
+        --replace \
+          '/usr/lib/x86_64-linux-gnu/gconv/' \
+          '${glibc}/lib/gconv/' \
+        --replace \
+          '/usr/share/locale/' \
+          '${glibc}/share/locale/'
+
+      sed -i -e 's@"\(#!\)\?.*xdg-@"\1${xdg_utils}/bin/xdg-@' \
+        chrome/browser/shell_integration_linux.cc
+
+      sed -i -e '/lib_loader.*Load/s!"\(libudev\.so\)!"${systemd.lib}/lib/\1!' \
+        device/udev_linux/udev?_loader.cc
+
+      sed -i -e '/libpci_loader.*Load/s!"\(libpci\.so\)!"${pciutils}/lib/\1!' \
+        gpu/config/gpu_info_collector_linux.cc
+
+      sed -i -re 's/([^:])\<(isnan *\()/\1std::\2/g' \
+        chrome/browser/ui/webui/engagement/site_engagement_ui.cc
+
+      sed -i -e '/#include/ {
+        i #include <algorithm>
+        :l; n; bl
+      }' gpu/config/gpu_control_list.cc
+
+      # Allow to put extensions into the system-path.
+      sed -i -e 's,/usr,/run/current-system/sw,' chrome/common/chrome_paths.cc
+
+      patchShebangs .
+      # use our own nodejs
+      mkdir -p third_party/node/linux/node-linux-x64/bin
+      ln -s $(which node) third_party/node/linux/node-linux-x64/bin/node
+
+      # remove unused third-party
+      # in third_party/crashpad third_party/zlib contains just a header-adapter
+      for lib in ${toString gnSystemLibraries}; do
+        find -type f -path "*third_party/$lib/*"     \
+            \! -path "*third_party/crashpad/crashpad/third_party/zlib/*"  \
+            \! -path "*third_party/$lib/chromium/*"  \
+            \! -path "*third_party/$lib/google/*"    \
+            \! -path "*base/third_party/icu/*"       \
+            \! -path "*base/third_party/libevent/*"  \
+            \! -regex '.*\.\(gn\|gni\|isolate\|py\)' \
+            -delete
+      done
+    '' + optionalString stdenv.isAarch64 ''
+      substituteInPlace build/toolchain/linux/BUILD.gn \
+        --replace 'toolprefix = "aarch64-linux-gnu-"' 'toolprefix = ""'
+    '' + optionalString stdenv.cc.isClang ''
+      mkdir -p third_party/llvm-build/Release+Asserts/bin
+      ln -s ${stdenv.cc}/bin/clang              third_party/llvm-build/Release+Asserts/bin/clang
+      ln -s ${stdenv.cc}/bin/clang++            third_party/llvm-build/Release+Asserts/bin/clang++
+      ln -s ${llvmPackages.llvm}/bin/llvm-ar    third_party/llvm-build/Release+Asserts/bin/llvm-ar
+    '' + optionalString ungoogled ''
+      ${ungoogler}/utils/prune_binaries.py . ${ungoogler}/pruning.list || echo "some errors"
+      ${ungoogler}/utils/patches.py . ${ungoogler}/patches
+      ${ungoogler}/utils/domain_substitution.py apply -r ${ungoogler}/domain_regex.list -f ${ungoogler}/domain_substitution.list -c ./ungoogled-domsubcache.tar.gz .
+    '';
+
+    gnFlags = mkGnFlags ({
+      linux_use_bundled_binutils = false;
+      use_lld = false;
+      use_gold = true;
+      gold_path = "${stdenv.cc}/bin";
+      is_debug = false;
+
+      proprietary_codecs = false;
+      use_sysroot = false;
+      use_gnome_keyring = gnomeKeyringSupport;
+      use_gio = gnomeSupport;
+      # ninja: error: '../../native_client/toolchain/linux_x86/pnacl_newlib/bin/x86_64-nacl-objcopy',
+      # needed by 'nacl_irt_x86_64.nexe', missing and no known rule to make it
+      enable_nacl = false;
+      # Enabling the Widevine component here doesn't affect whether we can
+      # redistribute the chromium package; the Widevine component is either
+      # added later in the wrapped -wv build or downloaded from Google.
+      enable_widevine = true;
+      use_cups = cupsSupport;
+
+      treat_warnings_as_errors = false;
+      is_clang = stdenv.cc.isClang;
+      clang_use_chrome_plugins = false;
+      blink_symbol_level = 0;
+      fieldtrial_testing_like_official_build = true;
+
+      # Google API keys, see:
+      #   http://www.chromium.org/developers/how-tos/api-keys
+      # Note: These are for NixOS/nixpkgs use ONLY. For your own distribution,
+      # please get your own set of keys.
+      google_api_key = "AIzaSyDGi15Zwl11UNe6Y-5XW_upsfyw31qwZPI";
+      google_default_client_id = "404761575300.apps.googleusercontent.com";
+      google_default_client_secret = "9rIFQjfnkykEmqb6FfjJQD1D";
+    } // optionalAttrs proprietaryCodecs {
+      # enable support for the H.264 codec
+      proprietary_codecs = true;
+      enable_hangout_services_extension = true;
+      ffmpeg_branding = "Chrome";
+    } // optionalAttrs useVaapi {
+      use_vaapi = true;
+    } // optionalAttrs pulseSupport {
+      use_pulseaudio = true;
+      link_pulseaudio = true;
+    } // optionalAttrs useOzone {
+      use_ozone = true;
+      ozone_platform_gbm = false;
+      use_xkbcommon = true;
+      use_glib = true;
+      use_gtk = true;
+      use_system_libwayland = true;
+      use_system_minigbm = true;
+      use_system_libdrm = true;
+      system_wayland_scanner_path = "${wayland}/bin/wayland-scanner";
+    } // optionalAttrs ungoogled {
+      closure_compile = false;
+      enable_hangout_services_extension = false;
+      enable_mdns = false;
+      enable_nacl_nonsfi = false;
+      enable_one_click_signin = false;
+      enable_reading_list = false;
+      enable_remoting = false;
+      enable_reporting = false;
+      enable_service_discovery = false;
+      exclude_unwind_tables = true;
+      google_api_key = "";
+      google_default_client_id = "";
+      google_default_client_secret = "";
+      optimize_webui = false;
+      safe_browsing_mode = 0;
+      use_official_google_api_keys = false;
+      use_unofficial_version_number = false;
+    } // (extraAttrs.gnFlags or {}));
+
+    configurePhase = ''
+      runHook preConfigure
+
+      # This is to ensure expansion of $out.
+      libExecPath="${libExecPath}"
+      python build/linux/unbundle/replace_gn_files.py \
+        --system-libraries ${toString gnSystemLibraries}
+      ${gnChromium}/bin/gn gen --args=${escapeShellArg gnFlags} out/Release | tee gn-gen-outputs.txt
+
+      # Fail if `gn gen` contains a WARNING.
+      grep -o WARNING gn-gen-outputs.txt && echo "Found gn WARNING, exiting nix build" && exit 1
+
+      runHook postConfigure
+    '';
+
+    # Don't spam warnings about unknown warning options. This is useful because
+    # our Clang is always older than Chromium's and the build logs have a size
+    # of approx. 25 MB without this option (and this saves e.g. 66 %).
+    NIX_CFLAGS_COMPILE = "-Wno-unknown-warning-option";
+
+    buildPhase = let
+      # Build paralelism: on Hydra the build was frequently running into memory
+      # exhaustion, and even other users might be running into similar issues.
+      # -j is halved to avoid memory problems, and -l is slightly increased
+      # so that the build gets slight preference before others
+      # (it will often be on "critical path" and at risk of timing out)
+      buildCommand = target: ''
+        ninja -C "${buildPath}"  \
+          -j$(( ($NIX_BUILD_CORES+1) / 2 )) -l$(( $NIX_BUILD_CORES+1 )) \
+          "${target}"
+        (
+          source chrome/installer/linux/common/installer.include
+          PACKAGE=$packageName
+          MENUNAME="Chromium"
+          process_template chrome/app/resources/manpage.1.in "${buildPath}/chrome.1"
+        )
+      '';
+      targets = extraAttrs.buildTargets or [];
+      commands = map buildCommand targets;
+    in concatStringsSep "\n" commands;
+
+    postFixup = ''
+      # Make sure that libGLESv2 is found by dlopen (if using EGL).
+      chromiumBinary="$libExecPath/$packageName"
+      origRpath="$(patchelf --print-rpath "$chromiumBinary")"
+      patchelf --set-rpath "${libGL}/lib:$origRpath" "$chromiumBinary"
+    '';
+  };
+
+# Remove some extraAttrs we supplied to the base attributes already.
+in stdenv.mkDerivation (base // removeAttrs extraAttrs [
+  "name" "gnFlags" "buildTargets"
+])
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/default.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/default.nix
new file mode 100644
index 00000000000..f172e7c09ce
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/default.nix
@@ -0,0 +1,205 @@
+{ newScope, config, stdenv, llvmPackages_9, llvmPackages_10
+, makeWrapper, ed
+, glib, gtk3, gnome3, gsettings-desktop-schemas, gn, fetchgit
+, libva ? null
+, gcc, nspr, nss, patchelfUnstable, runCommand
+, lib
+
+# package customization
+, channel ? "stable"
+, gnomeSupport ? false, gnome ? null
+, gnomeKeyringSupport ? false
+, proprietaryCodecs ? true
+, enablePepperFlash ? false
+, enableWideVine ? false
+, ungoogled ? true
+, useVaapi ? false # test video on radeon, before enabling this
+, useOzone ? false
+, cupsSupport ? true
+, pulseSupport ? config.pulseaudio or stdenv.isLinux
+, commandLineArgs ? ""
+}:
+
+let
+  llvmPackages = if channel == "dev"
+    then llvmPackages_10
+    else llvmPackages_9;
+  stdenv = llvmPackages.stdenv;
+
+  callPackage = newScope chromium;
+
+  chromium = {
+    inherit stdenv llvmPackages;
+
+    upstream-info = (callPackage ./update.nix {}).getChannel channel;
+
+    mkChromiumDerivation = callPackage ./common.nix ({
+      inherit gnome gnomeSupport gnomeKeyringSupport proprietaryCodecs cupsSupport pulseSupport useVaapi useOzone ungoogled;
+      gnChromium = gn;
+    } // lib.optionalAttrs (channel == "dev") {
+      # TODO: Remove after we can update gn for the stable channel (backward incompatible changes):
+      gnChromium = gn.overrideAttrs (oldAttrs: {
+        version = "2020-03-23";
+        src = fetchgit {
+          url = "https://gn.googlesource.com/gn";
+          rev = "5ed3c9cc67b090d5e311e4bd2aba072173e82db9";
+          sha256 = "00y2d35wvqmx9glaqhfb62wdgbfpwr77v0934nnvh9ks71vnsjqy";
+        };
+      });
+    });
+
+    browser = callPackage ./browser.nix { inherit channel enableWideVine; };
+
+    plugins = callPackage ./plugins.nix {
+      inherit enablePepperFlash;
+    };
+
+    ungoogled-chromium = callPackage ./ungoogled.nix {};
+  };
+
+  mkrpath = p: "${lib.makeSearchPathOutput "lib" "lib64" p}:${lib.makeLibraryPath p}";
+  widevineCdm = let upstream-info = chromium.upstream-info; in stdenv.mkDerivation {
+    name = "chrome-widevine-cdm";
+
+    # The .deb file for Google Chrome
+    src = upstream-info.binary;
+
+    nativeBuildInputs = [ patchelfUnstable ];
+
+    phases = [ "unpackPhase" "patchPhase" "installPhase" "checkPhase" ];
+
+    unpackCmd = let
+      widevineCdmPath =
+        if upstream-info.channel == "stable" then
+          "./opt/google/chrome/WidevineCdm"
+        else if upstream-info.channel == "beta" then
+          "./opt/google/chrome-beta/WidevineCdm"
+        else if upstream-info.channel == "dev" then
+          "./opt/google/chrome-unstable/WidevineCdm"
+        else
+          throw "Unknown chromium channel.";
+    in ''
+      # Extract just WidevineCdm from upstream's .deb file
+      ar p "$src" data.tar.xz | tar xJ "${widevineCdmPath}"
+
+      # Move things around so that we don't have to reference a particular
+      # chrome-* directory later.
+      mv "${widevineCdmPath}" ./
+
+      # unpackCmd wants a single output directory; let it take WidevineCdm/
+      rm -rf opt
+    '';
+
+    doCheck = true;
+    checkPhase = ''
+      ! find -iname '*.so' -exec ldd {} + | grep 'not found'
+    '';
+
+    PATCH_RPATH = mkrpath [ gcc.cc glib nspr nss ];
+
+    patchPhase = ''
+      patchelf --set-rpath "$PATCH_RPATH" _platform_specific/linux_x64/libwidevinecdm.so
+    '';
+
+    installPhase = ''
+      mkdir -p $out/WidevineCdm
+      cp -a * $out/WidevineCdm/
+    '';
+
+    meta = {
+      platforms = [ "x86_64-linux" ];
+      license = lib.licenses.unfree;
+    };
+  };
+
+  suffix = if channel != "stable" then "-" + channel else "";
+
+  sandboxExecutableName = chromium.browser.passthru.sandboxExecutableName;
+
+  version = chromium.browser.version;
+
+  # We want users to be able to enableWideVine without rebuilding all of
+  # chromium, so we have a separate derivation here that copies chromium
+  # and adds the unfree WidevineCdm.
+  chromiumWV = let browser = chromium.browser; in if enableWideVine then
+    runCommand (browser.name + "-wv") { version = browser.version; }
+      ''
+        mkdir -p $out
+        cp -a ${browser}/* $out/
+        chmod u+w $out/libexec/chromium
+        cp -a ${widevineCdm}/WidevineCdm $out/libexec/chromium/
+      ''
+    else browser;
+in stdenv.mkDerivation {
+  name = "chromium${suffix}-${version}";
+  inherit version;
+
+  buildInputs = [
+    makeWrapper ed
+
+    # needed for GSETTINGS_SCHEMAS_PATH
+    gsettings-desktop-schemas glib gtk3
+
+    # needed for XDG_ICON_DIRS
+    gnome3.adwaita-icon-theme
+  ];
+
+  outputs = ["out" "sandbox"];
+
+  buildCommand = let
+    browserBinary = "${chromiumWV}/libexec/chromium/chromium";
+    getWrapperFlags = plugin: "$(< \"${plugin}/nix-support/wrapper-flags\")";
+    libPath = stdenv.lib.makeLibraryPath ([]
+      ++ stdenv.lib.optional useVaapi libva
+    );
+
+  in with stdenv.lib; ''
+    mkdir -p "$out/bin"
+
+    eval makeWrapper "${browserBinary}" "$out/bin/chromium" \
+      --add-flags ${escapeShellArg (escapeShellArg commandLineArgs)} \
+      ${concatMapStringsSep " " getWrapperFlags chromium.plugins.enabled}
+
+    ed -v -s "$out/bin/chromium" << EOF
+    2i
+
+    if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
+    then
+      export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
+    else
+      export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
+    fi
+
+  '' + lib.optionalString (libPath != "") ''
+    # To avoid loading .so files from cwd, LD_LIBRARY_PATH here must not
+    # contain an empty section before or after a colon.
+    export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH\''${LD_LIBRARY_PATH:+:}${libPath}"
+  '' + ''
+
+    # libredirect causes chromium to deadlock on startup
+    export LD_PRELOAD="\$(echo -n "\$LD_PRELOAD" | tr ':' '\n' | grep -v /lib/libredirect\\\\.so$ | tr '\n' ':')"
+
+    export XDG_DATA_DIRS=$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH\''${XDG_DATA_DIRS:+:}\$XDG_DATA_DIRS
+
+    .
+    w
+    EOF
+
+    ln -sv "${chromium.browser.sandbox}" "$sandbox"
+
+    ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
+
+    mkdir -p "$out/share"
+    for f in '${chromium.browser}'/share/*; do # hello emacs */
+      ln -s -t "$out/share/" "$f"
+    done
+  '';
+
+  inherit (chromium.browser) packageName;
+  meta = chromium.browser.meta;
+  passthru = {
+    inherit (chromium) upstream-info browser;
+    mkDerivation = chromium.mkChromiumDerivation;
+    inherit sandboxExecutableName;
+  };
+}
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/dont-use-ANGLE-by-default.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/dont-use-ANGLE-by-default.patch
new file mode 100644
index 00000000000..9f14a304eb3
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/dont-use-ANGLE-by-default.patch
@@ -0,0 +1,26 @@
+A field trial currently enables the passthrough command decoder, which causes
+gl_factory.cc to try kGLImplementationEGLANGLE first, which causes Chromium to fail
+to load libGLESv2.so on NixOS.  It somehow does not try kGLImplementationDesktopGL,
+and so there is no GL support at all.
+
+Revert to using the validating command decoder, which prevents gl_factory.cc
+from touching allowed_impls, allowing it to successfully use kGLImplementationDesktopGL.
+
+diff --git a/ui/gl/gl_utils.cc b/ui/gl/gl_utils.cc
+index 697cbed5fe2d..8419bdb21a2f 100644
+--- a/ui/gl/gl_utils.cc
++++ b/ui/gl/gl_utils.cc
+@@ -71,9 +71,10 @@ bool UsePassthroughCommandDecoder(const base::CommandLine* command_line) {
+   } else if (switch_value == kCmdDecoderValidatingName) {
+     return false;
+   } else {
+-    // Unrecognized or missing switch, use the default.
+-    return base::FeatureList::IsEnabled(
+-        features::kDefaultPassthroughCommandDecoder);
++    // Ignore the field trial that enables it; disable it until
++    // gl_factory.cc kGLImplementationEGLANGLE issues are sorted
++    // out on NixOS.
++    return false;
+   }
+ }
+ }
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/nix_plugin_paths_68.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/nix_plugin_paths_68.patch
new file mode 100644
index 00000000000..da6a4c92b46
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/nix_plugin_paths_68.patch
@@ -0,0 +1,61 @@
+diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
+index f4e119d..d9775bd 100644
+--- a/chrome/common/chrome_paths.cc
++++ b/chrome/common/chrome_paths.cc
+@@ -68,21 +68,14 @@ static base::LazyInstance<base::FilePath>
+     g_invalid_specified_user_data_dir = LAZY_INSTANCE_INITIALIZER;
+ 
+ // Gets the path for internal plugins.
+-bool GetInternalPluginsDirectory(base::FilePath* result) {
+-#if defined(OS_MACOSX)
+-  // If called from Chrome, get internal plugins from a subdirectory of the
+-  // framework.
+-  if (base::mac::AmIBundled()) {
+-    *result = chrome::GetFrameworkBundlePath();
+-    DCHECK(!result->empty());
+-    *result = result->Append("Internet Plug-Ins");
+-    return true;
+-  }
+-  // In tests, just look in the module directory (below).
+-#endif
+-
+-  // The rest of the world expects plugins in the module directory.
+-  return base::PathService::Get(base::DIR_MODULE, result);
++bool GetInternalPluginsDirectory(base::FilePath* result,
++                                 const std::string& ident) {
++  std::string full_env = std::string("NIX_CHROMIUM_PLUGIN_PATH_") + ident;
++  const char* value = getenv(full_env.c_str());
++  if (value == NULL)
++      return base::PathService::Get(base::DIR_MODULE, result);
++  else
++      *result = base::FilePath(value);
+ }
+ 
+ // Gets the path for bundled implementations of components. Note that these
+@@ -272,7 +265,7 @@ bool PathProvider(int key, base::FilePath* result) {
+       create_dir = true;
+       break;
+     case chrome::DIR_INTERNAL_PLUGINS:
+-      if (!GetInternalPluginsDirectory(&cur))
++      if (!GetInternalPluginsDirectory(&cur, "ALL"))
+         return false;
+       break;
+     case chrome::DIR_COMPONENTS:
+@@ -280,7 +273,7 @@ bool PathProvider(int key, base::FilePath* result) {
+         return false;
+       break;
+     case chrome::DIR_PEPPER_FLASH_PLUGIN:
+-      if (!GetInternalPluginsDirectory(&cur))
++      if (!GetInternalPluginsDirectory(&cur, "PEPPERFLASH"))
+         return false;
+       cur = cur.Append(kPepperFlashBaseDirectory);
+       break;
+@@ -358,7 +351,7 @@ bool PathProvider(int key, base::FilePath* result) {
+         cur = cur.DirName();
+       }
+ #else
+-      if (!GetInternalPluginsDirectory(&cur))
++      if (!GetInternalPluginsDirectory(&cur, "PNACL"))
+         return false;
+ #endif
+       cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/no-build-timestamps.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/no-build-timestamps.patch
new file mode 100644
index 00000000000..6b788f43d29
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/no-build-timestamps.patch
@@ -0,0 +1,17 @@
+--- chromium-70.0.3538.67/build/compute_build_timestamp.py.orig	2018-11-02 16:00:34.368933077 +0200
++++ chromium-70.0.3538.67/build/compute_build_timestamp.py	2018-11-08 04:06:21.658105129 +0200
+@@ -94,6 +94,14 @@
+       'build_type', help='The type of build', choices=('official', 'default'))
+   args = argument_parser.parse_args()
+ 
++  # I don't trust LASTCHANGE magic, and I definelly want something deterministic here
++  SOURCE_DATE_EPOCH = os.getenv("SOURCE_DATE_EPOCH", None)
++  if SOURCE_DATE_EPOCH is not None:
++    print(SOURCE_DATE_EPOCH)
++    return 0
++  else:
++    raise RuntimeError("SOURCE_DATE_EPOCH not set")
++
+   # The mtime of the revision in build/util/LASTCHANGE is stored in a file
+   # next to it. Read it, to get a deterministic time close to "now".
+   # That date is then modified as described at the top of the file so that
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/remove-webp-include-69.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/remove-webp-include-69.patch
new file mode 100644
index 00000000000..07572cf7ee9
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/remove-webp-include-69.patch
@@ -0,0 +1,11 @@
+--- a/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
++++ b/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
+@@ -13,7 +13,7 @@
+
+ #include "jpeglib.h"  // for JPEG_MAX_DIMENSION
+
+-#include "third_party/libwebp/src/webp/encode.h"  // for WEBP_MAX_DIMENSION
++#define WEBP_MAX_DIMENSION 16383
+
+ namespace blink {
+
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/vaapi-fix.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/vaapi-fix.patch
new file mode 100644
index 00000000000..b5372d1a255
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/vaapi-fix.patch
@@ -0,0 +1,74 @@
+--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
++++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+@@ -641,6 +641,7 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
+   // |vpp_vaapi_wrapper_| for VaapiPicture to DownloadFromSurface() the VA's
+   // internal decoded frame.
+   if (buffer_allocation_mode_ != BufferAllocationMode::kNone &&
++      buffer_allocation_mode_ != BufferAllocationMode::kWrapVdpau &&
+       !vpp_vaapi_wrapper_) {
+     vpp_vaapi_wrapper_ = VaapiWrapper::Create(
+         VaapiWrapper::kVideoProcess, VAProfileNone,
+@@ -665,7 +666,8 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
+     PictureBuffer buffer = buffers[i];
+     buffer.set_size(requested_pic_size_);
+     std::unique_ptr<VaapiPicture> picture = vaapi_picture_factory_->Create(
+-        (buffer_allocation_mode_ == BufferAllocationMode::kNone)
++        ((buffer_allocation_mode_ == BufferAllocationMode::kNone) ||
++         (buffer_allocation_mode_ == BufferAllocationMode::kWrapVdpau))
+             ? vaapi_wrapper_
+             : vpp_vaapi_wrapper_,
+         make_context_current_cb_, bind_image_cb_, buffer);
+@@ -1093,6 +1095,12 @@ VaapiVideoDecodeAccelerator::GetSupportedProfiles() {
+
+ VaapiVideoDecodeAccelerator::BufferAllocationMode
+ VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() {
++  // NVIDIA blobs use VDPAU
++  if (VaapiWrapper::GetImplementationType() == VAImplementation::kNVIDIAVDPAU) {
++    LOG(INFO) << "VA-API driver on VDPAU backend";
++    return BufferAllocationMode::kWrapVdpau;
++  }
++
+   // TODO(crbug.com/912295): Enable a better BufferAllocationMode for IMPORT
+   // |output_mode_| as well.
+   if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT)
+@@ -1105,7 +1113,7 @@ VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() {
+   // depends on the bitstream and sometimes it's not enough to cover the amount
+   // of frames needed by the client pipeline (see b/133733739).
+   // TODO(crbug.com/911754): Enable for VP9 Profile 2.
+-  if (IsGeminiLakeOrLater() &&
++  if (false && IsGeminiLakeOrLater() &&
+       (profile_ == VP9PROFILE_PROFILE0 || profile_ == VP8PROFILE_ANY)) {
+     // Add one to the reference frames for the one being currently egressed, and
+     // an extra allocation for both |client_| and |decoder_|, see
+--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.h
++++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.h
+@@ -204,6 +204,7 @@ class MEDIA_GPU_EXPORT VaapiVideoDecodeAccelerator
+     // Using |client_|s provided PictureBuffers and as many internally
+     // allocated.
+     kNormal,
++    kWrapVdpau,
+   };
+
+   // Decides the concrete buffer allocation mode, depending on the hardware
+--- a/media/gpu/vaapi/vaapi_wrapper.cc
++++ b/media/gpu/vaapi/vaapi_wrapper.cc
+@@ -131,6 +131,9 @@ media::VAImplementation VendorStringToImplementationType(
+   } else if (base::StartsWith(va_vendor_string, "Intel iHD driver",
+                               base::CompareCase::SENSITIVE)) {
+     return media::VAImplementation::kIntelIHD;
++  } else if (base::StartsWith(va_vendor_string, "Splitted-Desktop Systems VDPAU",
++                              base::CompareCase::SENSITIVE)) {
++    return media::VAImplementation::kNVIDIAVDPAU;
+   }
+   return media::VAImplementation::kOther;
+ }
+--- a/media/gpu/vaapi/vaapi_wrapper.h
++++ b/media/gpu/vaapi/vaapi_wrapper.h
+@@ -79,6 +79,7 @@ enum class VAImplementation {
+   kIntelIHD,
+   kOther,
+   kInvalid,
++  kNVIDIAVDPAU,
+ };
+
+ // This class handles VA-API calls and ensures proper locking of VA-API calls
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/patches/widevine-79.patch b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/widevine-79.patch
new file mode 100644
index 00000000000..32f0ae2fb5e
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/patches/widevine-79.patch
@@ -0,0 +1,13 @@
+diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn
+index ed0e2f5208b..5b431a030d5 100644
+--- a/third_party/widevine/cdm/BUILD.gn
++++ b/third_party/widevine/cdm/BUILD.gn
+@@ -14,7 +14,7 @@ buildflag_header("buildflags") {
+ 
+   flags = [
+     "ENABLE_WIDEVINE=$enable_widevine",
+-    "BUNDLE_WIDEVINE_CDM=$bundle_widevine_cdm",
++    "BUNDLE_WIDEVINE_CDM=true",
+     "ENABLE_WIDEVINE_CDM_COMPONENT=$enable_widevine_cdm_component",
+   ]
+ }
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/plugins.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/plugins.nix
new file mode 100644
index 00000000000..434bd77b6d1
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/plugins.nix
@@ -0,0 +1,93 @@
+{ stdenv, gcc
+, jshon
+, glib
+, nspr
+, nss
+, fetchzip
+, patchelfUnstable
+, enablePepperFlash ? false
+
+, upstream-info
+}:
+
+with stdenv.lib;
+
+let
+  mkrpath = p: "${makeSearchPathOutput "lib" "lib64" p}:${makeLibraryPath p}";
+
+  # Generate a shell fragment that emits flags appended to the
+  # final makeWrapper call for wrapping the browser's main binary.
+  #
+  # Note that this is shell-escaped so that only the variable specified
+  # by the "output" attribute is substituted.
+  mkPluginInfo = { output ? "out", allowedVars ? [ output ]
+                 , flags ? [], envVars ? {}
+                 }: let
+    shSearch = ["'"] ++ map (var: "@${var}@") allowedVars;
+    shReplace = ["'\\''"] ++ map (var: "'\"\${${var}}\"'") allowedVars;
+    # We need to triple-escape "val":
+    #  * First because makeWrapper doesn't do any quoting of its arguments by
+    #    itself.
+    #  * Second because it's passed to the makeWrapper call separated by IFS but
+    #    not by the _real_ arguments, for example the Widevine plugin flags
+    #    contain spaces, so they would end up as separate arguments.
+    #  * Third in order to be correctly quoted for the "echo" call below.
+    shEsc = val: "'${replaceStrings ["'"] ["'\\''"] val}'";
+    mkSh = val: "'${replaceStrings shSearch shReplace (shEsc val)}'";
+    mkFlag = flag: ["--add-flags" (shEsc flag)];
+    mkEnvVar = key: val: ["--set" (shEsc key) (shEsc val)];
+    envList = mapAttrsToList mkEnvVar envVars;
+    quoted = map mkSh (flatten ((map mkFlag flags) ++ envList));
+  in ''
+    mkdir -p "''$${output}/nix-support"
+    echo ${toString quoted} > "''$${output}/nix-support/wrapper-flags"
+  '';
+
+  flash = stdenv.mkDerivation rec {
+    pname = "flashplayer-ppapi";
+    version = "32.0.0.344";
+
+    src = fetchzip {
+      url = "https://fpdownload.adobe.com/pub/flashplayer/pdc/${version}/flash_player_ppapi_linux.x86_64.tar.gz";
+      sha256 = "05ijlgsby9zxx0qs6f3vav1z0p6xr1cg6idl4akxvfmsl6hn6hkq";
+      stripRoot = false;
+    };
+
+    patchPhase = ''
+      chmod +x libpepflashplayer.so
+      patchelf --set-rpath "${mkrpath [ gcc.cc ]}" libpepflashplayer.so
+    '';
+
+    doCheck = true;
+    checkPhase = ''
+      ! find -iname '*.so' -exec ldd {} + | grep 'not found'
+    '';
+
+    installPhase = ''
+      flashVersion="$(
+        "${jshon}/bin/jshon" -F manifest.json -e version -u
+      )"
+
+      install -vD libpepflashplayer.so "$out/lib/libpepflashplayer.so"
+
+      ${mkPluginInfo {
+        allowedVars = [ "out" "flashVersion" ];
+        flags = [
+          "--ppapi-flash-path=@out@/lib/libpepflashplayer.so"
+          "--ppapi-flash-version=@flashVersion@"
+        ];
+      }}
+    '';
+
+    dontStrip = true;
+
+    meta = {
+      license = stdenv.lib.licenses.unfree;
+      maintainers = with stdenv.lib.maintainers; [ taku0 ];
+      platforms = platforms.x86_64;
+    };
+  };
+
+in {
+  enabled = optional enablePepperFlash flash;
+}
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled-src.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled-src.nix
new file mode 100644
index 00000000000..9b5c76f5342
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled-src.nix
@@ -0,0 +1,6 @@
+{
+  "81.0.4044.92" = {
+    rev = "81.0.4044.92-2";
+    sha256 = "071a33idn2zcix6z8skn7y85mhb9w5s0bh0fvrjm269y7cmjrh3l";
+  };
+}
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled.nix
new file mode 100644
index 00000000000..17418c90af4
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/ungoogled.nix
@@ -0,0 +1,42 @@
+{ stdenv
+, fetchFromGitHub
+, python3Packages
+, makeWrapper
+, patch
+}:
+{ rev
+, sha256
+}:
+
+stdenv.mkDerivation rec {
+  name = "ungoogled-chromium-${version}";
+
+  version = rev;
+
+  src = fetchFromGitHub {
+    owner = "Eloston";
+    repo = "ungoogled-chromium";
+    inherit rev sha256;
+  };
+
+  dontBuild = true;
+
+  buildInputs = [
+    python3Packages.python
+    patch
+  ];
+
+  nativeBuildInputs = [
+    makeWrapper
+  ];
+
+  patchPhase = ''
+    sed -i '/chromium-widevine/d' patches/series
+  '';
+
+  installPhase = ''
+    mkdir $out
+    cp -R * $out/
+    wrapProgram $out/utils/patches.py --add-flags "apply" --prefix PATH : "${patch}/bin"
+  '';
+}
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix
new file mode 100644
index 00000000000..6dff17c69dd
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/update.nix
@@ -0,0 +1,271 @@
+let maybePkgs = import ../../../../../. {}; in
+
+{ stdenv     ? maybePkgs.stdenv
+, runCommand ? maybePkgs.runCommand
+, fetchurl   ? maybePkgs.fetchurl
+, writeText  ? maybePkgs.writeText
+, curl       ? maybePkgs.curl
+, cacert     ? maybePkgs.cacert
+, nix        ? maybePkgs.nix
+}:
+
+let
+  inherit (stdenv) lib;
+
+  sources = if builtins.pathExists ./upstream-info.nix
+            then import ./upstream-info.nix
+            else {};
+
+  bucketURL = "https://commondatastorage.googleapis.com/"
+            + "chromium-browser-official";
+
+  mkVerURL = version: "${bucketURL}/chromium-${version}.tar.xz";
+
+  debURL = "https://dl.google.com/linux/chrome/deb/pool/main/g";
+
+  getDebURL = channelName: version: arch: mirror: let
+    packageSuffix = if channelName == "dev" then "unstable" else channelName;
+    packageName = "google-chrome-${packageSuffix}";
+  in "${mirror}/${packageName}/${packageName}_${version}-1_${arch}.deb";
+
+  # Untrusted mirrors, don't try to update from them!
+  debMirrors = [
+    "http://95.31.35.30/chrome/pool/main/g"
+    "http://mirror.pcbeta.com/google/chrome/deb/pool/main/g"
+    "http://repo.fdzh.org/chrome/deb/pool/main/g"
+  ];
+
+in {
+  getChannel = channel: let
+    chanAttrs = builtins.getAttr channel sources;
+  in {
+    inherit channel;
+    inherit (chanAttrs) version;
+
+    main = fetchurl {
+      url = mkVerURL chanAttrs.version;
+      inherit (chanAttrs) sha256;
+    };
+
+    binary = fetchurl (let
+      mkUrls = arch: let
+        mkURLForMirror = getDebURL channel chanAttrs.version arch;
+      in map mkURLForMirror ([ debURL ] ++ debMirrors);
+    in if stdenv.is64bit && chanAttrs ? sha256bin64 then {
+      urls = mkUrls "amd64";
+      sha256 = chanAttrs.sha256bin64;
+    } else if !stdenv.is64bit && chanAttrs ? sha256bin32 then {
+      urls = mkUrls "i386";
+      sha256 = chanAttrs.sha256bin32;
+    } else throw "No Chrome plugins are available for your architecture.");
+  };
+
+  update = let
+    csv2nix = name: src: import (runCommand "${name}.nix" {
+      src = builtins.fetchurl src;
+    } ''
+      esc() { echo "\"$(echo "$1" | sed -e 's/"\\$/\\&/')\""; } # ohai emacs "
+      IFS=, read -r -a headings <<< "$(head -n1 "$src")"
+      echo "[" > "$out"
+      tail -n +2 "$src" | while IFS=, read -r -a line; do
+        echo "  {"
+        for idx in "''${!headings[@]}"; do
+          echo "    $(esc "''${headings[idx]}") = $(esc ''${line[$idx]});"
+        done
+        echo "  }"
+      done >> "$out"
+      echo "]" >> "$out"
+    '');
+
+    channels = lib.fold lib.recursiveUpdate {} (map (attrs: {
+      ${attrs.os}.${attrs.channel} = attrs // {
+        history = let
+          drvName = "omahaproxy-${attrs.os}.${attrs.channel}-info";
+          history = csv2nix drvName "http://omahaproxy.appspot.com/history";
+          cond = h: attrs.os == h.os && attrs.channel == h.channel
+                 && lib.versionOlder h.version attrs.current_version;
+          # Note that this is a *reverse* sort!
+          sorter = a: b: lib.versionOlder b.version a.version;
+          sorted = builtins.sort sorter (lib.filter cond history);
+        in map (lib.flip removeAttrs ["os" "channel"]) sorted;
+        version = attrs.current_version;
+      };
+    }) (csv2nix "omahaproxy-info" "http://omahaproxy.appspot.com/all?csv=1"));
+
+    /*
+      XXX: This is essentially the same as:
+
+        builtins.tryEval (builtins.fetchurl url)
+
+      ... except that tryEval on fetchurl isn't working and doesn't catch
+      errors for fetchurl, so we go for a different approach.
+
+      We only have fixed-output derivations that can have networking access, so
+      we abuse SHA1 and its weaknesses to forge a fixed-output derivation which
+      is not so fixed, because it emits different contents that have the same
+      SHA1 hash.
+
+      Using this method, we can distinguish whether the URL is available or
+      whether it's not based on the actual content.
+
+      So let's use tryEval as soon as it's working with fetchurl in Nix.
+    */
+    tryFetch = url: let
+      # SHA1 hash collisions from https://shattered.io/static/shattered.pdf:
+      collisions = runCommand "sha1-collisions" {
+        outputs = [ "out" "good" "bad" ];
+        base64 = ''
+          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
+          NC/4ct6rQkPkQHMcV/8XckU4UJCy+VeTA==
+        '';
+      } ''
+        echo "$base64" | base64 -d | tar xj
+        mv good.pdf "$good"
+        mv bad.pdf "$bad"
+        touch "$out"
+      '';
+
+      cacheVal = let
+        urlHash = builtins.hashString "sha256" url;
+        timeSlice = builtins.currentTime / 600;
+      in "${urlHash}-${toString timeSlice}";
+
+    in {
+      success = import (runCommand "check-success" {
+        result = stdenv.mkDerivation {
+          name = "tryfetch-${cacheVal}";
+          inherit url;
+
+          outputHash = "d00bbe65d80f6d53d5c15da7c6b4f0a655c5a86a";
+          outputHashMode = "flat";
+          outputHashAlgo = "sha1";
+
+          nativeBuildInputs = [ curl ];
+          preferLocalBuild = true;
+
+          inherit (collisions) good bad;
+
+          buildCommand = ''
+            if SSL_CERT_FILE="${cacert}/etc/ssl/certs/ca-bundle.crt" \
+               curl -s -L -f -I "$url" > /dev/null; then
+              cp "$good" "$out"
+            else
+              cp "$bad" "$out"
+            fi
+          '';
+
+          impureEnvVars = lib.fetchers.proxyImpureEnvVars;
+        };
+        inherit (collisions) good;
+      } ''
+        if cmp -s "$result" "$good"; then
+          echo true > "$out"
+        else
+          echo false > "$out"
+        fi
+      '');
+      value = builtins.fetchurl url;
+    };
+
+    fetchLatest = channel: let
+      result = tryFetch (mkVerURL channel.version);
+    in if result.success then result.value else fetchLatest (channel // {
+      version = if channel.history != []
+                then (lib.head channel.history).version
+                else throw "Unfortunately there's no older version than " +
+                           "${channel.version} available for channel " +
+                           "${channel.channel} on ${channel.os}.";
+      history = lib.tail channel.history;
+    });
+
+    getHash = path: import (runCommand "gethash.nix" {
+      inherit path;
+      nativeBuildInputs = [ nix ];
+    } ''
+      sha256="$(nix-hash --flat --base32 --type sha256 "$path")"
+      echo "\"$sha256\"" > "$out"
+    '');
+
+    isLatest = channel: version: let
+      ourVersion = sources.${channel}.version or null;
+    in if ourVersion == null then false
+       else lib.versionOlder version sources.${channel}.version
+         || version == sources.${channel}.version;
+
+    # We only support GNU/Linux right now.
+    linuxChannels = let
+      genLatest = channelName: channel: let
+        newUpstream = {
+          inherit (channel) version;
+          sha256 = getHash (fetchLatest channel);
+        };
+        keepOld = let
+          oldChannel = sources.${channelName};
+        in {
+          inherit (oldChannel) version sha256;
+        } // lib.optionalAttrs (oldChannel ? sha256bin32) {
+          inherit (oldChannel) sha256bin32;
+        } // lib.optionalAttrs (oldChannel ? sha256bin64) {
+          inherit (oldChannel) sha256bin64;
+        };
+      in if isLatest channelName channel.version then keepOld else newUpstream;
+    in lib.mapAttrs genLatest channels.linux;
+
+    getLinuxFlash = channelName: channel: let
+      inherit (channel) version;
+      fetchArch = arch: tryFetch (getDebURL channelName version arch debURL);
+      packages = lib.genAttrs ["i386" "amd64"] fetchArch;
+      isNew = arch: attr: !(builtins.hasAttr attr channel)
+                       && packages.${arch}.success;
+    in channel // lib.optionalAttrs (isNew "i386" "sha256bin32") {
+      sha256bin32 = getHash (packages.i386.value);
+    } // lib.optionalAttrs (isNew "amd64" "sha256bin64") {
+      sha256bin64 = getHash (packages.amd64.value);
+    };
+
+    newChannels = lib.mapAttrs getLinuxFlash linuxChannels;
+
+    dumpAttrs = indent: attrs: let
+      mkVal = val: if lib.isAttrs val then dumpAttrs (indent + 1) val
+                   else "\"${lib.escape ["$" "\\" "\""] (toString val)}\"";
+      mkIndent = level: lib.concatStrings (builtins.genList (_: "  ") level);
+      mkAttr = key: val: "${mkIndent (indent + 1)}${key} = ${mkVal val};\n";
+      attrLines = lib.mapAttrsToList mkAttr attrs;
+    in "{\n" + (lib.concatStrings attrLines) + (mkIndent indent) + "}";
+  in writeText "chromium-new-upstream-info.nix" ''
+    # This file is autogenerated from update.sh in the same directory.
+    ${dumpAttrs 0 newChannels}
+  '';
+}
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/update.sh b/pkgs/applications/networking/browsers/ungoogled-chromium/update.sh
new file mode 100755
index 00000000000..ea67a62c107
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/update.sh
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+cd "$(dirname "$0")"
+sp="$(nix-build --builders "" -Q --no-out-link update.nix -A update)"
+cat "$sp" > upstream-info.nix
diff --git a/pkgs/applications/networking/browsers/ungoogled-chromium/upstream-info.nix b/pkgs/applications/networking/browsers/ungoogled-chromium/upstream-info.nix
new file mode 100644
index 00000000000..c5f9d60122d
--- /dev/null
+++ b/pkgs/applications/networking/browsers/ungoogled-chromium/upstream-info.nix
@@ -0,0 +1,18 @@
+# This file is autogenerated from update.sh in the same directory.
+{
+  beta = {
+    sha256 = "0i0szd749ihb08rxnsmsbxq75b6x952wpk94jwc0ncv6gb83zkx2";
+    sha256bin64 = "1y70kmfz9nv507b0zdda7zfk2ac9qh9m2gq00aphdmzd0al7skj8";
+    version = "81.0.4044.92";
+  };
+  dev = {
+    sha256 = "1rydvjmv62zj95sf0fgsyipqz2hphbxm60y8q0813wq9ym35d4yy";
+    sha256bin64 = "1m6740lw7xjjp1lplwp9ii4d3l7dfa9jrv5bysm4ar5pb9kywrai";
+    version = "83.0.4100.3";
+  };
+  stable = {
+    sha256 = "0i0szd749ihb08rxnsmsbxq75b6x952wpk94jwc0ncv6gb83zkx2";
+    sha256bin64 = "1ig899cpahw1xfhdff5xj6w4k8jja5smxvrcbw6b0jcjmawdrf72";
+    version = "81.0.4044.92";
+  };
+}