Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gaba
fenix
Commits
49b617c9
Unverified
Commit
49b617c9
authored
Jun 25, 2020
by
Mihai Branescu
Committed by
GitHub
Jun 24, 2020
Browse files
For #9100 - Private browsing notification fixes
Co-authored-by: Seef <Saif Dara>
parent
632b6497
Changes
6
Hide whitespace changes
Inline
Side-by-side
app/src/main/java/org/mozilla/fenix/FenixApplication.kt
View file @
49b617c9
...
...
@@ -43,7 +43,6 @@ import org.mozilla.fenix.ext.settings
import
org.mozilla.fenix.perf.StartupTimeline
import
org.mozilla.fenix.push.PushFxaIntegration
import
org.mozilla.fenix.push.WebPushEngineIntegration
import
org.mozilla.fenix.session.NotificationSessionObserver
import
org.mozilla.fenix.session.PerformanceActivityLifecycleCallbacks
import
org.mozilla.fenix.session.VisibilityLifecycleCallback
import
org.mozilla.fenix.utils.BrowsersCache
...
...
@@ -157,9 +156,6 @@ open class FenixApplication : LocaleAwareApplication() {
visibilityLifecycleCallback
=
VisibilityLifecycleCallback
(
getSystemService
())
registerActivityLifecycleCallbacks
(
visibilityLifecycleCallback
)
val
privateNotificationObserver
=
NotificationSessionObserver
(
this
)
privateNotificationObserver
.
start
()
// Storage maintenance disabled, for now, as it was interfering with background migrations.
// See https://github.com/mozilla-mobile/fenix/issues/7227 for context.
// if ((System.currentTimeMillis() - settings().lastPlacesStorageMaintenance) > ONE_DAY_MILLIS) {
...
...
app/src/main/java/org/mozilla/fenix/HomeActivity.kt
View file @
49b617c9
...
...
@@ -74,6 +74,7 @@ import org.mozilla.fenix.library.history.HistoryFragmentDirections
import
org.mozilla.fenix.perf.Performance
import
org.mozilla.fenix.perf.StartupTimeline
import
org.mozilla.fenix.search.SearchFragmentDirections
import
org.mozilla.fenix.session.NotificationSessionObserver
import
org.mozilla.fenix.settings.SettingsFragmentDirections
import
org.mozilla.fenix.settings.TrackingProtectionFragmentDirections
import
org.mozilla.fenix.settings.about.AboutFragmentDirections
...
...
@@ -154,6 +155,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
sessionObserver
=
UriOpenedObserver
(
this
)
checkPrivateShortcutEntryPoint
(
intent
)
val
privateNotificationObserver
=
NotificationSessionObserver
(
this
)
privateNotificationObserver
.
start
()
if
(
isActivityColdStarted
(
intent
,
savedInstanceState
))
{
externalSourceIntentProcessors
.
any
{
it
.
process
(
intent
,
navHost
.
navController
,
this
.
intent
)
}
}
...
...
@@ -176,6 +181,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
StartupTimeline
.
homeActivityLifecycleObserver
)
StartupTimeline
.
onActivityCreateEndHome
(
this
)
if
(
shouldAddToRecentsScreen
(
intent
))
{
intent
.
removeExtra
(
START_IN_RECENTS_SCREEN
)
moveTaskToBack
(
true
)
}
}
@CallSuper
...
...
@@ -313,6 +323,30 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
return
settings
().
lastKnownMode
}
/**
* Determines whether the activity should be pushed to be backstack (i.e., 'minimized' to the recents
* screen) upon starting.
* @param intent - The intent that started this activity. Is checked for having the 'START_IN_RECENTS_SCREEN'-extra.
* @return true if the activity should be started and pushed to the recents screen, false otherwise.
*/
private
fun
shouldAddToRecentsScreen
(
intent
:
Intent
?):
Boolean
{
intent
?.
toSafeIntent
()
?.
let
{
return
it
.
getBooleanExtra
(
START_IN_RECENTS_SCREEN
,
false
)
}
return
false
}
private
fun
checkPrivateShortcutEntryPoint
(
intent
:
Intent
)
{
if
(
intent
.
hasExtra
(
OPEN_TO_SEARCH
)
&&
(
intent
.
getStringExtra
(
OPEN_TO_SEARCH
)
==
StartSearchIntentProcessor
.
STATIC_SHORTCUT_NEW_PRIVATE_TAB
||
intent
.
getStringExtra
(
OPEN_TO_SEARCH
)
==
StartSearchIntentProcessor
.
PRIVATE_BROWSING_PINNED_SHORTCUT
)
)
{
NotificationSessionObserver
.
isStartedFromPrivateShortcut
=
true
}
}
private
fun
setupThemeAndBrowsingMode
(
mode
:
BrowsingMode
)
{
settings
().
lastKnownMode
=
mode
browsingModeManager
=
createBrowsingModeManager
(
mode
)
...
...
@@ -499,5 +533,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
const
val
EXTRA_DELETE_PRIVATE_TABS
=
"notification_delete_and_open"
const
val
EXTRA_OPENED_FROM_NOTIFICATION
=
"notification_open"
const
val
delay
=
5000L
const
val
START_IN_RECENTS_SCREEN
=
"start_in_recents_screen"
}
}
app/src/main/java/org/mozilla/fenix/session/NotificationSessionObserver.kt
View file @
49b617c9
...
...
@@ -34,7 +34,7 @@ class NotificationSessionObserver(
.
ifChanged
()
.
collect
{
hasPrivateTabs
->
if
(
hasPrivateTabs
)
{
notificationService
.
start
(
context
)
notificationService
.
start
(
context
,
isStartedFromPrivateShortcut
)
started
=
true
}
else
if
(
started
)
{
notificationService
.
stop
(
context
)
...
...
@@ -47,4 +47,8 @@ class NotificationSessionObserver(
fun
stop
()
{
scope
?.
cancel
()
}
companion
object
{
var
isStartedFromPrivateShortcut
=
false
}
}
app/src/main/java/org/mozilla/fenix/session/SessionNotificationService.kt
View file @
49b617c9
...
...
@@ -37,32 +37,41 @@ import org.mozilla.fenix.ext.sessionsOfType
*/
class
SessionNotificationService
:
Service
()
{
private
var
isStartedFromPrivateShortcut
:
Boolean
=
false
override
fun
onStartCommand
(
intent
:
Intent
,
flags
:
Int
,
startId
:
Int
):
Int
{
val
action
=
intent
.
action
?:
return
Service
.
START_NOT_STICKY
val
action
=
intent
.
action
?:
return
START_NOT_STICKY
when
(
action
)
{
ACTION_START
->
{
isStartedFromPrivateShortcut
=
intent
.
getBooleanExtra
(
STARTED_FROM_PRIVATE_SHORTCUT
,
false
)
createNotificationChannelIfNeeded
()
startForeground
(
NOTIFICATION_ID
,
buildNotification
())
}
ACTION_ERASE
->
{
metrics
.
track
(
Event
.
PrivateBrowsingNotificationTapped
)
components
.
core
.
sessionManager
.
removeAndCloseAllPrivateSessions
()
if
(!
VisibilityLifecycleCallback
.
finishAndRemoveTaskIfInBackground
(
this
))
{
startActivity
(
Intent
(
this
,
HomeActivity
::
class
.
java
).
apply
{
this
.
flags
=
Intent
.
FLAG_ACTIVITY_NEW_TASK
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
}
)
val
homeScreenIntent
=
Intent
(
this
,
HomeActivity
::
class
.
java
)
val
intentFlags
=
Intent
.
FLAG_ACTIVITY_NEW_TASK
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
homeScreenIntent
.
apply
{
setFlags
(
intentFlags
)
putExtra
(
HomeActivity
.
PRIVATE_BROWSING_MODE
,
isStartedFromPrivateShortcut
)
}
if
(
VisibilityLifecycleCallback
.
finishAndRemoveTaskIfInBackground
(
this
))
{
// Set start mode to be in background (recents screen)
homeScreenIntent
.
apply
{
putExtra
(
HomeActivity
.
START_IN_RECENTS_SCREEN
,
true
)
}
}
startActivity
(
homeScreenIntent
)
components
.
core
.
sessionManager
.
removeAndCloseAllPrivateSessions
()
}
else
->
throw
IllegalStateException
(
"Unknown intent: $intent"
)
}
return
Service
.
START_NOT_STICKY
return
START_NOT_STICKY
}
override
fun
onTaskRemoved
(
rootIntent
:
Intent
)
{
...
...
@@ -125,13 +134,18 @@ class SessionNotificationService : Service() {
companion
object
{
private
const
val
NOTIFICATION_ID
=
83
private
const
val
NOTIFICATION_CHANNEL_ID
=
"browsing-session"
private
const
val
STARTED_FROM_PRIVATE_SHORTCUT
=
"STARTED_FROM_PRIVATE_SHORTCUT"
private
const
val
ACTION_START
=
"start"
private
const
val
ACTION_ERASE
=
"erase"
internal
fun
start
(
context
:
Context
)
{
internal
fun
start
(
context
:
Context
,
startedFromPrivateShortcut
:
Boolean
)
{
val
intent
=
Intent
(
context
,
SessionNotificationService
::
class
.
java
)
intent
.
action
=
ACTION_START
intent
.
putExtra
(
STARTED_FROM_PRIVATE_SHORTCUT
,
startedFromPrivateShortcut
)
// From Focus #2901: The application is crashing due to the service not calling `startForeground`
// before it times out. This is a speculative fix to decrease the time between these two
...
...
app/src/main/java/org/mozilla/fenix/session/VisibilityLifecycleCallback.kt
View file @
49b617c9
...
...
@@ -25,6 +25,13 @@ class VisibilityLifecycleCallback(private val activityManager: ActivityManager?)
*/
private
var
activitiesInStartedState
:
Int
=
0
/**
* Finishes and removes the list of AppTasks only if the application is in the background.
* The application is considered to be in the background if it has at least 1 Activity in the
* started state
* @return True if application is in background (also finishes and removes all AppTasks),
* false otherwise
*/
private
fun
finishAndRemoveTaskIfInBackground
():
Boolean
{
if
(
activitiesInStartedState
==
0
)
{
activityManager
?.
let
{
...
...
@@ -59,6 +66,9 @@ class VisibilityLifecycleCallback(private val activityManager: ActivityManager?)
/**
* If all activities of this app are in the background then finish and remove all tasks. After
* that the app won't show up in "recent apps" anymore.
*
* @return True if application is in background (and consequently, finishes and removes all tasks),
* false otherwise.
*/
internal
fun
finishAndRemoveTaskIfInBackground
(
context
:
Context
):
Boolean
{
return
(
context
.
applicationContext
as
FenixApplication
)
...
...
app/src/test/java/org/mozilla/fenix/session/NotificationSessionObserverTest.kt
View file @
49b617c9
...
...
@@ -35,6 +35,7 @@ class NotificationSessionObserverTest {
store
=
BrowserStore
()
every
{
context
.
components
.
core
.
store
}
returns
store
observer
=
NotificationSessionObserver
(
context
,
notificationService
)
NotificationSessionObserver
.
isStartedFromPrivateShortcut
=
false
}
@Test
...
...
@@ -44,7 +45,7 @@ class NotificationSessionObserverTest {
store
.
dispatch
(
TabListAction
.
AddTabAction
(
privateSession
)).
join
()
observer
.
start
()
verify
(
exactly
=
1
)
{
notificationService
.
start
(
context
)
}
verify
(
exactly
=
1
)
{
notificationService
.
start
(
context
,
false
)
}
confirmVerified
(
notificationService
)
}
...
...
@@ -57,10 +58,10 @@ class NotificationSessionObserverTest {
verify
{
notificationService
wasNot
Called
}
store
.
dispatch
(
TabListAction
.
AddTabAction
(
normalSession
)).
join
()
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
)
}
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
,
false
)
}
store
.
dispatch
(
CustomTabListAction
.
AddCustomTabAction
(
customSession
)).
join
()
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
)
}
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
,
false
)
}
}
@Test
...
...
@@ -74,9 +75,9 @@ class NotificationSessionObserverTest {
verify
{
notificationService
wasNot
Called
}
store
.
dispatch
(
CustomTabListAction
.
AddCustomTabAction
(
privateCustomSession
)).
join
()
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
)
}
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
,
false
)
}
store
.
dispatch
(
CustomTabListAction
.
AddCustomTabAction
(
customSession
)).
join
()
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
)
}
verify
(
exactly
=
0
)
{
notificationService
.
start
(
context
,
false
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment