Pop out privacy notice in first launch in MozillaOnline builds

Add privacy notice related strings

Pop out privacy notice with onboarding

Using embeded geckoview to display details about privacy

Present or hide privacy pop window according to isMozillaOnline

Add activity_privacy_content_display.xml into layoutNotToTest due to EngineView
upstream-sync
rxu 4 years ago committed by Arturo Mejia
parent e188185b15
commit be0382fca7

@ -119,6 +119,9 @@
</intent-filter>
</activity>
<activity android:name=".home.mozonline.PrivacyContentDisplayActivity"
android:exported="false"/>
<activity
android:name=".customtabs.ExternalAppBrowserActivity"
android:autoRemoveFromRecents="false"

@ -120,6 +120,8 @@ import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.whatsnew.WhatsNew
import java.lang.ref.WeakReference
import kotlin.math.min
import org.mozilla.fenix.Config
import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow
@ExperimentalCoroutinesApi
@Suppress("TooManyFunctions", "LargeClass")
@ -175,6 +177,12 @@ class HomeFragment : Fragment() {
requireComponents.analytics.metrics.track(Event.OpenedAppFirstRun)
}
}
if (!onboarding.userHasBeenOnboarded() &&
requireContext().settings().shouldShowPrivacyPopWindow &&
Config.channel.isMozillaOnline) {
showPrivacyPopWindow(requireContext(), requireActivity())
}
}
@Suppress("LongMethod")

@ -0,0 +1,84 @@
/* 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.fenix.home.mozonline
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.View
import android.widget.ImageButton
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineView
import mozilla.components.feature.contextmenu.DefaultSelectionActionDelegate
import mozilla.components.feature.search.BrowserStoreSearchAdapter
import mozilla.components.support.ktx.android.content.call
import mozilla.components.support.ktx.android.content.email
import mozilla.components.support.ktx.android.content.share
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
/**
* A special activity for displaying the detail content about privacy hyperlinked in alert dialog.
*/
class PrivacyContentDisplayActivity : Activity(), EngineSession.Observer {
private lateinit var engineView: EngineView
private lateinit var closeButton: ImageButton
private lateinit var engineSession: EngineSession
private var url: String? = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_privacy_content_display)
val addr = intent.extras
if (addr != null) {
url = addr.getString("url")
}
engineView = findViewById<View>(R.id.privacyContentEngineView) as EngineView
closeButton = findViewById<View>(R.id.privacyContentCloseButton) as ImageButton
engineSession = components.core.engine.createSession()
}
override fun onCreateView(
parent: View?,
name: String,
context: Context,
attrs: AttributeSet
): View? = when (name) {
EngineView::class.java.name -> components.core.engine.createView(context, attrs).apply {
selectionActionDelegate = DefaultSelectionActionDelegate(
BrowserStoreSearchAdapter(
components.core.store
),
resources = context.resources,
shareTextClicked = { share(it) },
emailTextClicked = { email(it) },
callTextClicked = { call(it) }
)
}.asView()
else -> super.onCreateView(parent, name, context, attrs)
}
override fun onStart() {
super.onStart()
engineSession.register(this)
engineSession.let { engineSession ->
engineView.render(engineSession)
url?.let { engineSession.loadUrl(it) }
}
closeButton.setOnClickListener { finish() }
}
override fun onStop() {
super.onStop()
engineSession.unregister(this)
}
override fun onDestroy() {
super.onDestroy()
engineSession.close()
}
}

@ -0,0 +1,53 @@
/* 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.fenix.home.mozonline
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.text.SpannableString
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import kotlin.system.exitProcess
fun showPrivacyPopWindow(context: Context, activity: Activity) {
val content = context.getString(R.string.privacy_notice_content)
// Use hyperlinks to display details about privacy
val messageClickable1 = context.getString(R.string.privacy_notice_clickable1)
val messageClickable2 = context.getString(R.string.privacy_notice_clickable2)
val messageClickable3 = context.getString(R.string.privacy_notice_clickable3)
val messageSpannable = SpannableString(content)
val clickableSpan1 = PrivacyContentSpan(Position.POS1, context)
val clickableSpan2 = PrivacyContentSpan(Position.POS2, context)
val clickableSpan3 = PrivacyContentSpan(Position.POS3, context)
messageSpannable.setSpan(clickableSpan1, content.indexOf(messageClickable1),
content.indexOf(messageClickable1) + messageClickable1.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
messageSpannable.setSpan(clickableSpan2, content.indexOf(messageClickable2),
content.indexOf(messageClickable2) + messageClickable2.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
messageSpannable.setSpan(clickableSpan3, content.indexOf(messageClickable3),
content.indexOf(messageClickable3) + messageClickable3.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
// Users can only use fenix after they agree with the privacy notice
val builder = AlertDialog.Builder(activity)
.setPositiveButton(context.getString(R.string.privacy_notice_positive_button),
DialogInterface.OnClickListener { _, _ ->
context.settings().shouldShowPrivacyPopWindow = false
})
.setNeutralButton(context.getString(R.string.privacy_notice_neutral_button),
DialogInterface.OnClickListener { _, _ -> exitProcess(0) })
.setTitle(context.getString(R.string.privacy_notice_title))
.setMessage(messageSpannable)
.setCancelable(false)
val alertDialog: AlertDialog = builder.create()
alertDialog.show()
alertDialog.findViewById<TextView>(android.R.id.message)?.movementMethod = LinkMovementMethod.getInstance()
}

@ -0,0 +1,44 @@
/* 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.fenix.home.mozonline
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.style.ClickableSpan
import android.view.View
object Position {
const val POS1 = 1
const val POS2 = 2
const val POS3 = 3
}
object ADDR {
const val URL1 = "https://www.mozilla.org/en-US/MPL/"
const val URL2 = "https://www.mozilla.org/en-US/foundation/trademarks/policy/"
const val URL3 = "https://www.mozilla.org/zh-CN/privacy/firefox/"
}
class PrivacyContentSpan(var pos: Int, var context: Context) :
ClickableSpan() {
override fun onClick(widget: View) {
/**
* To avoid users directly using fenix by clicking these urls before
* they click positive button of privacy notice alert dialog, start
* PrivacyContentDisplayActivity to display them.
*/
val engineViewIntent = Intent(context, PrivacyContentDisplayActivity::class.java)
engineViewIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
val addr = Bundle()
when (pos) {
Position.POS1 -> addr.putString("url", ADDR.URL1)
Position.POS2 -> addr.putString("url", ADDR.URL2)
Position.POS3 -> addr.putString("url", ADDR.URL3)
}
engineViewIntent.putExtras(addr)
context.startActivity(engineViewIntent)
}
}

