Commit 4c051716 authored by Alex Catarineu's avatar Alex Catarineu Committed by Matthew Finkel
Browse files

Bug 40001: Start Tor as part of the Fenix initialization

parent 9134be30
Loading
Loading
Loading
Loading
+35 −6
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ default:
    image: openjdk:8-jdk

    before_script:
        - set -e

        # Prepare our Debian environment.
        - apt-get update -qq
        - apt-get upgrade -qy
@@ -45,6 +47,33 @@ default:
        # Create local.properties file.
        - echo "sdk.dir=$PWD" > local.properties

        # Fetch tor library build dependencies
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor-onion-proxy-library/0.0.3/android-release.aar
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor-onion-proxy-library/0.0.3/universal-0.0.3.jar
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor-android-service/1.0/jsocksAndroid-release.aar
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor-android-service/1.0/service-release.aar
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor/0.4.4.4-rc/tor_x86.tar.gz
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor/0.4.4.4-rc/tor_x86_64.tar.gz
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor/0.4.4.4-rc/tor_armv7.tar.gz
        - wget --quiet https://people.torproject.org/~sysrqb/mirrors/tor/0.4.4.4-rc/tor_aarch64.tar.gz

        - echo "4e2bd087df6128a31c598d297367c106762f539c25d71cc343aae25386e4bee9  android-release.aar" | sha256sum -c
        - echo "0082d1d035a0808d03d7e1009398ed2c3e3ea4c51811198f6ff83ccda456036f  universal-0.0.3.jar" | sha256sum -c
        - echo "3dca44a48fdbd3f6c44f7ea335ae85fe542676d8e48c6438f84a2c852daf4f54  jsocksAndroid-release.aar" | sha256sum -c
        - echo "d38967569af56d809f09f08b888962971149411832c3bc2b7b0b64a43ceb0dcd  service-release.aar" | sha256sum -c
        - echo "0faa344f658d2e38c7cc881f51c1d8658aac56801f7def1b75be72a8d3f90c54  tor_x86.tar.gz" | sha256sum -c
        - echo "acf1d403ca12e3302d1150d2b5fba6585aa83d46db16f15ad33fae39645c5b5d  tor_x86_64.tar.gz" | sha256sum -c
        - echo "132cb40bbc15bd8f72abd15324705ab720f8b316a2fca84baaeb5db37f602c32  tor_armv7.tar.gz" | sha256sum -c
        - echo "6c453c5f7566c87d422ef60750cba794d9616e9197114be5dc1194f75b55b04e  tor_aarch64.tar.gz" | sha256sum -c

        - mv android-release.aar universal-0.0.3.jar jsocksAndroid-release.aar service-release.aar app/

        - tar -C app/src/main -xf tor_x86.tar.gz
        - tar -C app/src/main -xf tor_x86_64.tar.gz
        - tar -C app/src/main -xf tor_armv7.tar.gz
        - tar -C app/src/main -xf tor_aarch64.tar.gz
        - rm tor_x86.tar.gz tor_x86_64.tar.gz tor_armv7.tar.gz tor_aarch64.tar.gz

stages:
    - build
    - buildFenixProduction
@@ -55,7 +84,7 @@ stages:
buildDebug:
    stage: build
    script:
        - ./gradlew clean app:assembleDebug --stacktrace
        - ./gradlew -PdisableTor=true clean app:assembleDebug --stacktrace

    # Disable for now.
    #artifacts:
@@ -69,7 +98,7 @@ testLight:
        # from config/pre-push-recommended.sh
        # `tee` into a log file because resulting output is larger than 4 MB
        # (4 MB is max log size)
        - ./gradlew ktlint detekt assembleDebug assembleDebugAndroidTest testDebug | tee testLight_gradle.log
        - ./gradlew -PdisableTor=true ktlint detekt assembleDebug assembleDebugAndroidTest testDebug | tee testLight_gradle.log
    artifacts:
        paths:
            - testLight_gradle.log
@@ -83,25 +112,25 @@ buildFenixProduction:
    only:
        - schedules
    script:
        - ./gradlew clean app:assembleNightly --stacktrace
        - ./gradlew -PdisableTor=true clean app:assembleNightly --stacktrace

buildFennecBeta:
    stage: buildFennecBeta
    only:
        - schedules
    script:
        - ./gradlew clean app:assembleBeta --stacktrace
        - ./gradlew -PdisableTor=true clean app:assembleBeta --stacktrace

buildFennecProduction:
    stage: buildFennecProduction
    only:
        - schedules
    script:
        - ./gradlew clean app:assembleRelease --stacktrace
        - ./gradlew -PdisableTor=true clean app:assembleRelease --stacktrace

testAll:
    stage: test
    only:
        - schedules
    script:
        - ./gradlew clean test
        - ./gradlew -PdisableTor=true clean test
