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
a2848ce5
Commit
a2848ce5
authored
Sep 29, 2013
by
Max Lv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update UI
parent
6f55861d
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
375 additions
and
120 deletions
+375
-120
src/main/res/layout/layout_switch.xml
src/main/res/layout/layout_switch.xml
+2
-1
src/main/res/values/strings.xml
src/main/res/values/strings.xml
+3
-0
src/main/res/xml/pref_proxy.xml
src/main/res/xml/pref_proxy.xml
+6
-0
src/main/scala/com/github/shadowsocks/AppManager.scala
src/main/scala/com/github/shadowsocks/AppManager.scala
+2
-3
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+193
-67
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
...scala/com/github/shadowsocks/ShadowsocksApplication.scala
+0
-1
src/main/scala/com/github/shadowsocks/ShadowsocksService.scala
...ain/scala/com/github/shadowsocks/ShadowsocksService.scala
+2
-12
src/main/scala/com/github/shadowsocks/Utils.scala
src/main/scala/com/github/shadowsocks/Utils.scala
+46
-3
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
...main/scala/com/github/shadowsocks/database/DBHelper.scala
+1
-1
src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala
...n/scala/com/github/shadowsocks/database/MenuAdapter.scala
+31
-17
src/main/scala/com/github/shadowsocks/database/Profile.scala
src/main/scala/com/github/shadowsocks/database/Profile.scala
+14
-8
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
...cala/com/github/shadowsocks/database/ProfileManager.scala
+75
-7
No files found.
src/main/res/layout/layout_switch.xml
View file @
a2848ce5
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:gravity=
"center_vertical"
android:gravity=
"center_vertical"
android:textSize=
"2
2
sp"
android:textSize=
"2
4
sp"
android:textColor=
"@color/title"
android:textColor=
"@color/title"
android:text=
"@string/app_name"
android:text=
"@string/app_name"
android:layout_alignParentLeft=
"true"
android:layout_alignParentLeft=
"true"
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_alignParentRight=
"true"
android:layout_alignParentRight=
"true"
android:layout_marginRight =
"10dp"
android:layout_centerVertical=
"true"
/>
android:layout_centerVertical=
"true"
/>
</RelativeLayout>
</RelativeLayout>
src/main/res/values/strings.xml
View file @
a2848ce5
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
<!-- proxy category -->
<!-- proxy category -->
<string
name=
"proxy_cat"
>
Server Settings
</string>
<string
name=
"proxy_cat"
>
Server Settings
</string>
<string
name=
"profile"
>
Profile
</string>
<string
name=
"profile_summary"
>
Profile name
</string>
<string
name=
"proxy"
>
Server
</string>
<string
name=
"proxy"
>
Server
</string>
<string
name=
"proxy_summary"
>
Hostname or IP Address of your Shadowsocks server
</string>
<string
name=
"proxy_summary"
>
Hostname or IP Address of your Shadowsocks server
</string>
<string
name=
"remote_port"
>
Remote Port
</string>
<string
name=
"remote_port"
>
Remote Port
</string>
...
@@ -73,5 +75,6 @@
...
@@ -73,5 +75,6 @@
<string
name=
"about_title"
>
Shadowsocks %s
</string>
<string
name=
"about_title"
>
Shadowsocks %s
</string>
<string
name=
"flush_dnscache"
>
Flush DNS Cache
</string>
<string
name=
"flush_dnscache"
>
Flush DNS Cache
</string>
<string
name=
"flushing"
>
Flushing
</string>
<string
name=
"flushing"
>
Flushing
</string>
<string
name=
"add_profile"
>
Add Profile
</string>
</resources>
</resources>
src/main/res/xml/pref_proxy.xml
View file @
a2848ce5
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<PreferenceScreen
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<com.github.shadowsocks.preferences.SummaryEditTextPreference
android:defaultValue=
"Default"
android:key=
"profileName"
android:summary=
"@string/profile_summary"
android:title=
"@string/profile"
>
</com.github.shadowsocks.preferences.SummaryEditTextPreference>
<com.github.shadowsocks.preferences.SummaryEditTextPreference
<com.github.shadowsocks.preferences.SummaryEditTextPreference
android:defaultValue=
"198.199.101.152"
android:defaultValue=
"198.199.101.152"
android:key=
"proxy"
android:key=
"proxy"
...
...
src/main/scala/com/github/shadowsocks/AppManager.scala
View file @
a2848ce5
...
@@ -109,7 +109,6 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -109,7 +109,6 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
val
MSG_LOAD_START
=
1
val
MSG_LOAD_START
=
1
val
MSG_LOAD_FINISH
=
2
val
MSG_LOAD_FINISH
=
2
val
SCHEME
=
"app://"
val
STUB
=
android
.
R
.
drawable
.
sym_def_app_icon
val
STUB
=
android
.
R
.
drawable
.
sym_def_app_icon
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
ObjectArrayTools
(
a
)
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
ObjectArrayTools
(
a
)
...
@@ -184,7 +183,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -184,7 +183,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
.
cacheOnDisc
()
.
cacheOnDisc
()
.
displayer
(
new
FadeInBitmapDisplayer
(
300
))
.
displayer
(
new
FadeInBitmapDisplayer
(
300
))
.
build
()
.
build
()
ImageLoader
.
getInstance
().
displayImage
(
"app://"
+
app
.
uid
,
entry
.
icon
,
options
)
ImageLoader
.
getInstance
().
displayImage
(
Scheme
.
APP
+
app
.
uid
,
entry
.
icon
,
options
)
entry
.
text
.
setText
(
app
.
name
)
entry
.
text
.
setText
(
app
.
name
)
val
box
:
CheckBox
=
entry
.
box
val
box
:
CheckBox
=
entry
.
box
...
@@ -327,7 +326,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -327,7 +326,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
}
}
override
def
getStreamFromOtherSource
(
imageUri
:
String
,
extra
:
AnyRef
)
:
InputStream
=
{
override
def
getStreamFromOtherSource
(
imageUri
:
String
,
extra
:
AnyRef
)
:
InputStream
=
{
val
uid
=
imageUri
.
substring
(
S
CHEME
.
length
).
toInt
val
uid
=
imageUri
.
substring
(
S
cheme
.
APP
.
length
).
toInt
val
drawable
=
Utils
.
getAppIcon
(
getBaseContext
,
uid
)
val
drawable
=
Utils
.
getAppIcon
(
getBaseContext
,
uid
)
val
bitmap
=
Utils
.
drawableToBitmap
(
drawable
)
val
bitmap
=
Utils
.
drawableToBitmap
(
drawable
)
...
...
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
a2848ce5
...
@@ -41,21 +41,16 @@ package com.github.shadowsocks
...
@@ -41,21 +41,16 @@ package com.github.shadowsocks
import
android.app.
{
Activity
,
AlertDialog
,
ProgressDialog
}
import
android.app.
{
Activity
,
AlertDialog
,
ProgressDialog
}
import
android.content._
import
android.content._
import
android.content.res.AssetManager
import
android.content.res.AssetManager
import
android.graphics.
Typeface
import
android.graphics.
{
Color
,
Bitmap
,
Typeface
}
import
android.os._
import
android.os._
import
android.preference.
{
Preference
,
PreferenceManager
}
import
android.preference.
_
import
android.util.Log
import
android.util.Log
import
android.view.
{
View
Group
,
Gravity
,
ViewParent
,
KeyEvent
}
import
android.view.
{
View
,
ViewGroup
,
ViewParent
,
KeyEvent
}
import
android.widget._
import
android.widget._
import
com.actionbarsherlock.view.Menu
import
com.actionbarsherlock.view.MenuItem
import
com.google.analytics.tracking.android.EasyTracker
import
com.google.analytics.tracking.android.EasyTracker
import
de.keyboardsurfer.android.widget.crouton.Crouton
import
de.keyboardsurfer.android.widget.crouton.Crouton
import
de.keyboardsurfer.android.widget.crouton.Style
import
de.keyboardsurfer.android.widget.crouton.Style
import
java.io.FileOutputStream
import
java.io._
import
java.io.IOException
import
java.io.InputStream
import
java.io.OutputStream
import
java.util.Hashtable
import
java.util.Hashtable
import
net.saik0.android.unifiedpreference.UnifiedPreferenceFragment
import
net.saik0.android.unifiedpreference.UnifiedPreferenceFragment
import
net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity
import
net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity
...
@@ -71,21 +66,107 @@ import net.simonvt.menudrawer.MenuDrawer
...
@@ -71,21 +66,107 @@ import net.simonvt.menudrawer.MenuDrawer
import
com.github.shadowsocks.database._
import
com.github.shadowsocks.database._
import
scala.collection.mutable.ListBuffer
import
scala.collection.mutable.ListBuffer
import
com.github.shadowsocks.database.Profile
import
com.nostra13.universalimageloader.core.
{
ImageLoader
,
ImageLoaderConfiguration
}
import
com.nostra13.universalimageloader.core.download.BaseImageDownloader
import
com.github.shadowsocks.database.Item
import
com.github.shadowsocks.database.Category
import
com.github.shadowsocks.database.Category
import
com.actionbarsherlock.view.MenuItem
import
com.github.shadowsocks.preferences.
{
PasswordEditTextPreference
,
SummaryEditTextPreference
}
import
com.github.shadowsocks.database.Item
import
com.github.shadowsocks.database.Item
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.database.Category
import
scala.Option
class
ProfileIconDownloader
(
context
:
Context
,
connectTimeout
:
Int
,
readTimeout
:
Int
)
extends
BaseImageDownloader
(
context
,
connectTimeout
,
readTimeout
)
{
def
this
(
context
:
Context
)
{
this
(
context
,
0
,
0
)
}
override
def
getStreamFromOtherSource
(
imageUri
:
String
,
extra
:
AnyRef
)
:
InputStream
=
{
val
text
=
imageUri
.
substring
(
Scheme
.
PROFILE
.
length
)
val
size
=
Utils
.
dpToPx
(
context
,
16
).
toInt
val
idx
=
text
.
getBytes
.
last
%
6
val
color
=
Seq
(
Color
.
MAGENTA
,
Color
.
GREEN
,
Color
.
YELLOW
,
Color
.
BLUE
,
Color
.
DKGRAY
,
Color
.
CYAN
)(
idx
)
val
bitmap
=
Utils
.
getBitmap
(
text
,
size
,
size
,
color
)
val
os
=
new
ByteArrayOutputStream
()
bitmap
.
compress
(
Bitmap
.
CompressFormat
.
PNG
,
100
,
os
)
new
ByteArrayInputStream
(
os
.
toByteArray
)
}
}
object
Typefaces
{
def
get
(
c
:
Context
,
assetPath
:
String
)
:
Typeface
=
{
cache
synchronized
{
if
(!
cache
.
containsKey
(
assetPath
))
{
try
{
val
t
:
Typeface
=
Typeface
.
createFromAsset
(
c
.
getAssets
,
assetPath
)
cache
.
put
(
assetPath
,
t
)
}
catch
{
case
e
:
Exception
=>
{
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
e
.
getMessage
)
return
null
}
}
}
return
cache
.
get
(
assetPath
)
}
}
private
final
val
TAG
:
String
=
"Typefaces"
private
final
val
cache
:
Hashtable
[
String
,
Typeface
]
=
new
Hashtable
[
String
,
Typeface
]
}
object
Shadowsocks
{
object
Shadowsocks
{
val
PREFS_NAME
=
"Shadowsocks"
val
PREFS_NAME
=
"Shadowsocks"
val
PROXY_PREFS
=
Array
(
Key
.
proxy
,
Key
.
remotePort
,
Key
.
localPort
,
Key
.
sitekey
,
Key
.
encMethod
)
val
PROXY_PREFS
=
Array
(
Key
.
pro
fileName
,
Key
.
pro
xy
,
Key
.
remotePort
,
Key
.
localPort
,
Key
.
sitekey
,
Key
.
encMethod
)
val
FEATRUE_PREFS
=
Array
(
Key
.
isGFWList
,
Key
.
isGlobalProxy
,
Key
.
proxyedApps
,
val
FEATRUE_PREFS
=
Array
(
Key
.
isGFWList
,
Key
.
isGlobalProxy
,
Key
.
proxyedApps
,
Key
.
isTrafficStat
,
Key
.
is
TrafficStat
,
Key
.
is
AutoConnect
)
Key
.
isAutoConnect
)
val
TAG
=
"Shadowsocks"
val
TAG
=
"Shadowsocks"
val
REQUEST_CONNECT
=
1
val
REQUEST_CONNECT
=
1
private
var
vpnEnabled
=
-
1
private
var
vpnEnabled
=
-
1
var
currentProfile
:
Profile
=
null
def
updateListPreference
(
pref
:
Preference
,
value
:
String
)
{
pref
.
setSummary
(
value
)
pref
.
asInstanceOf
[
ListPreference
].
setValue
(
value
)
}
def
updatePasswordEditTextPreference
(
pref
:
Preference
,
value
:
String
)
{
pref
.
setSummary
(
value
)
pref
.
asInstanceOf
[
PasswordEditTextPreference
].
setText
(
value
)
}
def
updateSummaryEditTextPreference
(
pref
:
Preference
,
value
:
String
)
{
pref
.
setSummary
(
value
)
pref
.
asInstanceOf
[
SummaryEditTextPreference
].
setText
(
value
)
}
def
updateCheckBoxPreference
(
pref
:
Preference
,
value
:
Boolean
)
{
pref
.
asInstanceOf
[
CheckBoxPreference
].
setChecked
(
value
)
}
def
updatePreference
(
pref
:
Preference
,
name
:
String
,
profile
:
Profile
)
{
name
match
{
case
Key
.
profileName
=>
updateSummaryEditTextPreference
(
pref
,
profile
.
name
)
case
Key
.
proxy
=>
updateSummaryEditTextPreference
(
pref
,
profile
.
host
)
case
Key
.
remotePort
=>
updateSummaryEditTextPreference
(
pref
,
profile
.
remotePort
.
toString
)
case
Key
.
localPort
=>
updateSummaryEditTextPreference
(
pref
,
profile
.
localPort
.
toString
)
case
Key
.
sitekey
=>
updatePasswordEditTextPreference
(
pref
,
profile
.
password
)
case
Key
.
encMethod
=>
updateListPreference
(
pref
,
profile
.
method
)
case
Key
.
isGFWList
=>
updateCheckBoxPreference
(
pref
,
profile
.
chnroute
)
case
Key
.
isGlobalProxy
=>
updateCheckBoxPreference
(
pref
,
profile
.
global
)
case
Key
.
isTrafficStat
=>
updateCheckBoxPreference
(
pref
,
profile
.
traffic
)
case
_
=>
}
}
def
isServiceStarted
(
context
:
Context
)
:
Boolean
=
{
def
isServiceStarted
(
context
:
Context
)
:
Boolean
=
{
ShadowsocksService
.
isServiceStarted
(
context
)
||
ShadowVpnService
.
isServiceStarted
(
context
)
ShadowsocksService
.
isServiceStarted
(
context
)
||
ShadowVpnService
.
isServiceStarted
(
context
)
}
}
...
@@ -105,6 +186,13 @@ object Shadowsocks {
...
@@ -105,6 +186,13 @@ object Shadowsocks {
}
}
}
}
private
def
updatePreferenceScreen
()
{
for
(
name
<-
Shadowsocks
.
PROXY_PREFS
)
{
val
pref
=
findPreference
(
name
)
Shadowsocks
.
updatePreference
(
pref
,
name
,
Shadowsocks
.
currentProfile
)
}
}
override
def
onCreate
(
bundle
:
Bundle
)
{
override
def
onCreate
(
bundle
:
Bundle
)
{
super
.
onCreate
(
bundle
)
super
.
onCreate
(
bundle
)
val
filter
=
new
IntentFilter
()
val
filter
=
new
IntentFilter
()
...
@@ -112,6 +200,7 @@ object Shadowsocks {
...
@@ -112,6 +200,7 @@ object Shadowsocks {
receiver
=
new
BroadcastReceiver
{
receiver
=
new
BroadcastReceiver
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
setPreferenceEnabled
()
setPreferenceEnabled
()
updatePreferenceScreen
()
}
}
}
}
getActivity
.
getApplicationContext
.
registerReceiver
(
receiver
,
filter
)
getActivity
.
getApplicationContext
.
registerReceiver
(
receiver
,
filter
)
...
@@ -132,7 +221,7 @@ object Shadowsocks {
...
@@ -132,7 +221,7 @@ object Shadowsocks {
}
}
}
}
class
FeatureFragment
extends
UnifiedPreferenceFragment
with
OnSharedPreferenceChangeListener
{
class
FeatureFragment
extends
UnifiedPreferenceFragment
{
var
receiver
:
BroadcastReceiver
=
null
var
receiver
:
BroadcastReceiver
=
null
...
@@ -144,8 +233,8 @@ object Shadowsocks {
...
@@ -144,8 +233,8 @@ object Shadowsocks {
if
(
pref
!=
null
)
{
if
(
pref
!=
null
)
{
val
status
=
getActivity
.
getSharedPreferences
(
Key
.
status
,
Context
.
MODE_PRIVATE
)
val
status
=
getActivity
.
getSharedPreferences
(
Key
.
status
,
Context
.
MODE_PRIVATE
)
val
isRoot
=
status
.
getBoolean
(
Key
.
isRoot
,
false
)
val
isRoot
=
status
.
getBoolean
(
Key
.
isRoot
,
false
)
if
(
Seq
(
Key
.
isAutoConnect
,
Key
.
isGlobalProxy
,
Key
.
isTrafficStat
,
if
(
Seq
(
Key
.
isAutoConnect
,
Key
.
isGlobalProxy
,
Key
.
isTrafficStat
,
Key
.
proxyedApps
)
Key
.
proxyedApps
)
.
contains
(
name
))
{
.
contains
(
name
))
{
pref
.
setEnabled
(
enabled
&&
isRoot
)
pref
.
setEnabled
(
enabled
&&
isRoot
)
}
else
{
}
else
{
pref
.
setEnabled
(
enabled
)
pref
.
setEnabled
(
enabled
)
...
@@ -154,6 +243,13 @@ object Shadowsocks {
...
@@ -154,6 +243,13 @@ object Shadowsocks {
}
}
}
}
private
def
updatePreferenceScreen
()
{
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
val
pref
=
findPreference
(
name
)
Shadowsocks
.
updatePreference
(
pref
,
name
,
Shadowsocks
.
currentProfile
)
}
}
override
def
onCreate
(
bundle
:
Bundle
)
{
override
def
onCreate
(
bundle
:
Bundle
)
{
super
.
onCreate
(
bundle
)
super
.
onCreate
(
bundle
)
val
filter
=
new
IntentFilter
()
val
filter
=
new
IntentFilter
()
...
@@ -161,6 +257,7 @@ object Shadowsocks {
...
@@ -161,6 +257,7 @@ object Shadowsocks {
receiver
=
new
BroadcastReceiver
{
receiver
=
new
BroadcastReceiver
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
setPreferenceEnabled
()
setPreferenceEnabled
()
updatePreferenceScreen
()
}
}
}
}
getActivity
.
getApplicationContext
.
registerReceiver
(
receiver
,
filter
)
getActivity
.
getApplicationContext
.
registerReceiver
(
receiver
,
filter
)
...
@@ -179,40 +276,15 @@ object Shadowsocks {
...
@@ -179,40 +276,15 @@ object Shadowsocks {
override
def
onPause
()
{
override
def
onPause
()
{
super
.
onPause
()
super
.
onPause
()
}
}
def
onSharedPreferenceChanged
(
prefs
:
SharedPreferences
,
key
:
String
)
{
if
(
key
==
Key
.
isGlobalProxy
)
setPreferenceEnabled
()
}
}
}
}
}
object
Typefaces
{
def
get
(
c
:
Context
,
assetPath
:
String
)
:
Typeface
=
{
cache
synchronized
{
if
(!
cache
.
containsKey
(
assetPath
))
{
try
{
val
t
:
Typeface
=
Typeface
.
createFromAsset
(
c
.
getAssets
,
assetPath
)
cache
.
put
(
assetPath
,
t
)
}
catch
{
case
e
:
Exception
=>
{
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
e
.
getMessage
)
return
null
}
}
}
return
cache
.
get
(
assetPath
)
}
}
private
final
val
TAG
:
String
=
"Typefaces"
private
final
val
cache
:
Hashtable
[
String
,
Typeface
]
=
new
Hashtable
[
String
,
Typeface
]
}
class
Shadowsocks
class
Shadowsocks
extends
UnifiedSherlockPreferenceActivity
extends
UnifiedSherlockPreferenceActivity
with
CompoundButton
.
OnCheckedChangeListener
with
CompoundButton
.
OnCheckedChangeListener
with
OnSharedPreferenceChangeListener
{
with
OnSharedPreferenceChangeListener
with
MenuAdapter
.
MenuListener
{
private
val
MSG_CRASH_RECOVER
:
Int
=
1
private
val
MSG_CRASH_RECOVER
:
Int
=
1
private
val
MSG_INITIAL_FINISH
:
Int
=
2
private
val
MSG_INITIAL_FINISH
:
Int
=
2
...
@@ -227,9 +299,9 @@ class Shadowsocks
...
@@ -227,9 +299,9 @@ class Shadowsocks
lazy
val
status
=
getSharedPreferences
(
Key
.
status
,
Context
.
MODE_PRIVATE
)
lazy
val
status
=
getSharedPreferences
(
Key
.
status
,
Context
.
MODE_PRIVATE
)
lazy
val
receiver
=
new
StateBroadcastReceiver
lazy
val
receiver
=
new
StateBroadcastReceiver
lazy
val
drawer
=
MenuDrawer
.
attach
(
this
)
lazy
val
drawer
=
MenuDrawer
.
attach
(
this
)
lazy
val
listView
=
new
ListView
(
this
)
lazy
val
menuAdapter
=
new
MenuAdapter
(
this
,
getMenuList
)
lazy
val
menuAdapter
=
new
MenuAdapter
(
this
,
getMenuList
)
lazy
val
profileManager
=
getApplication
.
asInstanceOf
[
ShadowsocksApplication
].
profileManager
lazy
val
listView
=
new
ListView
(
this
)
lazy
val
profileManager
=
new
ProfileManager
(
settings
,
getApplication
.
asInstanceOf
[
ShadowsocksApplication
].
dbHelper
)
private
val
handler
:
Handler
=
new
Handler
{
private
val
handler
:
Handler
=
new
Handler
{
override
def
handleMessage
(
msg
:
Message
)
{
override
def
handleMessage
(
msg
:
Message
)
{
...
@@ -291,10 +363,10 @@ class Shadowsocks
...
@@ -291,10 +363,10 @@ class Shadowsocks
}
}
}
}
def
onSharedPreferenceChanged
(
prefs
:
SharedPreferences
,
key
:
String
)
{
override
def
onSharedPreferenceChanged
(
prefs
:
SharedPreferences
,
key
:
String
)
{
if
(
key
==
Key
.
isGlobalProxy
)
{
if
(
key
==
Key
.
profileName
)
{
val
enabled
=
state
!=
State
.
CONNECTED
&&
state
!=
State
.
CONNECTING
profileManager
.
save
()
setPreferenceEnabled
(
enable
d
)
menuAdapter
.
updateList
(
getMenuList
,
Shadowsocks
.
currentProfile
.
i
d
)
}
}
}
}
...
@@ -407,6 +479,10 @@ class Shadowsocks
...
@@ -407,6 +479,10 @@ class Shadowsocks
setHeaderRes
(
R
.
xml
.
shadowsocks_headers
)
setHeaderRes
(
R
.
xml
.
shadowsocks_headers
)
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
Shadowsocks
.
currentProfile
=
{
profileManager
.
getProfile
(
settings
.
getInt
(
Key
.
profileId
,
-
1
))
getOrElse
new
Profile
()
}
listView
.
setAdapter
(
menuAdapter
)
listView
.
setAdapter
(
menuAdapter
)
drawer
.
setMenuView
(
listView
)
drawer
.
setMenuView
(
listView
)
...
@@ -422,7 +498,6 @@ class Shadowsocks
...
@@ -422,7 +498,6 @@ class Shadowsocks
getSupportActionBar
.
setDisplayShowTitleEnabled
(
false
)
getSupportActionBar
.
setDisplayShowTitleEnabled
(
false
)
getSupportActionBar
.
setDisplayShowCustomEnabled
(
true
)
getSupportActionBar
.
setDisplayShowCustomEnabled
(
true
)
// getSupportActionBar.setDisplayShowHomeEnabled(false)
// getSupportActionBar.setDisplayShowHomeEnabled(false)
val
title
:
TextView
=
switchLayout
.
findViewById
(
R
.
id
.
title
).
asInstanceOf
[
TextView
]
val
title
:
TextView
=
switchLayout
.
findViewById
(
R
.
id
.
title
).
asInstanceOf
[
TextView
]
val
tf
:
Typeface
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
val
tf
:
Typeface
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
...
@@ -445,16 +520,49 @@ class Shadowsocks
...
@@ -445,16 +520,49 @@ class Shadowsocks
handler
.
sendEmptyMessage
(
MSG_INITIAL_FINISH
)
handler
.
sendEmptyMessage
(
MSG_INITIAL_FINISH
)
}
}
}
}
}
override
def
onActiveViewChanged
(
v
:
View
,
pos
:
Int
)
{
drawer
.
setActiveView
(
v
,
pos
)
}
}
def
updateProfile
(
id
:
Int
)
{
def
updateProfile
(
id
:
Int
)
{
drawer
.
closeMenu
(
true
)
handler
.
postDelayed
(
new
Runnable
{
def
run
()
{
Shadowsocks
.
currentProfile
=
profileManager
.
load
(
id
)
updatePreferenceScreen
()
}
},
600
)
if
(!
isSinglePane
)
sendBroadcast
(
new
Intent
(
Action
.
UPDATE_FRAGMENT
))
}
def
delProfile
(
id
:
Int
)
:
Boolean
=
{
drawer
.
closeMenu
(
true
)
handler
.
postDelayed
(
new
Runnable
{
def
run
()
{
profileManager
.
delProfile
(
id
)
val
profileId
=
{
val
profiles
=
profileManager
.
getAllProfiles
.
getOrElse
(
List
[
Profile
]())
if
(
profiles
.
isEmpty
)
-
1
else
profiles
(
0
).
id
}
Shadowsocks
.
currentProfile
=
profileManager
.
load
(
profileId
)
updatePreferenceScreen
()
menuAdapter
.
updateList
(
getMenuList
,
Shadowsocks
.
currentProfile
.
id
)
}
},
600
)
if
(!
isSinglePane
)
sendBroadcast
(
new
Intent
(
Action
.
UPDATE_FRAGMENT
))
true
}
}
def
getProfileList
:
List
[
Item
]
=
{
def
getProfileList
:
List
[
Item
]
=
{
val
list
=
profileManager
.
getAllProfiles
getOrElse
List
[
Profile
]()
val
list
=
profileManager
.
getAllProfiles
getOrElse
List
[
Profile
]()
list
.
map
(
p
=>
new
Item
(
p
.
id
,
p
.
name
,
-
1
,
updateProfile
))
list
.
map
(
p
=>
new
Item
(
p
.
id
,
p
.
name
,
-
1
,
updateProfile
,
delProfile
))
}
}
def
getMenuList
:
List
[
Any
]
=
{
def
getMenuList
:
List
[
Any
]
=
{
...
@@ -465,28 +573,31 @@ class Shadowsocks
...
@@ -465,28 +573,31 @@ class Shadowsocks
buf
++=
getProfileList
buf
++=
getProfileList
buf
+=
new
Item
(-
1
,
getString
(
R
.
string
.
add_profile
),
android
.
R
.
drawable
.
ic_menu_add
,
_
=>
{
updateProfile
(-
1
)
profileManager
.
save
()
menuAdapter
.
updateList
(
getMenuList
,
Shadowsocks
.
currentProfile
.
id
)
})
buf
+=
new
Category
(
"Settings"
)
buf
+=
new
Category
(
"Settings"
)
buf
+=
new
Item
(-
1
,
getString
(
R
.
string
.
recovery
),
android
.
R
.
drawable
.
ic_menu_revert
,
buf
+=
new
Item
(-
100
,
getString
(
R
.
string
.
recovery
),
android
.
R
.
drawable
.
ic_menu_revert
,
_
=>
{
_
=>
{
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"reset"
,
getVersionName
,
0L
)
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"reset"
,
getVersionName
,
0L
)
recovery
()
recovery
()
})
})
buf
+=
new
Item
(-
2
,
getString
(
R
.
string
.
flush_dnscache
),
android
.
R
.
drawable
.
ic_menu_delete
,
buf
+=
_
=>
{
new
Item
(-
200
,
getString
(
R
.
string
.
flush_dnscache
),
android
.
R
.
drawable
.
ic_menu_delete
,
_
=>
{
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"flush_dnscache"
,
getVersionName
,
0L
)
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"flush_dnscache"
,
getVersionName
,
0L
)
flushDnsCache
()
flushDnsCache
()
})
})
buf
+=
new
Item
(-
3
,
getString
(
R
.
string
.
about
),
android
.
R
.
drawable
.
ic_menu_info_details
,
buf
+=
new
Item
(-
300
,
getString
(
R
.
string
.
about
),
android
.
R
.
drawable
.
ic_menu_info_details
,
_
=>
{
_
=>
{
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"about"
,
getVersionName
,
0L
)
EasyTracker
.
getTracker
.
sendEvent
(
Shadowsocks
.
TAG
,
"about"
,
getVersionName
,
0L
)
showAbout
()
showAbout
()
})
})
buf
.
toList
buf
.
toList
}
}
override
def
onKeyDown
(
keyCode
:
Int
,
event
:
KeyEvent
)
:
Boolean
=
{
override
def
onKeyDown
(
keyCode
:
Int
,
event
:
KeyEvent
)
:
Boolean
=
{
...
@@ -516,6 +627,7 @@ class Shadowsocks
...
@@ -516,6 +627,7 @@ class Shadowsocks
protected
override
def
onPause
()
{
protected
override
def
onPause
()
{
super
.
onPause
()
super
.
onPause
()
prepared
=
false
prepared
=
false
settings
.
unregisterOnSharedPreferenceChangeListener
(
this
)
}
}
protected
override
def
onResume
()
{
protected
override
def
onResume
()
{
...
@@ -549,6 +661,8 @@ class Shadowsocks
...
@@ -549,6 +661,8 @@ class Shadowsocks
}
}
switchButton
.
setOnCheckedChangeListener
(
this
)
switchButton
.
setOnCheckedChangeListener
(
this
)
settings
.
registerOnSharedPreferenceChangeListener
(
this
)
}
}
private
def
setPreferenceEnabled
(
enabled
:
Boolean
)
{
private
def
setPreferenceEnabled
(
enabled
:
Boolean
)
{
...
@@ -562,8 +676,8 @@ class Shadowsocks
...
@@ -562,8 +676,8 @@ class Shadowsocks
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
val
pref
=
findPreference
(
name
)
val
pref
=
findPreference
(
name
)
if
(
pref
!=
null
)
{
if
(
pref
!=
null
)
{
if
(
Seq
(
Key
.
isAutoConnect
,
Key
.
isGlobalProxy
,
Key
.
isTrafficStat
,
if
(
Seq
(
Key
.
isAutoConnect
,
Key
.
isGlobalProxy
,
Key
.
isTrafficStat
,
Key
.
proxyedApps
)
Key
.
proxyedApps
)
.
contains
(
name
))
{
.
contains
(
name
))
{
pref
.
setEnabled
(
enabled
&&
isRoot
)
pref
.
setEnabled
(
enabled
&&
isRoot
)
}
else
{
}
else
{
pref
.
setEnabled
(
enabled
)
pref
.
setEnabled
(
enabled
)
...
@@ -572,6 +686,18 @@ class Shadowsocks
...
@@ -572,6 +686,18 @@ class Shadowsocks
}
}
}
}
private
def
updatePreferenceScreen
()
{
val
profile
=
Shadowsocks
.
currentProfile
for
(
name
<-
Shadowsocks
.
PROXY_PREFS
)
{
val
pref
=
findPreference
(
name
)
Shadowsocks
.
updatePreference
(
pref
,
name
,
profile
)
}
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
val
pref
=
findPreference
(
name
)
Shadowsocks
.
updatePreference
(
pref
,
name
,
profile
)
}
}
override
def
onStart
()
{
override
def
onStart
()
{
super
.
onStart
()
super
.
onStart
()
EasyTracker
.
getInstance
.
activityStart
(
this
)
EasyTracker
.
getInstance
.
activityStart
(
this
)
...
@@ -790,7 +916,7 @@ class Shadowsocks
...
@@ -790,7 +916,7 @@ class Shadowsocks
setPreferenceEnabled
(
enabled
=
true
)
setPreferenceEnabled
(
enabled
=
true
)
}
}
}
}
sendBroadcast
(
new
Intent
(
Action
.
UPDATE_FRAGMENT
))
if
(!
isSinglePane
)
sendBroadcast
(
new
Intent
(
Action
.
UPDATE_FRAGMENT
))
}
}
}
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
View file @
a2848ce5
...
@@ -44,7 +44,6 @@ import com.github.shadowsocks.database.{ProfileManager, DBHelper}
...
@@ -44,7 +44,6 @@ import com.github.shadowsocks.database.{ProfileManager, DBHelper}
class
ShadowsocksApplication
extends
Application
{
class
ShadowsocksApplication
extends
Application
{
lazy
val
dbHelper
=
new
DBHelper
(
this
)
lazy
val
dbHelper
=
new
DBHelper
(
this
)
lazy
val
profileManager
=
new
ProfileManager
(
dbHelper
)
override
def
onCreate
()
{
override
def
onCreate
()
{
EasyTracker
.
getInstance
.
setContext
(
this
)
EasyTracker
.
getInstance
.
setContext
(
this
)
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksService.scala
View file @
a2848ce5
...
@@ -324,18 +324,8 @@ class ShadowsocksService extends Service {
...
@@ -324,18 +324,8 @@ class ShadowsocksService extends Service {
val
icon
=
getResources
.
getDrawable
(
R
.
drawable
.
ic_stat_shadowsocks
)
val
icon
=
getResources
.
getDrawable
(
R
.
drawable
.
ic_stat_shadowsocks
)
if
(
rate
>=
0
)
{
if
(
rate
>=
0
)
{
val
bitmap
=
Bitmap
.
createBitmap
(
icon
.
getIntrinsicWidth
*
4
,
val
bitmap
=
Utils
.
getBitmap
(
rate
.
toString
,
icon
.
getIntrinsicWidth
*
4
,
icon
.
getIntrinsicHeight
*
4
,
Bitmap
.
Config
.
ARGB_8888
)
icon
.
getIntrinsicHeight
*
4
,
Color
.
TRANSPARENT
)
val
r
=
rate
.
toString
val
size
=
bitmap
.
getHeight
/
4
val
canvas
=
new
Canvas
(
bitmap
)
val
paint
=
new
Paint
()
paint
.
setColor
(
Color
.
WHITE
)
paint
.
setTextSize
(
size
)
val
bounds
=
new
Rect
()
paint
.
getTextBounds
(
r
,
0
,
r
.
length
,
bounds
)
canvas
.
drawText
(
r
,
(
bitmap
.
getWidth
-
bounds
.
width
())
/
2
,
bitmap
.
getHeight
-
(
bitmap
.
getHeight
-
bounds
.
height
())
/
2
,
paint
)
builder
.
setLargeIcon
(
bitmap
)
builder
.
setLargeIcon
(
bitmap
)
if
(
rate
<
1000
)
{
if
(
rate
<
1000
)
{
...
...
src/main/scala/com/github/shadowsocks/Utils.scala
View file @
a2848ce5
...
@@ -49,10 +49,11 @@ import org.apache.http.conn.util.InetAddressUtils
...
@@ -49,10 +49,11 @@ import org.apache.http.conn.util.InetAddressUtils
import
scala.collection.mutable.ArrayBuffer
import
scala.collection.mutable.ArrayBuffer
import
org.xbill.DNS._
import
org.xbill.DNS._
import
scala.Some
import
scala.Some
import
android.graphics.
{
Canvas
,
Bitmap
}
import
android.graphics.
_
import
android.app.ActivityManager
import
android.app.ActivityManager
import
android.os.Build
import
android.os.Build
import
android.provider.Settings
import
android.provider.Settings
import
scala.Some
object
Config
{
object
Config
{
val
SHADOWSOCKS
=
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"
val
SHADOWSOCKS
=
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"
...
@@ -112,10 +113,13 @@ object Config {
...
@@ -112,10 +113,13 @@ object Config {
}
}
case
class
Config
(
isGlobalProxy
:
Boolean
,
isGFWList
:
Boolean
,
isBypassApps
:
Boolean
,
isTrafficStat
:
Boolean
,
case
class
Config
(
isGlobalProxy
:
Boolean
,
isGFWList
:
Boolean
,
isBypassApps
:
Boolean
,
isTrafficStat
:
Boolean
,
var
proxy
:
String
,
sitekey
:
String
,
encMethod
:
String
,
remotePort
:
Int
,
profileName
:
String
,
var
proxy
:
String
,
sitekey
:
String
,
encMethod
:
String
,
remotePort
:
Int
,
localPort
:
Int
,
proxiedAppString
:
String
)
localPort
:
Int
,
proxiedAppString
:
String
)
object
Key
{
object
Key
{
val
profileId
=
"profileId"
val
profileName
=
"profileName"
val
proxied
=
"Proxyed"
val
proxied
=
"Proxyed"
val
isRoot
=
"isRoot"
val
isRoot
=
"isRoot"
...
@@ -137,6 +141,11 @@ object Key {
...
@@ -137,6 +141,11 @@ object Key {
val
localPort
=
"port"
val
localPort
=
"port"
}
}
object
Scheme
{
val
APP
=
"app://"
val
PROFILE
=
"profile://"
}
object
State
{
object
State
{
val
INIT
=
0
val
INIT
=
0
val
CONNECTING
=
1
val
CONNECTING
=
1
...
@@ -162,6 +171,7 @@ object Extra {
...
@@ -162,6 +171,7 @@ object Extra {
edit
.
putBoolean
(
Key
.
isBypassApps
,
config
.
isBypassApps
)
edit
.
putBoolean
(
Key
.
isBypassApps
,
config
.
isBypassApps
)
edit
.
putBoolean
(
Key
.
isTrafficStat
,
config
.
isTrafficStat
)
edit
.
putBoolean
(
Key
.
isTrafficStat
,
config
.
isTrafficStat
)
edit
.
putString
(
Key
.
profileName
,
config
.
profileName
)
edit
.
putString
(
Key
.
proxy
,
config
.
proxy
)
edit
.
putString
(
Key
.
proxy
,
config
.
proxy
)
edit
.
putString
(
Key
.
sitekey
,
config
.
sitekey
)
edit
.
putString
(
Key
.
sitekey
,
config
.
sitekey
)
edit
.
putString
(
Key
.
encMethod
,
config
.
encMethod
)
edit
.
putString
(
Key
.
encMethod
,
config
.
encMethod
)
...
@@ -177,6 +187,7 @@ object Extra {
...
@@ -177,6 +187,7 @@ object Extra {
val
isBypassApps
=
intent
.
getBooleanExtra
(
Key
.
isBypassApps
,
false
)
val
isBypassApps
=
intent
.
getBooleanExtra
(
Key
.
isBypassApps
,
false
)
val
isTrafficStat
=
intent
.
getBooleanExtra
(
Key
.
isTrafficStat
,
false
)
val
isTrafficStat
=
intent
.
getBooleanExtra
(
Key
.
isTrafficStat
,
false
)
val
profileName
=
intent
.
getStringExtra
(
Key
.
profileName
)
val
proxy
=
intent
.
getStringExtra
(
Key
.
proxy
)
val
proxy
=
intent
.
getStringExtra
(
Key
.
proxy
)
val
sitekey
=
intent
.
getStringExtra
(
Key
.
sitekey
)
val
sitekey
=
intent
.
getStringExtra
(
Key
.
sitekey
)
val
encMethod
=
intent
.
getStringExtra
(
Key
.
encMethod
)
val
encMethod
=
intent
.
getStringExtra
(
Key
.
encMethod
)
...
@@ -184,7 +195,7 @@ object Extra {
...
@@ -184,7 +195,7 @@ object Extra {
val
localPort
=
intent
.
getIntExtra
(
Key
.
localPort
,
1984
)
val
localPort
=
intent
.
getIntExtra
(
Key
.
localPort
,
1984
)
val
proxiedString
=
intent
.
getStringExtra
(
Key
.
proxied
)
val
proxiedString
=
intent
.
getStringExtra
(
Key
.
proxied
)
new
Config
(
isGlobalProxy
,
isGFWList
,
isBypassApps
,
isTrafficStat
,
proxy
,
sitekey
,
encMethod
,
remotePort
,
new
Config
(
isGlobalProxy
,
isGFWList
,
isBypassApps
,
isTrafficStat
,
pro
fileName
,
pro
xy
,
sitekey
,
encMethod
,
remotePort
,
localPort
,
proxiedString
)
localPort
,
proxiedString
)
}
}
...
@@ -194,6 +205,7 @@ object Extra {
...
@@ -194,6 +205,7 @@ object Extra {
val
isBypassApps
=
settings
.
getBoolean
(
Key
.
isBypassApps
,
false
)
val
isBypassApps
=
settings
.
getBoolean
(
Key
.
isBypassApps
,
false
)
val
isTrafficStat
=
settings
.
getBoolean
(
Key
.
isTrafficStat
,
false
)
val
isTrafficStat
=
settings
.
getBoolean
(
Key
.
isTrafficStat
,
false
)
val
profileName
=
settings
.
getString
(
Key
.
profileName
,
"default"
)
val
proxy
=
settings
.
getString
(
Key
.
proxy
,
"127.0.0.1"
)
match
{
val
proxy
=
settings
.
getString
(
Key
.
proxy
,
"127.0.0.1"
)
match
{
case
"198.199.101.152"
=>
BuildConfig
.
SERVER
case
"198.199.101.152"
=>
BuildConfig
.
SERVER
case
s
:
String
=>
s
case
s
:
String
=>
s
...
@@ -232,6 +244,7 @@ object Extra {
...
@@ -232,6 +244,7 @@ object Extra {
intent
.
putExtra
(
Key
.
isBypassApps
,
isBypassApps
)
intent
.
putExtra
(
Key
.
isBypassApps
,
isBypassApps
)
intent
.
putExtra
(
Key
.
isTrafficStat
,
isTrafficStat
)
intent
.
putExtra
(
Key
.
isTrafficStat
,
isTrafficStat
)
intent
.
putExtra
(
Key
.
profileName
,
profileName
)
intent
.
putExtra
(
Key
.
proxy
,
proxy
)
intent
.
putExtra
(
Key
.
proxy
,
proxy
)
intent
.
putExtra
(
Key
.
sitekey
,
sitekey
)
intent
.
putExtra
(
Key
.
sitekey
,
sitekey
)
intent
.
putExtra
(
Key
.
encMethod
,
encMethod
)
intent
.
putExtra
(
Key
.
encMethod
,
encMethod
)
...
@@ -265,6 +278,36 @@ object Utils {
...
@@ -265,6 +278,36 @@ object Utils {
var
data_path
:
String
=
null
var
data_path
:
String
=
null
var
rootTries
=
0
var
rootTries
=
0
/*
* round or floor depending on whether you are using offsets(floor) or
* widths(round)
*/
def
dpToPx
(
context
:
Context
,
dp
:
Float
)
:
Float
=
{
val
density
=
context
.
getResources
.
getDisplayMetrics
.
density
dp
*
density
}
def
pxToDp
(
context
:
Context
,
px
:
Float
)
:
Float
=
{
val
density
=
context
.
getResources
.
getDisplayMetrics
.
density
px
/
density
}
def
getBitmap
(
text
:
String
,
width
:
Int
,
height
:
Int
,
background
:
Int
)
:
Bitmap
=
{
val
bitmap
=
Bitmap
.
createBitmap
(
width
,
height
,
Bitmap
.
Config
.
ARGB_8888
)
val
size
=
bitmap
.
getHeight
/
4
val
canvas
=
new
Canvas
(
bitmap
)
canvas
.
drawColor
(
background
)
val
paint
=
new
Paint
()
paint
.
setColor
(
Color
.
WHITE
)
paint
.
setTextSize
(
size
)
val
bounds
=
new
Rect
()
paint
.
getTextBounds
(
text
,
0
,
text
.
length
,
bounds
)
canvas
.
drawText
(
text
,
(
bitmap
.
getWidth
-
bounds
.
width
())
/
2
,
bitmap
.
getHeight
-
(
bitmap
.
getHeight
-
bounds
.
height
())
/
2
,
paint
)
bitmap
}
// Blocked > 3 seconds
// Blocked > 3 seconds
def
toggleAirplaneMode
(
context
:
Context
)
{
def
toggleAirplaneMode
(
context
:
Context
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
17
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
17
)
{
...
...
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
View file @
a2848ce5
...
@@ -46,7 +46,7 @@ import com.j256.ormlite.support.ConnectionSource
...
@@ -46,7 +46,7 @@ import com.j256.ormlite.support.ConnectionSource
import
com.j256.ormlite.table.TableUtils
import
com.j256.ormlite.table.TableUtils
import
com.j256.ormlite.dao.Dao
import
com.j256.ormlite.dao.Dao
class
DBHelper
(
val
context
:
Context
)
extends
OrmLiteSqliteOpenHelper
(
context
,
"profile.db"
,
null
,
3
)
{
class
DBHelper
(
val
context
:
Context
)
extends
OrmLiteSqliteOpenHelper
(
context
,
"profile.db"
,
null
,
7
)
{
lazy
val
profileDao
:
Dao
[
Profile
,
Int
]
=
getDao
(
classOf
[
Profile
])
lazy
val
profileDao
:
Dao
[
Profile
,
Int
]
=
getDao
(
classOf
[
Profile
])
...
...
src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala
View file @
a2848ce5
...
@@ -39,39 +39,39 @@
...
@@ -39,39 +39,39 @@
package
com.github.shadowsocks.database
package
com.github.shadowsocks.database
import
android.content.
{
DialogInterface
,
Context
}
import
android.content.
Context
import
android.view.LayoutInflater
import
android.view.LayoutInflater
import
android.view.View
import
android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.widget.BaseAdapter
import
android.widget.BaseAdapter
import
android.widget.TextView
import
android.widget.TextView
import
com.github.shadowsocks.
R
import
com.github.shadowsocks.
{
Shadowsocks
,
R
}
import
android.view.View.
OnClickListener
import
android.view.View.
{
OnLongClickListener
,
OnClickListener
}
case
class
Item
(
id
:
Int
,
title
:
String
,
iconRes
:
Int
,
action
:
Int
=>
Unit
)
case
class
Item
(
id
:
Int
,
title
:
String
,
iconRes
:
Int
,
click
:
Int
=>
Unit
,
longClick
:
Int
=>
Boolean
=
_
=>
false
)
case
class
Category
(
title
:
String
)
case
class
Category
(
title
:
String
)
object
MenuAdapter
{
object
MenuAdapter
{
trait
MenuListener
{
trait
MenuListener
{
def
onActiveViewChanged
(
v
:
View
)
def
onActiveViewChanged
(
v
:
View
,
pos
:
Int
)
}
}
val
UNDEFINED
=
-
1
val
UNDEFINED
=
-
1
val
CATEGORY
=
0
val
CATEGORY
=
0
val
ITEM
=
1
val
ITEM
=
1
}
}
class
MenuAdapter
(
context
:
Context
,
var
items
:
List
[
Any
])
extends
BaseAdapter
{
class
MenuAdapter
(
context
:
Context
,
var
items
:
List
[
Any
])
extends
BaseAdapter
{
def
setListener
(
listener
:
MenuAdapter.MenuListener
)
{
def
setListener
(
listener
:
MenuAdapter.MenuListener
)
{
mL
istener
=
listener
this
.
l
istener
=
listener
}
}
def
setActivePosition
(
activePosition
:
Int
)
{
def
setActivePosition
(
activePosition
:
Int
)
{
mA
ctivePosition
=
activePosition
this
.
a
ctivePosition
=
activePosition
}
}
@Override
def
getCount
:
Int
=
{
@Override
def
getCount
:
Int
=
{
...
@@ -121,32 +121,46 @@ class MenuAdapter (context: Context, var items: List[Any]) extends BaseAdapter {
...
@@ -121,32 +121,46 @@ class MenuAdapter (context: Context, var items: List[Any]) extends BaseAdapter {
}
}
val
tv
:
TextView
=
v
.
asInstanceOf
[
TextView
]
val
tv
:
TextView
=
v
.
asInstanceOf
[
TextView
]
tv
.
setText
(
value
.
title
)
tv
.
setText
(
value
.
title
)
tv
.
setCompoundDrawablesWithIntrinsicBounds
(
value
.
iconRes
,
0
,
0
,
0
)
if
(
value
.
iconRes
!=
-
1
)
{
tv
.
setCompoundDrawablesWithIntrinsicBounds
(
value
.
iconRes
,
0
,
0
,
0
)
}
tv
.
setOnClickListener
(
new
OnClickListener
{
tv
.
setOnClickListener
(
new
OnClickListener
{
def
onClick
(
view
:
View
)
{
def
onClick
(
view
:
View
)
{
val
item
=
view
.
getTag
(
R
.
id
.
mdItem
).
asInstanceOf
[
Item
]
val
item
=
view
.
getTag
(
R
.
id
.
mdItem
).
asInstanceOf
[
Item
]
item
.
action
(
item
.
id
)
item
.
click
(
item
.
id
)
}
})
tv
.
setOnLongClickListener
(
new
OnLongClickListener
{
def
onLongClick
(
view
:
View
)
:
Boolean
=
{
val
item
=
view
.
getTag
(
R
.
id
.
mdItem
).
asInstanceOf
[
Item
]
item
.
longClick
(
item
.
id
)
}
}
})
})
v
.
setTag
(
R
.
id
.
mdItem
,
value
)
v
.
setTag
(
R
.
id
.
mdItem
,
value
)
case
_
=>
case
_
=>
}
}
v
.
setTag
(
R
.
id
.
mdActiveViewPosition
,
position
)
v
.
setTag
(
R
.
id
.
mdActiveViewPosition
,
position
)
if
(
position
==
mA
ctivePosition
)
{
if
(
position
==
a
ctivePosition
)
{
if
(
mListener
!=
null
)
mListener
.
onActiveViewChanged
(
v
)
if
(
listener
!=
null
)
listener
.
onActiveViewChanged
(
v
,
position
)
}
}
v
v
}
}
def
updateList
(
list
:
List
[
Any
])
{
def
updateList
(
list
:
List
[
Any
]
,
activeId
:
Int
)
{
items
=
list
items
=
list
activePosition
=
items
.
indexWhere
{
case
item
:
Item
=>
item
.
id
==
activeId
case
_
=>
false
}
notifyDataSetChanged
()
notifyDataSetChanged
()
}
}
private
var
mL
istener
:
MenuAdapter.MenuListener
=
null
private
var
l
istener
:
MenuAdapter.MenuListener
=
null
private
var
mActivePosition
:
Int
=
0
private
var
activePosition
:
Int
=
-
1
}
}
src/main/scala/com/github/shadowsocks/database/Profile.scala
View file @
a2848ce5
...
@@ -42,14 +42,14 @@ package com.github.shadowsocks.database
...
@@ -42,14 +42,14 @@ package com.github.shadowsocks.database
import
com.j256.ormlite.field.
{
DataType
,
DatabaseField
}
import
com.j256.ormlite.field.
{
DataType
,
DatabaseField
}
class
Profile
{
class
Profile
{
@DatabaseField
(
i
d
=
true
)
@DatabaseField
(
generatedI
d
=
true
)
var
id
:
Int
=
0
var
id
:
Int
=
0
@DatabaseField
@DatabaseField
var
name
:
String
=
null
var
name
:
String
=
"Untitled"
@DatabaseField
@DatabaseField
var
host
:
String
=
null
var
host
:
String
=
""
@DatabaseField
@DatabaseField
var
localPort
:
Int
=
0
var
localPort
:
Int
=
0
...
@@ -58,13 +58,13 @@ class Profile {
...
@@ -58,13 +58,13 @@ class Profile {
var
remotePort
:
Int
=
0
var
remotePort
:
Int
=
0
@DatabaseField
@DatabaseField
var
password
:
String
=
null
var
password
:
String
=
""
@DatabaseField
@DatabaseField
var
method
:
String
=
null
var
method
:
String
=
""
@DatabaseField
@DatabaseField
var
date
:
String
=
null
var
date
:
String
=
""
@DatabaseField
@DatabaseField
var
upload
:
Int
=
0
var
upload
:
Int
=
0
...
@@ -78,9 +78,15 @@ class Profile {
...
@@ -78,9 +78,15 @@ class Profile {
@DatabaseField
@DatabaseField
var
global
:
Boolean
=
false
var
global
:
Boolean
=
false
@DatabaseField
var
bypass
:
Boolean
=
false
@DatabaseField
var
traffic
:
Boolean
=
false
@DatabaseField
(
dataType
=
DataType
.
LONG_STRING
)
@DatabaseField
(
dataType
=
DataType
.
LONG_STRING
)
var
individual
:
String
=
null
var
individual
:
String
=
""
@DatabaseField
(
dataType
=
DataType
.
LONG_STRING
)
@DatabaseField
(
dataType
=
DataType
.
LONG_STRING
)
var
description
:
String
=
null
var
description
:
String
=
""
}
}
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
View file @
a2848ce5
...
@@ -40,18 +40,20 @@
...
@@ -40,18 +40,20 @@
package
com.github.shadowsocks.database
package
com.github.shadowsocks.database
import
android.util.Log
import
android.util.Log
import
com.github.shadowsocks.Shadowsocks
import
com.github.shadowsocks._
import
android.content.
{
SharedPreferences
,
Context
}
class
ProfileManager
(
dbHelper
:
DBHelper
)
{
class
ProfileManager
(
settings
:
SharedPreferences
,
dbHelper
:
DBHelper
)
{
def
addProfile
(
profile
:
Profile
)
:
Boolean
=
{
def
createOrUpdateProfile
(
profile
:
Profile
)
:
Boolean
=
{
try
{
try
{
dbHelper
.
profileDao
.
createOrUpdate
(
profile
)
dbHelper
.
profileDao
.
createOrUpdate
(
profile
)
true
}
catch
{
}
catch
{
case
ex
:
Exception
=>
case
ex
:
Exception
=>
Log
.
e
(
Shadowsocks
.
TAG
,
"addProfile"
,
ex
)
Log
.
e
(
Shadowsocks
.
TAG
,
"addProfile"
,
ex
)
return
false
false
}
}
true
}
}
def
getProfile
(
id
:
Int
)
:
Option
[
Profile
]
=
{
def
getProfile
(
id
:
Int
)
:
Option
[
Profile
]
=
{
...
@@ -70,12 +72,12 @@ class ProfileManager(dbHelper: DBHelper) {
...
@@ -70,12 +72,12 @@ class ProfileManager(dbHelper: DBHelper) {
def
delProfile
(
id
:
Int
)
:
Boolean
=
{
def
delProfile
(
id
:
Int
)
:
Boolean
=
{
try
{
try
{
dbHelper
.
profileDao
.
deleteById
(
id
)
dbHelper
.
profileDao
.
deleteById
(
id
)
true
}
catch
{
}
catch
{
case
ex
:
Exception
=>
case
ex
:
Exception
=>
Log
.
e
(
Shadowsocks
.
TAG
,
"delProfile"
,
ex
)
Log
.
e
(
Shadowsocks
.
TAG
,
"delProfile"
,
ex
)
return
false
false
}
}
true
}
}
def
getAllProfiles
:
Option
[
List
[
Profile
]]
=
{
def
getAllProfiles
:
Option
[
List
[
Profile
]]
=
{
...
@@ -88,4 +90,70 @@ class ProfileManager(dbHelper: DBHelper) {
...
@@ -88,4 +90,70 @@ class ProfileManager(dbHelper: DBHelper) {
None
None
}
}
}
}
def
load
(
id
:
Int
)
:
Profile
=
{
Log
.
d
(
Shadowsocks
.
TAG
,
id
+
" "
)
save
()
val
profile
=
getProfile
(
id
)
getOrElse
{
val
p
=
new
Profile
()
createOrUpdateProfile
(
p
)
p
}
Log
.
d
(
Shadowsocks
.
TAG
,
"load "
+
profile
.
id
+
" "
+
profile
.
name
)
val
edit
=
settings
.
edit
()
edit
.
putBoolean
(
Key
.
isGlobalProxy
,
profile
.
global
)
edit
.
putBoolean
(
Key
.
isGFWList
,
profile
.
chnroute
)
edit
.
putBoolean
(
Key
.
isBypassApps
,
profile
.
bypass
)
edit
.
putBoolean
(
Key
.
isTrafficStat
,
profile
.
traffic
)
edit
.
putString
(
Key
.
profileName
,
profile
.
name
)
edit
.
putString
(
Key
.
proxy
,
profile
.
host
)
edit
.
putString
(
Key
.
sitekey
,
profile
.
password
)
edit
.
putString
(
Key
.
encMethod
,
profile
.
method
)
edit
.
putString
(
Key
.
remotePort
,
profile
.
remotePort
.
toString
)
edit
.
putString
(
Key
.
localPort
,
profile
.
localPort
.
toString
)
edit
.
putString
(
Key
.
proxied
,
profile
.
individual
)
edit
.
putInt
(
Key
.
profileId
,
profile
.
id
)
edit
.
commit
()
profile
}
def
save
()
{
val
profile
=
new
Profile
()
profile
.
global
=
settings
.
getBoolean
(
Key
.
isGlobalProxy
,
false
)
profile
.
chnroute
=
settings
.
getBoolean
(
Key
.
isGFWList
,
false
)
profile
.
bypass
=
settings
.
getBoolean
(
Key
.
isBypassApps
,
false
)
profile
.
traffic
=
settings
.
getBoolean
(
Key
.
isTrafficStat
,
false
)
profile
.
name
=
settings
.
getString
(
Key
.
profileName
,
"default"
)
profile
.
host
=
settings
.
getString
(
Key
.
proxy
,
"127.0.0.1"
)
profile
.
password
=
settings
.
getString
(
Key
.
sitekey
,
"default"
)
profile
.
method
=
settings
.
getString
(
Key
.
encMethod
,
"table"
)
profile
.
remotePort
=
try
{
Integer
.
valueOf
(
settings
.
getString
(
Key
.
remotePort
,
"1984"
))
}
catch
{
case
ex
:
NumberFormatException
=>
{
1984
}
}
profile
.
localPort
=
try
{
Integer
.
valueOf
(
settings
.
getString
(
Key
.
localPort
,
"1984"
))
}
catch
{
case
ex
:
NumberFormatException
=>
{
1984
}
}
profile
.
individual
=
settings
.
getString
(
Key
.
proxied
,
""
)
profile
.
id
=
settings
.
getInt
(
Key
.
profileId
,
-
1
)
Log
.
d
(
Shadowsocks
.
TAG
,
"save "
+
profile
.
id
+
" "
+
profile
.
name
)
createOrUpdateProfile
(
profile
)
}
}
}
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