@ -252,6 +252,11 @@ class Settings(private val appContext: Context) : PreferencesHolder {
val shouldShowSecurityPinWarning: Boolean
get() = loginsSecureWarningCount.underMaxCount()
var shouldShowPrivacyPopWindow by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_privacy_pop_window),
default = true
)
var shouldUseLightTheme by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_light_theme),
default = false

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/browser_actions_divider_color">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:background="@android:color/transparent"
android:id="@+id/privacyContentCloseButton"
android:src="@drawable/ic_close"
android:contentDescription="close"
tools:ignore="AndroidSrcXmlDetector" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="@android:color/darker_gray"/>
</LinearLayout>
<mozilla.components.concept.engine.EngineView
tools:ignore="Instantiatable"
android:id="@+id/privacyContentEngineView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Privacy Notice-->
<!-- Privacy Notice title-->
<string name="privacy_notice_title">关于您的权利</string>
<!-- Privacy Notice content-->
<string name="privacy_notice_content">Mozilla Firefox 是一款自由开源软件,由来自世界各地成千上万的社区志愿者共同完成。以下几点您应该了解:
\n\n•Firefox 提供给您时依照的条款为 Mozilla 公共许可证MPL。这表示您可以使用、复制和向他人分发 Firefox。我们也非常欢迎您按自己的需要修改 Firefox 的源代码。Mozilla 公共许可证还授予您分发您自己修改过的软件版本的权利。
\n•您没有获得 Mozilla 基金会或其他任何一方的商标权利或许可,这包括但不限于 Firefox 的名称或标志。有关商标的其他信息在:这里。
\n•Firefox 的一些功能(例如崩溃报告器)使您可以向 Mozilla 提供反馈。提交反馈的同时,您授权 Mozilla 使用反馈信息改进产品、在其网站上发布反馈信息,以及分发反馈内容。
\n•关于我们如何使用您通过 Firefox 提交给 Mozilla 的个人信息和反馈,请参见 Firefox 隐私权政策。</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable1">Mozilla 公共许可证MPL</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable2">这里</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable3">Firefox 隐私权政策</string>
<!-- Privacy Notice positive button-->
<string name="privacy_notice_positive_button">同意并继续</string>
<!-- Privacy Notice neutral button-->
<string name="privacy_notice_neutral_button">退出应用</string>
</resources>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Privacy Notice-->
<!-- Privacy Notice title-->
<string name="privacy_notice_title">About your rights</string>
<!-- Privacy Notice content-->
<string name="privacy_notice_content">Mozilla Firefox is free and open source software, built by a community of thousands from all over the world. There are a few things you should know:
\n\n•Firefox is made available to you under the terms of the Mozilla Public License. This means you may use, copy and distribute Firefox to others. You are also welcome to modify the source code of Firefox as you want to meet your needs. The Mozilla Public License also gives you the right to distribute your modified versions.
\n•You are not granted any trademark rights or licenses to the trademarks of the Mozilla Foundation or any party, including without limitation the Firefox name or logo. Additional information on trademarks may be found here.
\n•Some features in Firefox, such as the Crash Reporter, give you the option to provide feedback to Mozilla. By choosing to submit feedback, you give Mozilla permission to use the feedback to improve its products, to publish the feedback on its websites, and to distribute the feedback.
\n•How we use your personal information and feedback submitted to Mozilla through Firefox is described in the Firefox Privacy Policy.</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable1">Mozilla Public License</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable2">found here</string>
<!-- Privacy Notice clickable-->
<string name="privacy_notice_clickable3">Firefox Privacy Policy</string>
<!-- Privacy Notice positive button-->
<string name="privacy_notice_positive_button">Agree and Continue</string>
<!-- Privacy Notice neutral button-->
<string name="privacy_notice_neutral_button">Exit the App</string>
</resources>

@ -126,6 +126,9 @@
<string name="pref_key_toolbar_top" translatable="false">pref_key_toolbar_top</string>
<string name="pref_key_toolbar_bottom" translatable="false">pref_key_toolbar_bottom</string>
<!-- Privacy Pop Window -->
<string name="pref_key_privacy_pop_window" translatable="false">pref_key_privacy_pop_window</string>
<!-- Theme Settings -->
<string name="pref_key_light_theme" translatable="false">pref_key_light_theme</string>
<string name="pref_key_dark_theme" translatable="false">pref_key_dark_theme</string>

@ -26,7 +26,8 @@ class PerformanceInflaterTest {
private val layoutsNotToTest = setOf(
"fragment_browser",
"fragment_add_on_internal_settings"
"fragment_add_on_internal_settings",
"activity_privacy_content_display"
)
@Before

Loading…
Cancel
Save