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
The Tor Project
Applications
android-components
Commits
a1e401ac
Commit
a1e401ac
authored
Jul 01, 2020
by
Sawyer Blatz
Browse files
For #7586: Add email & call actions to context menu
parent
0e3db53a
Changes
15
Hide whitespace changes
Inline
Side-by-side
components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -41,8 +41,10 @@ open class GeckoSelectionActionDelegate(
}
override
fun
isActionAvailable
(
id
:
String
):
Boolean
{
val
customActionIsAvailable
=
customDelegate
.
isActionAvailable
(
id
)
&&
!
mSelection
?.
text
.
isNullOrEmpty
()
val
selectedText
=
mSelection
?.
text
val
customActionIsAvailable
=
!
selectedText
.
isNullOrEmpty
()
&&
customDelegate
.
isActionAvailable
(
id
,
selectedText
)
return
customActionIsAvailable
||
super
.
isActionAvailable
(
id
)
...
...
components/browser/engine-gecko-beta/src/test/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegateTest.kt
View file @
a1e401ac
...
...
@@ -39,7 +39,7 @@ class GeckoSelectionActionDelegateTest {
val
customActions
=
arrayOf
(
"1"
,
"2"
,
"3"
)
val
customDelegate
=
object
:
SelectionActionDelegate
{
override
fun
getAllActions
():
Array
<
String
>
=
customActions
override
fun
isActionAvailable
(
id
:
String
):
Boolean
=
false
override
fun
isActionAvailable
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
getActionTitle
(
id
:
String
):
CharSequence
?
=
""
override
fun
performAction
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
sortedActions
(
actions
:
Array
<
String
>):
Array
<
String
>
{
...
...
components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -41,8 +41,10 @@ open class GeckoSelectionActionDelegate(
}
override
fun
isActionAvailable
(
id
:
String
):
Boolean
{
val
customActionIsAvailable
=
customDelegate
.
isActionAvailable
(
id
)
&&
!
mSelection
?.
text
.
isNullOrEmpty
()
val
selectedText
=
mSelection
?.
text
val
customActionIsAvailable
=
!
selectedText
.
isNullOrEmpty
()
&&
customDelegate
.
isActionAvailable
(
id
,
selectedText
)
return
customActionIsAvailable
||
super
.
isActionAvailable
(
id
)
...
...
components/browser/engine-gecko-nightly/src/test/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegateTest.kt
View file @
a1e401ac
...
...
@@ -39,7 +39,7 @@ class GeckoSelectionActionDelegateTest {
val
customActions
=
arrayOf
(
"1"
,
"2"
,
"3"
)
val
customDelegate
=
object
:
SelectionActionDelegate
{
override
fun
getAllActions
():
Array
<
String
>
=
customActions
override
fun
isActionAvailable
(
id
:
String
):
Boolean
=
false
override
fun
isActionAvailable
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
getActionTitle
(
id
:
String
):
CharSequence
?
=
""
override
fun
performAction
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
sortedActions
(
actions
:
Array
<
String
>):
Array
<
String
>
{
...
...
components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -41,8 +41,10 @@ open class GeckoSelectionActionDelegate(
}
override
fun
isActionAvailable
(
id
:
String
):
Boolean
{
val
customActionIsAvailable
=
customDelegate
.
isActionAvailable
(
id
)
&&
!
mSelection
?.
text
.
isNullOrEmpty
()
val
selectedText
=
mSelection
?.
text
val
customActionIsAvailable
=
!
selectedText
.
isNullOrEmpty
()
&&
customDelegate
.
isActionAvailable
(
id
,
selectedText
)
return
customActionIsAvailable
||
super
.
isActionAvailable
(
id
)
...
...
components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/selection/GeckoSelectionActionDelegateTest.kt
View file @
a1e401ac
...
...
@@ -39,7 +39,7 @@ class GeckoSelectionActionDelegateTest {
val
customActions
=
arrayOf
(
"1"
,
"2"
,
"3"
)
val
customDelegate
=
object
:
SelectionActionDelegate
{
override
fun
getAllActions
():
Array
<
String
>
=
customActions
override
fun
isActionAvailable
(
id
:
String
):
Boolean
=
false
override
fun
isActionAvailable
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
getActionTitle
(
id
:
String
):
CharSequence
?
=
""
override
fun
performAction
(
id
:
String
,
selectedText
:
String
):
Boolean
=
false
override
fun
sortedActions
(
actions
:
Array
<
String
>):
Array
<
String
>
{
...
...
components/concept/engine/src/main/java/mozilla/components/concept/engine/selection/SelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -19,9 +19,10 @@ interface SelectionActionDelegate {
/**
* Checks if an action can be shown on a new selection context menu.
*
* @returns whether or not the the custom action with the id of [id] is currently available.
* @returns whether or not the the custom action with the id of [id] is currently available
* which may be informed by [selectedText].
*/
fun
isActionAvailable
(
id
:
String
):
Boolean
fun
isActionAvailable
(
id
:
String
,
selectedText
:
String
):
Boolean
/**
* Gets a title to be shown in the selection context menu.
...
...
components/feature/contextmenu/src/main/java/mozilla/components/feature/contextmenu/DefaultSelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -5,6 +5,7 @@
package
mozilla.components.feature.contextmenu
import
android.content.res.Resources
import
android.util.Patterns
import
androidx.annotation.VisibleForTesting
import
mozilla.components.feature.search.SearchAdapter
import
mozilla.components.concept.engine.selection.SelectionActionDelegate
...
...
@@ -15,16 +16,24 @@ internal const val SEARCH = "CUSTOM_CONTEXT_MENU_SEARCH"
internal
const
val
SEARCH_PRIVATELY
=
"CUSTOM_CONTEXT_MENU_SEARCH_PRIVATELY"
@VisibleForTesting
(
otherwise
=
VisibleForTesting
.
PRIVATE
)
internal
const
val
SHARE
=
"CUSTOM_CONTEXT_MENU_SHARE"
@VisibleForTesting
(
otherwise
=
VisibleForTesting
.
PRIVATE
)
internal
const
val
EMAIL
=
"CUSTOM_CONTEXT_MENU_EMAIL"
@VisibleForTesting
(
otherwise
=
VisibleForTesting
.
PRIVATE
)
internal
const
val
CALL
=
"CUSTOM_CONTEXT_MENU_CALL"
private
val
customActions
=
arrayOf
(
SEARCH
,
SEARCH_PRIVATELY
,
SHARE
)
private
val
customActions
=
arrayOf
(
CALL
,
EMAIL
,
SEARCH
,
SEARCH_PRIVATELY
,
SHARE
)
/**
* Adds normal and private search buttons to text selection context menus.
* Also adds share, email, and call actions which are optionally displayed.
*/
@Suppress
(
"LongParameterList"
)
class
DefaultSelectionActionDelegate
(
private
val
searchAdapter
:
SearchAdapter
,
resources
:
Resources
,
private
val
shareTextClicked
:
((
String
)
->
Unit
)?
=
null
,
private
val
emailTextClicked
:
((
String
)
->
Unit
)?
=
null
,
private
val
callTextClicked
:
((
String
)
->
Unit
)?
=
null
,
private
val
actionSorter
:
((
Array
<
String
>)
->
Array
<
String
>)?
=
null
)
:
SelectionActionDelegate
{
...
...
@@ -33,12 +42,17 @@ class DefaultSelectionActionDelegate(
private
val
privateSearchText
=
resources
.
getString
(
R
.
string
.
mozac_selection_context_menu_search_privately_2
)
private
val
shareText
=
resources
.
getString
(
R
.
string
.
mozac_selection_context_menu_share
)
private
val
emailText
=
resources
.
getString
(
R
.
string
.
mozac_selection_context_menu_email
)
private
val
callText
=
resources
.
getString
(
R
.
string
.
mozac_selection_context_menu_call
)
override
fun
getAllActions
():
Array
<
String
>
=
customActions
override
fun
isActionAvailable
(
id
:
String
):
Boolean
{
@SuppressWarnings
(
"ComplexMethod"
)
override
fun
isActionAvailable
(
id
:
String
,
selectedText
:
String
):
Boolean
{
val
isPrivate
=
searchAdapter
.
isPrivateSession
()
return
(
id
==
SHARE
&&
shareTextClicked
!=
null
)
||
(
id
==
EMAIL
&&
emailTextClicked
!=
null
&&
Patterns
.
EMAIL_ADDRESS
.
matcher
(
selectedText
).
matches
())
||
(
id
==
CALL
&&
callTextClicked
!=
null
&&
Patterns
.
PHONE
.
matcher
(
selectedText
).
matches
())
||
(
id
==
SEARCH
&&
!
isPrivate
)
||
(
id
==
SEARCH_PRIVATELY
&&
isPrivate
)
}
...
...
@@ -47,6 +61,8 @@ class DefaultSelectionActionDelegate(
SEARCH
->
normalSearchText
SEARCH_PRIVATELY
->
privateSearchText
SHARE
->
shareText
EMAIL
->
emailText
CALL
->
callText
else
->
null
}
...
...
@@ -63,6 +79,14 @@ class DefaultSelectionActionDelegate(
shareTextClicked
?.
invoke
(
selectedText
)
true
}
EMAIL
->
{
emailTextClicked
?.
invoke
(
selectedText
)
true
}
CALL
->
{
callTextClicked
?.
invoke
(
selectedText
)
true
}
else
->
false
}
...
...
components/feature/contextmenu/src/main/java/mozilla/components/feature/contextmenu/ext/DefaultSelectionActionDelegate.kt
View file @
a1e401ac
...
...
@@ -8,6 +8,9 @@ import android.content.Context
import
mozilla.components.browser.state.store.BrowserStore
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
/**
* More convenient secondary constructor for creating a [DefaultSelectionActionDelegate].
...
...
@@ -16,10 +19,14 @@ import mozilla.components.feature.search.BrowserStoreSearchAdapter
fun
DefaultSelectionActionDelegate
(
store
:
BrowserStore
,
context
:
Context
,
shareTextClicked
:
((
String
)
->
Unit
)?
=
null
shareTextClicked
:
((
String
)
->
Unit
)?
=
{
context
.
share
(
it
)
},
emailTextClicked
:
((
String
)
->
Unit
)?
=
{
context
.
email
(
it
)
},
callTextClicked
:
((
String
)
->
Unit
)?
=
{
context
.
call
(
it
)
}
)
=
DefaultSelectionActionDelegate
(
BrowserStoreSearchAdapter
(
store
),
context
.
resources
,
shareTextClicked
shareTextClicked
,
emailTextClicked
,
callTextClicked
)
components/feature/contextmenu/src/main/res/values/strings.xml
View file @
a1e401ac
...
...
@@ -39,4 +39,8 @@
<string
name=
"mozac_selection_context_menu_search_privately_2"
>
Private Search
</string>
<!-- Action shown in a text selection context menu. This will prompt a share of the selected text. -->
<string
name=
"mozac_selection_context_menu_share"
>
Share
</string>
<!-- Action shown in a text selection context menu. This will prompt a new email from the selected text. -->
<string
name=
"mozac_selection_context_menu_email"
>
Email
</string>
<!-- Action shown in a text selection context menu. This will prompt a new call from the selected text. -->
<string
name=
"mozac_selection_context_menu_call"
>
Call
</string>
</resources>
\ No newline at end of file
components/feature/contextmenu/src/test/java/mozilla/components/feature/contextmenu/DefaultSelectionActionDelegateTest.kt
View file @
a1e401ac
package
mozilla.components.feature.contextmenu
import
android.content.res.Resources
import
androidx.test.ext.junit.runners.AndroidJUnit4
import
mozilla.components.feature.search.SearchAdapter
import
mozilla.components.support.test.mock
import
mozilla.components.support.test.whenever
...
...
@@ -8,30 +9,41 @@ import org.junit.Assert.assertEquals
import
org.junit.Assert.assertFalse
import
org.junit.Assert.assertTrue
import
org.junit.Test
import
org.junit.runner.RunWith
import
org.mockito.Mockito.anyBoolean
import
org.mockito.Mockito.anyString
import
org.mockito.Mockito.times
import
org.mockito.Mockito.verify
@RunWith
(
AndroidJUnit4
::
class
)
class
DefaultSelectionActionDelegateTest
{
val
selectedRegularText
=
"mozilla"
val
selectedEmailText
=
"test@mozilla.org"
val
selectedPhoneText
=
"555-5555"
var
lambdaValue
:
String
?
=
null
val
shareClicked
:
(
String
)
->
Unit
=
{
lambdaValue
=
it
}
val
emailClicked
:
(
String
)
->
Unit
=
{
lambdaValue
=
it
}
val
phoneClicked
:
(
String
)
->
Unit
=
{
lambdaValue
=
it
}
@Test
fun
`are
non-private
actions
available`
()
{
fun
`are
non-private
regular
actions
available`
()
{
val
searchAdapter
=
mock
<
SearchAdapter
>
{
whenever
(
isPrivateSession
()).
thenReturn
(
false
)
}
val
delegate
=
DefaultSelectionActionDelegate
(
searchAdapter
,
getTestResources
(),
shareClicked
shareClicked
,
emailClicked
,
phoneClicked
)
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH
))
assertTrue
(
delegate
.
isActionAvailable
(
SHARE
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
))
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH
,
selectedRegularText
))
assertTrue
(
delegate
.
isActionAvailable
(
SHARE
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
EMAIL
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
CALL
,
selectedRegularText
))
}
@Test
...
...
@@ -44,9 +56,41 @@ class DefaultSelectionActionDelegateTest {
getTestResources
()
)
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH
))
assertFalse
(
delegate
.
isActionAvailable
(
SHARE
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
))
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
SHARE
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
,
selectedRegularText
))
}
@Test
fun
`is
email
available
when
passed
in
and
email
text
selected`
()
{
val
searchAdapter
=
mock
<
SearchAdapter
>
{
whenever
(
isPrivateSession
()).
thenReturn
(
false
)
}
val
delegate
=
DefaultSelectionActionDelegate
(
searchAdapter
,
getTestResources
(),
emailTextClicked
=
emailClicked
)
assertTrue
(
delegate
.
isActionAvailable
(
EMAIL
,
selectedEmailText
))
assertFalse
(
delegate
.
isActionAvailable
(
EMAIL
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
EMAIL
,
selectedPhoneText
))
}
@Test
fun
`is
call
available
when
passed
in
and
call
text
selected`
()
{
val
searchAdapter
=
mock
<
SearchAdapter
>
{
whenever
(
isPrivateSession
()).
thenReturn
(
false
)
}
val
delegate
=
DefaultSelectionActionDelegate
(
searchAdapter
,
getTestResources
(),
callTextClicked
=
phoneClicked
)
assertTrue
(
delegate
.
isActionAvailable
(
CALL
,
selectedPhoneText
))
assertFalse
(
delegate
.
isActionAvailable
(
CALL
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
CALL
,
selectedEmailText
))
}
@Test
...
...
@@ -60,9 +104,9 @@ class DefaultSelectionActionDelegateTest {
shareClicked
)
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
))
assertTrue
(
delegate
.
isActionAvailable
(
SHARE
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH
))
assertTrue
(
delegate
.
isActionAvailable
(
SEARCH_PRIVATELY
,
selectedRegularText
))
assertTrue
(
delegate
.
isActionAvailable
(
SHARE
,
selectedRegularText
))
assertFalse
(
delegate
.
isActionAvailable
(
SEARCH
,
selectedRegularText
))
}
@Test
...
...
@@ -76,6 +120,28 @@ class DefaultSelectionActionDelegateTest {
assertEquals
(
lambdaValue
,
"some selected text"
)
}
@Test
fun
`when
email
ID
is
passed
to
perform
action
it
should
invoke
the
lambda`
()
{
val
adapter
=
mock
<
SearchAdapter
>()
val
delegate
=
DefaultSelectionActionDelegate
(
adapter
,
getTestResources
(),
emailTextClicked
=
emailClicked
)
delegate
.
performAction
(
EMAIL
,
selectedEmailText
)
assertEquals
(
lambdaValue
,
selectedEmailText
)
}
@Test
fun
`when
call
ID
is
passed
to
perform
action
it
should
invoke
the
lambda`
()
{
val
adapter
=
mock
<
SearchAdapter
>()
val
delegate
=
DefaultSelectionActionDelegate
(
adapter
,
getTestResources
(),
callTextClicked
=
phoneClicked
)
delegate
.
performAction
(
CALL
,
selectedPhoneText
)
assertEquals
(
lambdaValue
,
selectedPhoneText
)
}
@Test
fun
`when
unknown
ID
is
passed
to
performAction
it
should
not
perform
a
search`
()
{
val
adapter
=
mock
<
SearchAdapter
>()
...
...
@@ -148,4 +214,6 @@ fun getTestResources() = mock<Resources> {
whenever
(
getString
(
R
.
string
.
mozac_selection_context_menu_search_privately_2
))
.
thenReturn
(
"search privately"
)
whenever
(
getString
(
R
.
string
.
mozac_selection_context_menu_share
)).
thenReturn
(
"share"
)
whenever
(
getString
(
R
.
string
.
mozac_selection_context_menu_email
)).
thenReturn
(
"email"
)
whenever
(
getString
(
R
.
string
.
mozac_selection_context_menu_call
)).
thenReturn
(
"call"
)
}
components/support/ktx/src/main/java/mozilla/components/support/ktx/android/content/Context.kt
View file @
a1e401ac
...
...
@@ -2,18 +2,24 @@
* 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/. */
@
file
:
Suppress
(
"TooManyFunctions"
)
package
mozilla.components.support.ktx.android.content
import
android.app.ActivityManager
import
android.content.ActivityNotFoundException
import
android.content.Context
import
android.content.Intent
import
android.content.Intent.ACTION_DIAL
import
android.content.Intent.ACTION_SEND
import
android.content.Intent.ACTION_SENDTO
import
android.content.Intent.EXTRA_EMAIL
import
android.content.Intent.EXTRA_SUBJECT
import
android.content.Intent.EXTRA_TEXT
import
android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import
android.content.pm.PackageManager.PERMISSION_GRANTED
import
android.hardware.camera2.CameraManager
import
android.net.Uri
import
android.os.Process
import
android.view.accessibility.AccessibilityManager
import
androidx.annotation.AttrRes
...
...
@@ -25,6 +31,7 @@ import androidx.core.content.ContextCompat
import
androidx.core.content.ContextCompat.checkSelfPermission
import
androidx.core.content.getSystemService
import
mozilla.components.support.base.log.Log
import
mozilla.components.support.base.log.logger.Logger
import
mozilla.components.support.ktx.R
import
mozilla.components.support.ktx.android.content.res.resolveAttribute
...
...
@@ -100,6 +107,68 @@ fun Context.share(text: String, subject: String = getString(R.string.mozac_suppo
}
}
/**
* Emails content via [ACTION_SENDTO] intent.
*
* @param address the email address to send to [EXTRA_EMAIL]
* @param subject of the intent [EXTRA_TEXT]
* @return true it is able to share email false otherwise.
*/
@SuppressWarnings
(
"TooManyFunctions"
)
fun
Context
.
email
(
address
:
String
,
subject
:
String
=
getString
(
R
.
string
.
mozac_support_ktx_share_dialog_title
)
):
Boolean
{
return
try
{
val
intent
=
Intent
(
ACTION_SENDTO
,
Uri
.
parse
(
"mailto:$address"
))
intent
.
putExtra
(
EXTRA_SUBJECT
,
subject
)
val
emailIntent
=
Intent
.
createChooser
(
intent
,
getString
(
R
.
string
.
mozac_support_ktx_menu_email_with
)
).
apply
{
flags
=
FLAG_ACTIVITY_NEW_TASK
}
startActivity
(
emailIntent
)
true
}
catch
(
e
:
ActivityNotFoundException
)
{
Logger
.
warn
(
"No activity found to handle email intent"
,
throwable
=
e
)
false
}
}
/**
* Calls phone number via [ACTION_DIAL] intent.
*
* Note: we purposely use ACTION_DIAL rather than ACTION_CALL as the latter requires user permission
* @param phoneNumber the phone number to send to [ACTION_DIAL]
* @param subject of the intent [EXTRA_TEXT]
* @return true it is able to share phone call false otherwise.
*/
fun
Context
.
call
(
phoneNumber
:
String
,
subject
:
String
=
getString
(
R
.
string
.
mozac_support_ktx_share_dialog_title
)
):
Boolean
{
return
try
{
val
intent
=
Intent
(
ACTION_DIAL
,
Uri
.
parse
(
"tel:$phoneNumber"
))
intent
.
putExtra
(
EXTRA_SUBJECT
,
subject
)
val
callIntent
=
Intent
.
createChooser
(
intent
,
getString
(
R
.
string
.
mozac_support_ktx_menu_call_with
)
).
apply
{
flags
=
FLAG_ACTIVITY_NEW_TASK
}
startActivity
(
callIntent
)
true
}
catch
(
e
:
ActivityNotFoundException
)
{
Logger
.
warn
(
"No activity found to handle dial intent"
,
throwable
=
e
)
false
}
}
/**
* Check if TalkBack service is enabled.
*
...
...
components/support/ktx/src/main/res/values/strings.xml
View file @
a1e401ac
...
...
@@ -6,6 +6,10 @@
-->
<resources>
<!-- Text displayed when choosing which app to call with after selecting a phone number-->
<string
name=
"mozac_support_ktx_menu_call_with"
>
Call with…
</string>
<!-- Text displayed when choosing which app to email with after selecting an email address-->
<string
name=
"mozac_support_ktx_menu_email_with"
>
Email with…
</string>
<string
name=
"mozac_support_ktx_menu_share_with"
>
Share with…
</string>
<string
name=
"mozac_support_ktx_share_dialog_title"
>
Share via
</string>
</resources>
\ No newline at end of file
components/support/ktx/src/test/java/mozilla/components/support/ktx/android/content/ContextTest.kt
View file @
a1e401ac
...
...
@@ -79,6 +79,32 @@ class ContextTest {
assertEquals
(
FLAG_ACTIVITY_NEW_TASK
,
argCaptor
.
value
.
flags
)
}
@Test
fun
`email
invokes
startActivity`
()
{
val
context
=
spy
(
testContext
)
val
argCaptor
=
argumentCaptor
<
Intent
>()
val
result
=
context
.
email
(
"test@mozilla.org"
)
verify
(
context
).
startActivity
(
argCaptor
.
capture
())
assertTrue
(
result
)
assertEquals
(
FLAG_ACTIVITY_NEW_TASK
,
argCaptor
.
value
.
flags
)
}
@Test
fun
`call
invokes
startActivity`
()
{
val
context
=
spy
(
testContext
)
val
argCaptor
=
argumentCaptor
<
Intent
>()
val
result
=
context
.
call
(
"555-5555"
)
verify
(
context
).
startActivity
(
argCaptor
.
capture
())
assertTrue
(
result
)
assertEquals
(
FLAG_ACTIVITY_NEW_TASK
,
argCaptor
.
value
.
flags
)
}
@Test
fun
`isMainProcess
must
only
return
true
if
we
are
in
the
main
process`
()
{
val
myPid
=
Int
.
MAX_VALUE
...
...
samples/browser/src/main/java/org/mozilla/samples/browser/BrowserActivity.kt
View file @
a1e401ac
...
...
@@ -24,7 +24,6 @@ import mozilla.components.concept.tabstray.TabsTray
import
mozilla.components.feature.intent.ext.getSessionId
import
mozilla.components.feature.contextmenu.ext.DefaultSelectionActionDelegate
import
mozilla.components.support.base.feature.UserInteractionHandler
import
mozilla.components.support.ktx.android.content.share
import
mozilla.components.support.utils.SafeIntent
import
mozilla.components.support.webextensions.WebExtensionPopupFeature
import
org.mozilla.samples.browser.addons.WebExtensionActionPopupActivity
...
...
@@ -73,11 +72,9 @@ open class BrowserActivity : AppCompatActivity(), ComponentCallbacks2 {
when
(
name
)
{
EngineView
::
class
.
java
.
name
->
components
.
engine
.
createView
(
context
,
attrs
).
apply
{
selectionActionDelegate
=
DefaultSelectionActionDelegate
(
components
.
store
,
context
)
{
share
(
it
)
}
store
=
components
.
store
,
context
=
context
)
}.
asView
()
TabsTray
::
class
.
java
.
name
->
createTabsTray
(
context
,
attrs
)
else
->
super
.
onCreateView
(
parent
,
name
,
context
,
attrs
)
...
...
Write
Preview
Supports
Markdown
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