+20 −0
Original line number Diff line number Diff line
@@ -198,12 +198,20 @@ android.applicationVariants.all { variant ->
    def useReleaseVersioning = variant.buildType.buildConfigFields['USE_RELEASE_VERSIONING']?.value ?: false
    def versionName = Config.releaseVersionName(project)

    def disableTor = false
    if (project.hasProperty("disableTor")) {
        disableTor = project.getProperty("disableTor")
    }

    println("----------------------------------------------")
    println("Variant name:      " + variant.name)
    println("Application ID:    " + [variant.mergedFlavor.applicationId, variant.buildType.applicationIdSuffix].findAll().join())
    println("Build type:        " + variant.buildType.name)
    println("Flavor:            " + variant.flavorName)
    println("Telemetry enabled: " + !isDebugOrDCD)
    println("Tor is disabled:   " + disableTor)

    buildConfigField "boolean", "DISABLE_TOR", "$disableTor"

    if (useReleaseVersioning) {
        // The Google Play Store does not allow multiple APKs for the same app that all have the
@@ -516,6 +524,18 @@ dependencies {
    testImplementation "org.mozilla.telemetry:glean-forUnitTests:${project.ext.glean_version}"

    lintChecks project(":mozilla-lint-rules")

    // Tor Android Services Dependencies
    implementation 'net.freehaven.tor.control:jtorctl:0.2'
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'org.slf4j:slf4j-android:1.7.25'

    // Tor Android Services.
    implementation files('service-release.aar')

    // Tor Onion Proxy Library.
    implementation files('universal-0.0.3.jar')
    implementation files('android-release.aar')
}

if (project.hasProperty("coverage")) {
+7 −0
Original line number Diff line number Diff line
@@ -279,6 +279,13 @@
            android:name="androidx.work.impl.WorkManagerInitializer"
            android:authorities="${applicationId}.workmanager-init"
            tools:node="remove" />
        <!-- Define Orbotservice's TorService -->
        <service
            android:name="org.torproject.android.service.TorService"
            android:enabled="true"
            android:exported="false"
            android:stopWithTask="true">
        </service>
    </application>

</manifest>
+75 −0
Original line number Diff line number Diff line
@@ -4,8 +4,10 @@

package org.mozilla.fenix

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
@@ -24,6 +26,7 @@ import androidx.annotation.VisibleForTesting.PROTECTED
import androidx.appcompat.app.ActionBar
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.navigation.NavDestination
import androidx.navigation.NavDirections
import androidx.navigation.fragment.NavHostFragment
@@ -37,6 +40,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.coroutines.channels.Channel
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
import mozilla.components.browser.state.state.SessionState
@@ -101,6 +106,9 @@ import org.mozilla.fenix.tabtray.TabTrayDialogFragmentDirections
import org.mozilla.fenix.theme.DefaultThemeManager
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.BrowsersCache
import org.torproject.android.service.TorService
import org.torproject.android.service.TorServiceConstants
import org.torproject.android.service.util.Prefs
import java.lang.ref.WeakReference

/**
@@ -153,7 +161,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
    private lateinit var navigationToolbar: Toolbar

    final override fun onCreate(savedInstanceState: Bundle?) {
        // Give Orbot the base Context
        Prefs.setContext(applicationContext)

        components.strictMode.attachListenerToDisablePenaltyDeath(supportFragmentManager)

        // There is disk read violations on some devices such as samsung and pixel for android 9/10
        components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
            super.onCreate(savedInstanceState)
@@ -263,8 +275,63 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
        components.appStartupTelemetry.onHomeActivityOnRestart(rootContainer)
    }

    /**
     * Receive the current Tor status.
     *
     * Send a request for the current status and receive the response.
     * Returns true if Tor is running, false otherwise.
     *
     */
    private suspend fun checkTorIsStarted(): Boolean {
        val channel = Channel<Boolean>()

        // Register receiver
        val lbm: LocalBroadcastManager = LocalBroadcastManager.getInstance(this@HomeActivity)
        val localBroadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                val action = intent.action ?: return
                // We only want ACTION_STATUS messages
                if (action != TorServiceConstants.ACTION_STATUS) {
                    return
                }
                // The current status has the EXTRA_STATUS key
                val currentStatus =
                    intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)
                channel.offer(currentStatus === TorServiceConstants.STATUS_ON)
            }
        }
        lbm.registerReceiver(
            localBroadcastReceiver,
            IntentFilter(TorServiceConstants.ACTION_STATUS)
        )

        // Request service status
        val torServiceStatus = Intent(this@HomeActivity, TorService::class.java)
        torServiceStatus.action = TorServiceConstants.ACTION_STATUS
        startService(torServiceStatus)

        // Wait for response and unregister receiver
        var torIsStarted = false
        withTimeoutOrNull(timeout) {
            torIsStarted = channel.receive()
        }
        lbm.unregisterReceiver(localBroadcastReceiver)
        return torIsStarted
    }

    @CallSuper
    override fun onResume() {
        if (!BuildConfig.DISABLE_TOR) {
            lifecycleScope.launch {
                val torNeedsStart = !checkTorIsStarted()
                if (torNeedsStart) {
                    val torServiceStatus = Intent(this@HomeActivity, TorService::class.java)
                    torServiceStatus.action = TorServiceConstants.ACTION_START
                    startService(torServiceStatus)
                }
            }
        }

        super.onResume()

        // Diagnostic breadcrumb for "Display already aquired" crash:
@@ -370,6 +437,13 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
        )

        privateNotificationObserver?.stop()

        if (BuildConfig.DISABLE_TOR) {
            return
        }

        val torService = Intent(this, TorService::class.java)
        stopService(torService)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
@@ -853,6 +927,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
        const val EXTRA_DELETE_PRIVATE_TABS = "notification_delete_and_open"
        const val EXTRA_OPENED_FROM_NOTIFICATION = "notification_open"
        const val START_IN_RECENTS_SCREEN = "start_in_recents_screen"
        const val timeout = 5000L

        // PWA must have been used within last 30 days to be considered "recently used" for the
        // telemetry purposes.
+5 −0
Original line number Diff line number Diff line
@@ -127,6 +127,11 @@ allprojects {
                }
            }
        }

        // These are needed for Orbot's dependencies.
        maven { url "https://raw.githubusercontent.com/guardianproject/gpmaven/master" }
        maven { url 'https://jitpack.io' }
        jcenter()
    }

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {