Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
11dd7112
Commit
11dd7112
authored
Dec 16, 2017
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement plugin entirely in Kotlin
parent
612a34a6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
128 additions
and
28 deletions
+128
-28
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
+1
-2
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
...main/java/com/github/shadowsocks/ProfileConfigFragment.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/bg/BaseService.kt
...le/src/main/java/com/github/shadowsocks/bg/BaseService.kt
+1
-2
mobile/src/main/java/com/github/shadowsocks/plugin/PluginConfiguration.kt
...java/com/github/shadowsocks/plugin/PluginConfiguration.kt
+1
-1
plugin/src/main/java/com/github/shadowsocks/plugin/PluginContract.kt
...main/java/com/github/shadowsocks/plugin/PluginContract.kt
+20
-22
plugin/src/main/java/com/github/shadowsocks/plugin/PluginOptions.kt
.../main/java/com/github/shadowsocks/plugin/PluginOptions.kt
+104
-0
No files found.
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
View file @
11dd7112
...
...
@@ -39,7 +39,6 @@ import android.support.v7.app.AppCompatActivity
import
android.support.v7.content.res.AppCompatResources
import
android.support.v7.preference.PreferenceDataStore
import
android.support.v7.widget.TooltipCompat
import
android.text.TextUtils
import
android.util.Log
import
android.view.View
import
android.widget.TextView
...
...
@@ -355,7 +354,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe
}
else
->
null
}
if
(
TextUtils
.
isEmpty
(
sharedStr
))
return
if
(
sharedStr
.
isNullOrEmpty
(
))
return
val
profiles
=
Profile
.
findAll
(
sharedStr
).
toList
()
if
(
profiles
.
isEmpty
())
{
Snackbar
.
make
(
findViewById
(
R
.
id
.
snackbar
),
R
.
string
.
profile_invalid_input
,
Snackbar
.
LENGTH_LONG
).
show
()
...
...
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
View file @
11dd7112
...
...
@@ -143,7 +143,7 @@ class ProfileConfigFragment : PreferenceFragmentCompatDividers(), Toolbar.OnMenu
override
fun
onPreferenceChange
(
preference
:
Preference
?,
newValue
:
Any
?):
Boolean
=
try
{
val
selected
=
pluginConfiguration
.
selected
pluginConfiguration
=
PluginConfiguration
(
pluginConfiguration
.
pluginsOptions
+
(
pluginConfiguration
.
selected
to
PluginOptions
(
selected
,
newValue
as
String
?)),
selected
)
(
pluginConfiguration
.
selected
to
PluginOptions
(
selected
,
newValue
as
?
String
?)),
selected
)
DataStore
.
plugin
=
pluginConfiguration
.
toString
()
DataStore
.
dirty
=
true
true
...
...
mobile/src/main/java/com/github/shadowsocks/bg/BaseService.kt
View file @
11dd7112
...
...
@@ -29,7 +29,6 @@ import android.os.Build
import
android.os.IBinder
import
android.os.RemoteCallbackList
import
android.support.v4.os.UserManagerCompat
import
android.text.TextUtils
import
android.util.Base64
import
android.util.Log
import
android.widget.Toast
...
...
@@ -218,7 +217,7 @@ object BaseService {
fun
onBind
(
intent
:
Intent
):
IBinder
?
=
if
(
intent
.
action
==
Action
.
SERVICE
)
data
.
binder
else
null
fun
checkProfile
(
profile
:
Profile
):
Boolean
=
if
(
TextUtils
.
isEmpty
(
profile
.
host
)
||
TextUtils
.
isEmpty
(
profile
.
password
))
{
if
(
profile
.
host
.
isEmpty
()
||
profile
.
password
.
isEmpty
(
))
{
stopRunner
(
true
,
(
this
as
Context
).
getString
(
R
.
string
.
proxy_empty
))
false
}
else
true
...
...
mobile/src/main/java/com/github/shadowsocks/plugin/PluginConfiguration.kt
View file @
11dd7112
...
...
@@ -50,7 +50,7 @@ class PluginConfiguration(val pluginsOptions: Map<String, PluginOptions>, val se
})
fun
getOptions
(
id
:
String
):
PluginOptions
=
if
(
id
.
isEmpty
())
PluginOptions
()
else
pluginsOptions
.
get
(
id
)
?:
PluginOptions
(
id
,
PluginManager
.
fetchPlugins
()[
id
]
?.
defaultConfig
)
pluginsOptions
[
id
]
?:
PluginOptions
(
id
,
PluginManager
.
fetchPlugins
()[
id
]
?.
defaultConfig
)
val
selectedOptions
:
PluginOptions
get
()
=
getOptions
(
selected
)
override
fun
toString
():
String
{
...
...
plugin/src/main/java/com/github/shadowsocks/plugin/PluginContract.
java
→
plugin/src/main/java/com/github/shadowsocks/plugin/PluginContract.
kt
View file @
11dd7112
...
...
@@ -18,35 +18,33 @@
* *
*******************************************************************************/
package
com.github.shadowsocks.plugin
;
package
com.github.shadowsocks.plugin
/**
* The contract between the plugin provider and host. Contains definitions for the supported actions, extras, etc.
*
* This class is written in Java to keep Java interoperability.
*/
public
final
class
PluginContract
{
private
PluginContract
()
{
}
object
PluginContract
{
/**
* ContentProvider Action: Used for NativePluginProvider.
*
* Constant Value: "com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN"
*/
public
static
final
String
ACTION_NATIVE_PLUGIN
=
"com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN"
;
const
val
ACTION_NATIVE_PLUGIN
=
"com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN"
/**
* Activity Action: Used for ConfigurationActivity.
*
* Constant Value: "com.github.shadowsocks.plugin.ACTION_CONFIGURE"
*/
public
static
final
String
ACTION_CONFIGURE
=
"com.github.shadowsocks.plugin.ACTION_CONFIGURE"
;
const
val
ACTION_CONFIGURE
=
"com.github.shadowsocks.plugin.ACTION_CONFIGURE"
/**
* Activity Action: Used for HelpActivity or HelpCallback.
*
* Constant Value: "com.github.shadowsocks.plugin.ACTION_HELP"
*/
public
static
final
String
ACTION_HELP
=
"com.github.shadowsocks.plugin.ACTION_HELP"
;
const
val
ACTION_HELP
=
"com.github.shadowsocks.plugin.ACTION_HELP"
/**
* The lookup key for a string that provides the plugin entry binary.
...
...
@@ -55,7 +53,7 @@ public final class PluginContract {
*
* Constant Value: "com.github.shadowsocks.plugin.EXTRA_ENTRY"
*/
public
static
final
String
EXTRA_ENTRY
=
"com.github.shadowsocks.plugin.EXTRA_ENTRY"
;
const
val
EXTRA_ENTRY
=
"com.github.shadowsocks.plugin.EXTRA_ENTRY"
/**
* The lookup key for a string that provides the options as a string.
*
...
...
@@ -63,34 +61,34 @@ public final class PluginContract {
*
* Constant Value: "com.github.shadowsocks.plugin.EXTRA_OPTIONS"
*/
public
static
final
String
EXTRA_OPTIONS
=
"com.github.shadowsocks.plugin.EXTRA_OPTIONS"
;
const
val
EXTRA_OPTIONS
=
"com.github.shadowsocks.plugin.EXTRA_OPTIONS"
/**
* The lookup key for a CharSequence that provides user relevant help message.
*
* Example: "obfs=<http|tls> Enable obfuscating: HTTP or TLS (Experimental).
*
obfs-host=<host_name> Hostname for obfuscating (Experimental)."
* Example: "obfs=<http
></http>
|tls> Enable obfuscating: HTTP or TLS (Experimental).
* obfs-host=<host_name> Hostname for obfuscating (Experimental)."
*
* Constant Value: "com.github.shadowsocks.plugin.EXTRA_HELP_MESSAGE"
*/
public
static
final
String
EXTRA_HELP_MESSAGE
=
"com.github.shadowsocks.plugin.EXTRA_HELP_MESSAGE"
;
</host_name>
*/
const
val
EXTRA_HELP_MESSAGE
=
"com.github.shadowsocks.plugin.EXTRA_HELP_MESSAGE"
/**
* The metadata key to retrieve plugin id. Required for plugins.
*
* Constant Value: "com.github.shadowsocks.plugin.id"
*/
public
static
final
String
METADATA_KEY_ID
=
"com.github.shadowsocks.plugin.id"
;
const
val
METADATA_KEY_ID
=
"com.github.shadowsocks.plugin.id"
/**
* The metadata key to retrieve default configuration. Default value is empty.
*
* Constant Value: "com.github.shadowsocks.plugin.default_config"
*/
public
static
final
String
METADATA_KEY_DEFAULT_CONFIG
=
"com.github.shadowsocks.plugin.default_config"
;
const
val
METADATA_KEY_DEFAULT_CONFIG
=
"com.github.shadowsocks.plugin.default_config"
public
static
final
String
METHOD_GET_EXECUTABLE
=
"shadowsocks:getExecutable"
;
const
val
METHOD_GET_EXECUTABLE
=
"shadowsocks:getExecutable"
/** ConfigurationActivity result: fallback to manual edit mode. */
public
static
final
int
RESULT_FALLBACK
=
1
;
/** ConfigurationActivity result: fallback to manual edit mode.
*/
const
val
RESULT_FALLBACK
=
1
/**
* Relative to the file to be copied. This column is required.
...
...
@@ -99,7 +97,7 @@ public final class PluginContract {
*
* Type: String
*/
public
static
final
String
COLUMN_PATH
=
"path"
;
const
val
COLUMN_PATH
=
"path"
/**
* File mode bits. Default value is "644".
*
...
...
@@ -107,14 +105,14 @@ public final class PluginContract {
*
* Type: String
*/
public
static
final
String
COLUMN_MODE
=
"mode"
;
const
val
COLUMN_MODE
=
"mode"
/**
* The scheme for general plugin actions.
*/
public
static
final
String
SCHEME
=
"plugin"
;
const
val
SCHEME
=
"plugin"
/**
* The authority for general plugin actions.
*/
public
static
final
String
AUTHORITY
=
"com.github.shadowsocks"
;
const
val
AUTHORITY
=
"com.github.shadowsocks"
}
plugin/src/main/java/com/github/shadowsocks/plugin/PluginOptions.
java
→
plugin/src/main/java/com/github/shadowsocks/plugin/PluginOptions.
kt
View file @
11dd7112
...
...
@@ -18,110 +18,87 @@
* *
*******************************************************************************/
package
com.github.shadowsocks.plugin
;
package
com.github.shadowsocks.plugin
import
android.text.TextUtils
;
import
java.util.HashMap
;
import
java.util.Objects
;
import
java.util.StringTokenizer
;
import
java.util.*
/**
* Helper class for processing plugin options.
*
* Based on: https://github.com/apache/ant/blob/588ce1f/src/main/org/apache/tools/ant/types/Commandline.java
*/
public
final
class
PluginOptions
extends
HashMap
<
String
,
String
>
{
public
PluginOptions
()
{
super
();
}
public
PluginOptions
(
int
initialCapacity
)
{
super
(
initialCapacity
);
}
public
PluginOptions
(
int
initialCapacity
,
float
loadFactor
)
{
super
(
initialCapacity
,
loadFactor
);
}
class
PluginOptions
:
HashMap
<
String
,
String
?
>
{
var
id
=
""
// TODO: this method is not needed since API 24
public
String
getOrDefault
(
Object
key
,
String
defaultValue
)
{
String
v
;
return
(((
v
=
get
(
key
))
!=
null
)
||
containsKey
(
key
))
?
v
:
defaultValue
;
}
constructor
()
:
super
()
constructor
(
initialCapacity
:
Int
)
:
super
(
initialCapacity
)
constructor
(
initialCapacity
:
Int
,
loadFactor
:
Float
)
:
super
(
initialCapacity
,
loadFactor
)
private
PluginOptions
(
String
options
,
boolean
parseId
)
{
this
();
if
(
TextUtils
.
isEmpty
(
options
))
return
;
final
StringTokenizer
tokenizer
=
new
StringTokenizer
(
options
+
';'
,
"\\=;"
,
true
);
final
StringBuilder
current
=
new
StringBuilder
();
String
key
=
null
;
private
constructor
(
options
:
String
?,
parseId
:
Boolean
)
:
this
()
{
@Suppress
(
"NAME_SHADOWING"
)
var
parseId
=
parseId
if
(
options
.
isNullOrEmpty
())
return
val
tokenizer
=
StringTokenizer
(
options
+
';'
,
"\\=;"
,
true
)
val
current
=
StringBuilder
()
var
key
:
String
?
=
null
while
(
tokenizer
.
hasMoreTokens
())
{
String
nextToken
=
tokenizer
.
nextToken
();
if
(
"\\"
.
equals
(
nextToken
))
current
.
append
(
tokenizer
.
nextToken
());
else
if
(
"="
.
equals
(
nextToken
)
&&
key
==
null
)
{
key
=
current
.
toString
();
current
.
setLength
(
0
);
}
else
if
(
";"
.
equals
(
nextToken
))
{
if
(
key
!=
null
)
{
put
(
key
,
current
.
toString
());
key
=
null
;
}
else
if
(
current
.
length
()
>
0
)
if
(
parseId
)
id
=
current
.
toString
();
else
put
(
current
.
toString
(),
null
);
current
.
setLength
(
0
);
parseId
=
false
;
}
else
current
.
append
(
nextToken
);
val
nextToken
=
tokenizer
.
nextToken
()
when
(
nextToken
)
{
"\\"
->
current
.
append
(
tokenizer
.
nextToken
())
"="
->
if
(
key
==
null
)
{
key
=
current
.
toString
()
current
.
setLength
(
0
)
}
else
current
.
append
(
nextToken
)
";"
->
{
if
(
key
!=
null
)
{
put
(
key
,
current
.
toString
())
key
=
null
}
else
if
(
current
.
isNotEmpty
())
if
(
parseId
)
id
=
current
.
toString
()
else
put
(
current
.
toString
(),
null
)
current
.
setLength
(
0
)
parseId
=
false
}
else
->
current
.
append
(
nextToken
)
}
}
}
public
PluginOptions
(
String
options
)
{
this
(
options
,
true
);
}
public
PluginOptions
(
String
id
,
String
options
)
{
this
(
options
,
false
);
this
.
id
=
id
;
}
public
String
id
=
""
;
constructor
(
options
:
String
?)
:
this
(
options
,
true
)
constructor
(
id
:
String
,
options
:
String
?)
:
this
(
options
,
false
)
{
this
.
id
=
id
}
private
static
void
append
(
StringBuilder
result
,
String
str
)
{
for
(
int
i
=
0
;
i
<
str
.
length
();
++
i
)
{
char
ch
=
str
.
charAt
(
i
);
switch
(
ch
)
{
case
'\\'
:
case
'='
:
case
';'
:
result
.
append
(
'\\'
);
// intentionally no break
default
:
result
.
append
(
ch
);
private
fun
append
(
result
:
StringBuilder
,
str
:
String
)
=
(
0
until
str
.
length
)
.
map
{
str
[
it
]
}
.
forEach
{
when
(
it
)
{
'\\'
,
'='
,
';'
->
{
result
.
append
(
'\\'
)
// intentionally no break
result
.
append
(
it
)
}
else
->
result
.
append
(
it
)
}
}
}
}
public
String
toString
(
boolean
trimId
)
{
final
StringBuilder
result
=
new
StringBuilder
();
if
(!
trimId
)
if
(
TextUtils
.
isEmpty
(
id
))
return
""
;
else
append
(
result
,
id
);
for
(
Entry
<
String
,
String
>
entry
:
entrySet
())
{
if
(
result
.
length
()
>
0
)
result
.
append
(
';'
);
append
(
result
,
entry
.
getKey
());
String
value
=
entry
.
getValue
();
fun
toString
(
trimId
:
Boolean
):
String
{
val
result
=
StringBuilder
()
if
(!
trimId
)
if
(
id
.
isEmpty
())
return
""
else
append
(
result
,
id
)
for
((
key
,
value
)
in
entries
)
{
if
(
result
.
isNotEmpty
())
result
.
append
(
';'
)
append
(
result
,
key
)
if
(
value
!=
null
)
{
result
.
append
(
'='
)
;
append
(
result
,
value
)
;
result
.
append
(
'='
)
append
(
result
,
value
)
}
}
return
result
.
toString
();
}
@Override
public
String
toString
()
{
return
toString
(
true
);
return
result
.
toString
()
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(!
super
.
equals
(
o
))
return
false
;
PluginOptions
that
=
(
PluginOptions
)
o
;
return
Objects
.
equals
(
id
,
that
.
id
)
&&
super
.
equals
(
that
);
}
override
fun
toString
():
String
=
toString
(
true
)
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
super
.
hashCode
(),
id
);
override
fun
equals
(
other
:
Any
?):
Boolean
{
if
(
this
===
other
)
return
true
return
javaClass
==
other
?.
javaClass
&&
super
.
equals
(
other
)
&&
id
==
(
other
as
PluginOptions
).
id
}
override
fun
hashCode
():
Int
=
Objects
.
hash
(
super
.
hashCode
(),
id
)
}
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