Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
f5e53cd6
Commit
f5e53cd6
authored
Aug 21, 2016
by
dvdandroid
Committed by
topjohnwu
Aug 22, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start materializing module fragment
parent
4a48f59d
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
500 additions
and
198 deletions
+500
-198
.gitignore
.gitignore
+2
-2
misc.xml
.idea/misc.xml
+1
-1
build.gradle
app/build.gradle
+7
-5
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+6
-1
WelcomeActivity.java
app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
+121
-0
Module.java
app/src/main/java/com/topjohnwu/magisk/model/Module.java
+0
-8
ModulesAdapter.java
...src/main/java/com/topjohnwu/magisk/rv/ModulesAdapter.java
+48
-38
LogFragment.java
app/src/main/java/com/topjohnwu/magisk/ui/LogFragment.java
+5
-0
MainActivity.java
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.java
+14
-8
ModulesFragment.java
...rc/main/java/com/topjohnwu/magisk/ui/ModulesFragment.java
+36
-13
RootFragment.java
app/src/main/java/com/topjohnwu/magisk/ui/RootFragment.java
+4
-0
fade_in.xml
app/src/main/res/anim/fade_in.xml
+8
-0
fade_out.xml
app/src/main/res/anim/fade_out.xml
+8
-0
ic_bug_report.xml
app/src/main/res/drawable-anydpi/ic_bug_report.xml
+9
-0
ic_extension.xml
app/src/main/res/drawable-anydpi/ic_extension.xml
+9
-0
root.xml
app/src/main/res/drawable/root.xml
+9
-0
activity_welcome.xml
app/src/main/res/layout/activity_welcome.xml
+41
-0
modules_fragment.xml
app/src/main/res/layout/modules_fragment.xml
+15
-0
row.xml
app/src/main/res/layout/row.xml
+79
-31
drawer.xml
app/src/main/res/menu/drawer.xml
+28
-0
colors.xml
app/src/main/res/values/colors.xml
+10
-3
strings.xml
app/src/main/res/values/strings.xml
+9
-0
styles.xml
app/src/main/res/values/styles.xml
+19
-1
build.gradle
build.gradle
+2
-0
Remounter.java
...n/java/org/sufficientlysecure/rootcommands/Remounter.java
+2
-1
RootCommands.java
...ava/org/sufficientlysecure/rootcommands/RootCommands.java
+1
-1
Shell.java
.../main/java/org/sufficientlysecure/rootcommands/Shell.java
+2
-1
Toolbox.java
...ain/java/org/sufficientlysecure/rootcommands/Toolbox.java
+1
-1
Command.java
.../org/sufficientlysecure/rootcommands/command/Command.java
+2
-1
Log.java
...in/java/org/sufficientlysecure/rootcommands/util/Log.java
+0
-82
Utils.java
.../java/org/sufficientlysecure/rootcommands/util/Utils.java
+2
-0
No files found.
.gitignore
View file @
f5e53cd6
*.iml
*.iml
.gradle
.gradle
/local.properties
/local.properties
/
.idea/
.idea/
/build
/build
\ No newline at end of file
.idea/misc.xml
View file @
f5e53cd6
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
<ConfirmationsSetting
value=
"0"
id=
"Add"
/>
<ConfirmationsSetting
value=
"0"
id=
"Add"
/>
<ConfirmationsSetting
value=
"0"
id=
"Remove"
/>
<ConfirmationsSetting
value=
"0"
id=
"Remove"
/>
</component>
</component>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_1_
8
"
assert-keyword=
"true"
jdk-15=
"true"
project-jdk-name=
"1.8"
project-jdk-type=
"JavaSDK"
>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_1_
7
"
assert-keyword=
"true"
jdk-15=
"true"
project-jdk-name=
"1.8"
project-jdk-type=
"JavaSDK"
>
<output
url=
"file://$PROJECT_DIR$/build/classes"
/>
<output
url=
"file://$PROJECT_DIR$/build/classes"
/>
</component>
</component>
<component
name=
"ProjectType"
>
<component
name=
"ProjectType"
>
...
...
app/build.gradle
View file @
f5e53cd6
apply
plugin:
'com.android.application'
apply
plugin:
'com.android.application'
apply
plugin:
'android-apt'
android
{
android
{
compileSdkVersion
24
compileSdkVersion
24
...
@@ -10,10 +11,6 @@ android {
...
@@ -10,10 +11,6 @@ android {
targetSdkVersion
24
targetSdkVersion
24
versionCode
3
versionCode
3
versionName
"v4"
versionName
"v4"
jackOptions
{
enabled
true
}
}
}
buildTypes
{
buildTypes
{
release
{
release
{
...
@@ -24,6 +21,11 @@ android {
...
@@ -24,6 +21,11 @@ android {
}
}
dependencies
{
dependencies
{
compile
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
]
)
compile
fileTree
(
include:
[
'*.jar'
],
dir:
'libs'
)
compile
project
(
':lib:RootCommands'
)
compile
project
(
':lib:RootCommands'
)
compile
'com.android.support:recyclerview-v7:24.2.0'
compile
'com.android.support:cardview-v7:24.2.0'
compile
'com.android.support:design:24.2.0'
compile
'com.jakewharton:butterknife:8.2.1'
apt
'com.jakewharton:butterknife-compiler:8.2.1'
}
}
app/src/main/AndroidManifest.xml
View file @
f5e53cd6
...
@@ -15,7 +15,12 @@
...
@@ -15,7 +15,12 @@
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</intent-filter>
</activity>
</activity>
<activity
android:name=
".ui.ModulesActivity"
>
<activity
android:name=
".WelcomeActivity"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</activity>
</application>
</application>
...
...
app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
0 → 100644
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.support.annotation.NonNull
;
import
android.support.design.widget.NavigationView
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.app.FragmentTransaction
;
import
android.support.v4.view.GravityCompat
;
import
android.support.v4.widget.DrawerLayout
;
import
android.support.v7.app.ActionBarDrawerToggle
;
import
android.support.v7.app.AppCompatActivity
;
import
android.support.v7.widget.Toolbar
;
import
android.view.MenuItem
;
import
android.view.View
;
import
com.topjohnwu.magisk.ui.LogFragment
;
import
com.topjohnwu.magisk.ui.ModulesFragment
;
import
com.topjohnwu.magisk.ui.RootFragment
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
WelcomeActivity
extends
AppCompatActivity
implements
NavigationView
.
OnNavigationItemSelectedListener
{
private
static
final
String
SELECTED_ITEM_ID
=
"SELECTED_ITEM_ID"
;
private
final
Handler
mDrawerHandler
=
new
Handler
();
@BindView
(
R
.
id
.
toolbar
)
Toolbar
toolbar
;
@BindView
(
R
.
id
.
drawer_layout
)
DrawerLayout
drawer
;
@BindView
(
R
.
id
.
nav_view
)
NavigationView
navigationView
;
@Override
protected
void
onCreate
(
final
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_welcome
);
ButterKnife
.
bind
(
this
);
setSupportActionBar
(
toolbar
);
ActionBarDrawerToggle
toggle
=
new
ActionBarDrawerToggle
(
this
,
drawer
,
toolbar
,
R
.
string
.
navigation_drawer_open
,
R
.
string
.
navigation_drawer_close
)
{
@Override
public
void
onDrawerOpened
(
View
drawerView
)
{
super
.
onDrawerOpened
(
drawerView
);
super
.
onDrawerSlide
(
drawerView
,
0
);
// this disables the arrow @ completed state
}
@Override
public
void
onDrawerSlide
(
View
drawerView
,
float
slideOffset
)
{
super
.
onDrawerSlide
(
drawerView
,
0
);
// this disables the animation
}
};
drawer
.
setDrawerListener
(
toggle
);
toggle
.
syncState
();
navigationView
.
setNavigationItemSelectedListener
(
this
);
if
(
savedInstanceState
!=
null
)
{
mDrawerHandler
.
removeCallbacksAndMessages
(
null
);
mDrawerHandler
.
postDelayed
(
new
Runnable
()
{
@Override
public
void
run
()
{
navigate
(
savedInstanceState
.
getInt
(
SELECTED_ITEM_ID
));
}
},
250
);
}
}
@Override
public
void
onBackPressed
()
{
if
(
drawer
.
isDrawerOpen
(
GravityCompat
.
START
))
{
drawer
.
closeDrawer
(
GravityCompat
.
START
);
}
else
{
super
.
onBackPressed
();
}
}
@Override
public
boolean
onNavigationItemSelected
(
@NonNull
final
MenuItem
menuItem
)
{
menuItem
.
setChecked
(
true
);
mDrawerHandler
.
removeCallbacksAndMessages
(
null
);
mDrawerHandler
.
postDelayed
(
new
Runnable
()
{
@Override
public
void
run
()
{
navigate
(
menuItem
.
getItemId
());
}
},
250
);
drawer
.
closeDrawer
(
GravityCompat
.
START
);
return
true
;
}
private
void
navigate
(
final
int
itemId
)
{
Fragment
navFragment
=
null
;
switch
(
itemId
)
{
case
R
.
id
.
root
:
setTitle
(
R
.
string
.
root
);
navFragment
=
new
RootFragment
();
break
;
case
R
.
id
.
modules
:
setTitle
(
R
.
string
.
modules
);
navFragment
=
new
ModulesFragment
();
break
;
case
R
.
id
.
log
:
setTitle
(
R
.
string
.
log
);
navFragment
=
new
LogFragment
();
break
;
}
if
(
navFragment
!=
null
)
{
FragmentTransaction
transaction
=
getSupportFragmentManager
().
beginTransaction
();
transaction
.
setCustomAnimations
(
R
.
anim
.
fade_in
,
R
.
anim
.
fade_out
);
try
{
transaction
.
replace
(
R
.
id
.
content_frame
,
navFragment
).
commit
();
}
catch
(
IllegalStateException
ignored
)
{
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/model/Module.java
View file @
f5e53cd6
...
@@ -12,7 +12,6 @@ public class Module {
...
@@ -12,7 +12,6 @@ public class Module {
private
String
mName
;
private
String
mName
;
private
String
mVersion
;
private
String
mVersion
;
private
int
mVersionCode
;
private
String
mDescription
;
private
String
mDescription
;
public
Module
(
File
file
)
{
public
Module
(
File
file
)
{
...
@@ -36,10 +35,6 @@ public class Module {
...
@@ -36,10 +35,6 @@ public class Module {
return
mName
;
return
mName
;
}
}
public
int
getVersionCode
()
{
return
mVersionCode
;
}
public
String
getVersion
()
{
public
String
getVersion
()
{
return
mVersion
;
return
mVersion
;
}
}
...
@@ -70,9 +65,6 @@ public class Module {
...
@@ -70,9 +65,6 @@ public class Module {
case
"version"
:
case
"version"
:
mVersion
=
value
;
mVersion
=
value
;
break
;
break
;
case
"versionCode"
:
mVersionCode
=
Integer
.
parseInt
(
value
);
break
;
case
"description"
:
case
"description"
:
mDescription
=
value
;
mDescription
=
value
;
break
;
break
;
...
...
app/src/main/java/com/topjohnwu/magisk/rv/ModulesAdapter.java
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
.
rv
;
package
com
.
topjohnwu
.
magisk
.
rv
;
import
android.annotation.SuppressLint
;
import
android.support.v7.widget.RecyclerView
;
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.ArrayAdapter
;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.R
;
...
@@ -13,48 +11,60 @@ import com.topjohnwu.magisk.model.Module;
...
@@ -13,48 +11,60 @@ import com.topjohnwu.magisk.model.Module;
import
java.util.List
;
import
java.util.List
;
public
class
ModulesAdapter
extends
ArrayAdapter
<
Module
>
{
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
ModulesAdapter
(
Context
context
,
int
resource
,
List
<
Module
>
modules
)
{
public
class
ModulesAdapter
extends
RecyclerView
.
Adapter
<
ModulesAdapter
.
ViewHolder
>
{
super
(
context
,
resource
,
modules
);
private
final
List
<
Module
>
mList
;
public
ModulesAdapter
(
List
<
Module
>
mList
)
{
this
.
mList
=
mList
;
}
}
@SuppressLint
(
"SetTextI18n"
)
@Override
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
ViewHolder
vh
;
View
view
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
row
,
parent
,
false
);
/*FIXME
if
(
convertView
==
null
)
{
final ViewHolder viewHolder = new ViewHolder(view);
LayoutInflater
inflater
=
(
LayoutInflater
)
getContext
().
getSystemService
(
Context
.
LAYOUT_INFLATER_SERVICE
);
view.setOnClickListener(new View.OnClickListener() {
convertView
=
inflater
.
inflate
(
R
.
layout
.
row
,
null
);
@Override
public void onClick(View v) {
vh
=
new
ViewHolder
();
listener.onItemClick(viewHolder.getAdapterPosition());
vh
.
name
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
name
);
vh
.
version
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
version
);
vh
.
versionCode
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
versionCode
);
vh
.
description
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
description
);
vh
.
cache
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
cache
);
convertView
.
setTag
(
vh
);
}
else
{
vh
=
(
ViewHolder
)
convertView
.
getTag
();
}
}
});*/
return
new
ViewHolder
(
view
);
}
@Override
public
void
onBindViewHolder
(
ViewHolder
holder
,
int
position
)
{
Module
module
=
mList
.
get
(
position
);
Module
module
=
getItem
(
position
);
holder
.
title
.
setText
(
module
.
getName
());
vh
.
name
.
setText
(
"name= "
+
module
.
getName
());
holder
.
versionName
.
setText
(
module
.
getVersion
());
vh
.
version
.
setText
(
"version= "
+
module
.
getVersion
());
holder
.
description
.
setText
(
module
.
getDescription
());
vh
.
versionCode
.
setText
(
"versioncode= "
+
module
.
getVersionCode
());
vh
.
description
.
setText
(
"description= "
+
module
.
getDescription
());
vh
.
cache
.
setText
(
"is from cache= "
+
module
.
isCache
());
return
convertView
;
//FIXME
//holder.cache.setText("" + module.isCache());
}
@Override
public
int
getItemCount
()
{
return
mList
.
size
();
}
}
static
class
ViewHolder
{
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
public
TextView
name
;
public
TextView
version
;
@BindView
(
R
.
id
.
title
)
TextView
title
;
public
TextView
versionCode
;
@BindView
(
R
.
id
.
version_name
)
TextView
versionName
;
public
TextView
description
;
@BindView
(
R
.
id
.
description
)
TextView
description
;
public
TextView
cache
;
//@BindView(R.id.cache) TextView cache;
public
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
ButterKnife
.
bind
(
this
,
itemView
);
}
}
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/LogFragment.java
0 → 100644
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
.
ui
;
public
class
LogFragment
extends
android
.
support
.
v4
.
app
.
Fragment
{
// private static final String MAGISK_LOG = "/cache/magisk.log";
}
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.java
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
.
ui
;
package
com
.
topjohnwu
.
magisk
.
ui
;
import
android.app.Activity
;
import
android.app.Activity
;
import
android.content.Intent
;
import
android.graphics.Color
;
import
android.graphics.Color
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.widget.CompoundButton
;
import
android.widget.Switch
;
import
android.widget.Switch
;
import
android.widget.TextView
;
import
android.widget.TextView
;
...
@@ -35,17 +35,23 @@ public class MainActivity extends Activity {
...
@@ -35,17 +35,23 @@ public class MainActivity extends Activity {
suPath
=
executeCommand
(
"getprop magisk.supath"
);
suPath
=
executeCommand
(
"getprop magisk.supath"
);
updateStatus
();
updateStatus
();
rootToggle
.
setOnCheckedChangeListener
((
view
,
checked
)
->
{
rootToggle
.
setOnCheckedChangeListener
(
new
CompoundButton
.
OnCheckedChangeListener
()
{
executeCommand
(
checked
?
"setprop magisk.root 1"
:
"setprop magisk.root 0"
);
@Override
public
void
onCheckedChanged
(
CompoundButton
compoundButton
,
boolean
b
)
{
executeCommand
(
b
?
"setprop magisk.root 1"
:
"setprop magisk.root 0"
);
updateStatus
();
updateStatus
();
}
});
});
selinuxToggle
.
setOnCheckedChangeListener
((
view
,
checked
)
->
{
selinuxToggle
.
setOnCheckedChangeListener
(
new
CompoundButton
.
OnCheckedChangeListener
()
{
executeCommand
(
checked
?
"setenforce 1"
:
"setenforce 0"
);
@Override
public
void
onCheckedChanged
(
CompoundButton
compoundButton
,
boolean
b
)
{
executeCommand
(
b
?
"setenforce 1"
:
"setenforce 0"
);
updateStatus
();
updateStatus
();
}
});
});
findViewById
(
R
.
id
.
modules
).
setOnClickListener
(
view
->
startActivity
(
new
Intent
(
this
,
ModulesActivity
.
class
)));
//
findViewById(R.id.modules).setOnClickListener(view -> startActivity(new Intent(this, ModulesActivity.class)));
}
}
private
void
updateStatus
()
{
private
void
updateStatus
()
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/Modules
Activity
.java
→
app/src/main/java/com/topjohnwu/magisk/ui/Modules
Fragment
.java
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
.
ui
;
package
com
.
topjohnwu
.
magisk
.
ui
;
import
android.app.Activity
;
import
android.app.ProgressDialog
;
import
android.app.ProgressDialog
;
import
android.os.AsyncTask
;
import
android.os.AsyncTask
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.widget.ListView
;
import
android.support.annotation.Nullable
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.model.Module
;
import
com.topjohnwu.magisk.model.Module
;
import
com.topjohnwu.magisk.rv.ModulesAdapter
;
import
com.topjohnwu.magisk.rv.ModulesAdapter
;
import
com.topjohnwu.magisk.ui.utils.Utils
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileFilter
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
public
class
ModulesActivity
extends
Activity
{
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
ModulesFragment
extends
android
.
support
.
v4
.
app
.
Fragment
{
private
static
final
String
MAGISK_PATH
=
"/magisk"
;
private
static
final
String
MAGISK_PATH
=
"/magisk"
;
private
static
final
String
MAGISK_CACHE_PATH
=
"/cache/magisk"
;
private
static
final
String
MAGISK_CACHE_PATH
=
"/cache/magisk"
;
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
private
List
<
Module
>
listModules
=
new
ArrayList
<>();
private
List
<
Module
>
listModules
=
new
ArrayList
<>();
private
ListView
mListView
;
@Nullable
@Override
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
View
v
=
inflater
.
inflate
(
R
.
layout
.
modules_fragment
,
container
,
false
);
setContentView
(
R
.
layout
.
activity_modules
);
ButterKnife
.
bind
(
this
,
v
);
mListView
=
(
ListView
)
findViewById
(
android
.
R
.
id
.
list
);
new
CheckFolders
().
execute
();
new
CheckFolders
().
execute
();
return
v
;
}
}
private
class
CheckFolders
extends
AsyncTask
<
Void
,
Integer
,
Boolean
>
{
private
class
CheckFolders
extends
AsyncTask
<
Void
,
Integer
,
Boolean
>
{
...
@@ -40,13 +50,26 @@ public class ModulesActivity extends Activity {
...
@@ -40,13 +50,26 @@ public class ModulesActivity extends Activity {
protected
void
onPreExecute
()
{
protected
void
onPreExecute
()
{
super
.
onPreExecute
();
super
.
onPreExecute
();
progress
=
ProgressDialog
.
show
(
ModulesActivity
.
this
,
null
,
getString
(
R
.
string
.
loading
),
true
,
false
);
progress
=
ProgressDialog
.
show
(
getContext
()
,
null
,
getString
(
R
.
string
.
loading
),
true
,
false
);
}
}
@Override
@Override
protected
Boolean
doInBackground
(
Void
...
voids
)
{
protected
Boolean
doInBackground
(
Void
...
voids
)
{
File
[]
magisk
=
new
File
(
MAGISK_PATH
).
listFiles
(
File:
:
isDirectory
);
File
[]
magisk
=
new
File
(
MAGISK_PATH
).
listFiles
(
new
FileFilter
()
{
File
[]
magiskCache
=
new
File
(
MAGISK_CACHE_PATH
).
listFiles
(
File:
:
isDirectory
);
@Override
public
boolean
accept
(
File
file
)
{
return
file
.
isDirectory
();
}
});
Utils
.
executeCommand
(
"chmod 777 /cache"
);
File
[]
magiskCache
=
new
File
(
MAGISK_CACHE_PATH
).
listFiles
(
new
FileFilter
()
{
@Override
public
boolean
accept
(
File
file
)
{
return
file
.
isDirectory
();
}
});
if
(
magisk
!=
null
)
{
if
(
magisk
!=
null
)
{
for
(
File
mod
:
magisk
)
{
for
(
File
mod
:
magisk
)
{
...
@@ -83,7 +106,7 @@ public class ModulesActivity extends Activity {
...
@@ -83,7 +106,7 @@ public class ModulesActivity extends Activity {
progress
.
dismiss
();
progress
.
dismiss
();
mListView
.
setAdapter
(
new
ModulesAdapter
(
ModulesActivity
.
this
,
R
.
layout
.
row
,
listModules
));
recyclerView
.
setAdapter
(
new
ModulesAdapter
(
listModules
));
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/RootFragment.java
0 → 100644
View file @
f5e53cd6
package
com
.
topjohnwu
.
magisk
.
ui
;
public
class
RootFragment
extends
android
.
support
.
v4
.
app
.
Fragment
{
}
app/src/main/res/anim/fade_in.xml
0 → 100644
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:interpolator=
"@android:anim/linear_interpolator"
>
<alpha
android:duration=
"250"
android:fromAlpha=
"0.1"
android:toAlpha=
"1.0"
/>
</set>
\ No newline at end of file
app/src/main/res/anim/fade_out.xml
0 → 100644
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:interpolator=
"@android:anim/linear_interpolator"
>
<alpha
android:duration=
"250"
android:fromAlpha=
"1.0"
android:toAlpha=
"0.1"
/>
</set>
\ No newline at end of file
app/src/main/res/drawable-anydpi/ic_bug_report.xml
0 → 100644
View file @
f5e53cd6
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24.0"
android:viewportWidth=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"
/>
</vector>
app/src/main/res/drawable-anydpi/ic_extension.xml
0 → 100644
View file @
f5e53cd6
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24.0"
android:viewportWidth=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M20.5,11H19V7c0,-1.1 -0.9,-2 -2,-2h-4V3.5C13,2.12 11.88,1 10.5,1S8,2.12 8,3.5V5H4c-1.1,0 -1.99,0.9 -1.99,2v3.8H3.5c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7H2V20c0,1.1 0.9,2 2,2h3.8v-1.5c0,-1.49 1.21,-2.7 2.7,-2.7 1.49,0 2.7,1.21 2.7,2.7V22H17c1.1,0 2,-0.9 2,-2v-4h1.5c1.38,0 2.5,-1.12 2.5,-2.5S21.88,11 20.5,11z"
/>
</vector>
app/src/main/res/drawable/root.xml
0 → 100644
View file @
f5e53cd6
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24"
android:viewportWidth=
"24"
>
<path
android:fillColor=
"#000"
android:pathData=
"M3,5A2,2 0 0,1 5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5C3.89,21 3,20.1 3,19V5M7,18H9L9.35,16H13.35L13,18H15L15.35,16H17.35L17.71,14H15.71L16.41,10H18.41L18.76,8H16.76L17.12,6H15.12L14.76,8H10.76L11.12,6H9.12L8.76,8H6.76L6.41,10H8.41L7.71,14H5.71L5.35,16H7.35L7,18M10.41,10H14.41L13.71,14H9.71L10.41,10Z"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout/activity_welcome.xml
0 → 100644
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id=
"@+id/drawer_layout"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:fitsSystemWindows=
"true"
tools:openDrawer=
"start"
>
<FrameLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"?android:windowBackground"
android:orientation=
"vertical"
>
<FrameLayout
android:id=
"@+id/content_frame"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
<android.support.v7.widget.Toolbar
android:id=
"@+id/toolbar"
android:layout_width=
"match_parent"
android:layout_height=
"?attr/actionBarSize"
android:background=
"?attr/colorPrimary"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:theme=
"@style/AppTheme.Toolbar"
/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id=
"@+id/nav_view"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
android:fitsSystemWindows=
"true"
app:menu=
"@menu/drawer"
/>
</android.support.v4.widget.DrawerLayout>
app/src/main/res/layout/modules_fragment.xml
0 → 100644
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_marginTop=
"?attr/actionBarSize"
android:orientation=
"vertical"
>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recyclerView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
app:layoutManager=
"android.support.v7.widget.LinearLayoutManager"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/row.xml
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<android.support.v7.widget.CardView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:card_view=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:layout_marginBottom=
"3dip"
android:layout_marginLeft=
"8dip"
android:layout_marginRight=
"8dip"
android:layout_marginTop=
"3dip"
android:background=
"?android:attr/selectableItemBackground"
android:minHeight=
"?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius=
"2dp"
card_view:cardElevation=
"2dp"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_height=
"wrap_content"
android:minHeight=
"?android:attr/listPreferredItemHeight"
android:orientation=
"horizontal"
android:padding=
"8dp"
>
<LinearLayout
android:layout_width=
"0dip"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:layout_marginLeft=
"4dip"
android:layout_marginRight=
"4dip"
android:layout_weight=
"1"
android:orientation=
"vertical"
>
android:orientation=
"vertical"
>
<TextView
<LinearLayout
android:id=
"@+id/name"
android:layout_width=
"match_parent"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
/>
<TextView
<TextView
android:id=
"@+id/version"
android:id=
"@+id/title"
android:layout_width=
"wrap_content"
android:layout_width=
"0dip"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:singleLine=
"false"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:textIsSelectable=
"false"
/>
<TextView
<TextView
android:id=
"@+id/versionCod
e"
android:id=
"@+id/version_nam
e"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"4dip"
android:layout_marginRight=
"4dip"
android:gravity=
"end"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textColor=
"@android:color/tertiary_text_dark"
android:textIsSelectable=
"false"
/>
</LinearLayout>
<TextView
<TextView
android:id=
"@+id/description"
android:id=
"@+id/description"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
<TextView
</LinearLayout>
android:id=
"@+id/cache"
<!-- FIXME-->
<ImageView
android:id=
"@+id/overflow"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"match_parent"
android:focusable=
"false"
android:gravity=
"center"
android:padding=
"3dp"
android:src=
"@drawable/root"
/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
\ No newline at end of file
app/src/main/res/menu/drawer.xml
0 → 100644
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<group
android:checkableBehavior=
"single"
>
<item
android:id=
"@+id/root"
android:icon=
"@drawable/root"
android:title=
"@string/root"
/>
<item
android:id=
"@+id/modules"
android:icon=
"@drawable/ic_extension"
android:title=
"@string/modules"
/>
<item
android:id=
"@+id/log"
android:icon=
"@drawable/ic_bug_report"
android:title=
"@string/log"
/>
</group>
<!--
<group android:checkableBehavior="none">
</group>
-->
</menu>
\ No newline at end of file
app/src/main/res/values/colors.xml
View file @
f5e53cd6
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources>
<color
name=
"colorPrimary"
>
#3f51b5
</color>
<color
name=
"colorPrimaryDark"
>
#303F9F
</color>
<color
name=
"primary"
>
#009688
</color>
<color
name=
"colorAccent"
>
#FF4081
</color>
<color
name=
"primary_dark"
>
#00796B
</color>
<color
name=
"primary_light"
>
#B2DFDB
</color>
<color
name=
"accent"
>
#FFC107
</color>
<color
name=
"primary_text"
>
#212121
</color>
<color
name=
"secondary_text"
>
#757575
</color>
<color
name=
"icons"
>
#FFFFFF
</color>
<color
name=
"divider"
>
#BDBDBD
</color>
</resources>
</resources>
app/src/main/res/values/strings.xml
View file @
f5e53cd6
...
@@ -19,4 +19,13 @@
...
@@ -19,4 +19,13 @@
<string
name=
"magisk_version"
>
Magisk v%1$s
</string>
<string
name=
"magisk_version"
>
Magisk v%1$s
</string>
<string
name=
"selinux_samsung"
>
Samsung do not support switching SELinux status!
</string>
<string
name=
"selinux_samsung"
>
Samsung do not support switching SELinux status!
</string>
<string
name=
"loading"
>
Loading...
</string>
<string
name=
"loading"
>
Loading...
</string>
<string
name=
"title_activity_welcome"
>
WelcomeActivity
</string>
<string
name=
"navigation_drawer_open"
>
Open navigation drawer
</string>
<string
name=
"navigation_drawer_close"
>
Close navigation drawer
</string>
<string
name=
"action_settings"
>
Settings
</string>
<string
name=
"root"
>
Root
</string>
<string
name=
"modules"
>
Modules
</string>
<string
name=
"log"
>
Log
</string>
</resources>
</resources>
app/src/main/res/values/styles.xml
View file @
f5e53cd6
<resources>
<resources>
<!-- Base application theme. -->
<!-- Base application theme. -->
<style
name=
"AppTheme"
parent=
"android:Theme.Material"
/>
<style
name=
"AppTheme"
parent=
"Theme.AppCompat.Light.NoActionBar"
>
<item
name=
"colorPrimary"
>
@color/primary
</item>
<item
name=
"colorPrimaryDark"
>
@color/primary_dark
</item>
<item
name=
"colorAccent"
>
@color/accent
</item>
<item
name=
"windowActionModeOverlay"
>
true
</item>
<item
name=
"android:windowDrawsSystemBarBackgrounds"
>
true
</item>
<item
name=
"windowActionBar"
>
false
</item>
<item
name=
"windowNoTitle"
>
true
</item>
<item
name=
"android:statusBarColor"
>
@android:color/transparent
</item>
</style>
<style
name=
"AppTheme.Toolbar"
parent=
"ThemeOverlay.AppCompat.Light"
>
<item
name=
"colorPrimary"
>
@color/primary
</item>
<item
name=
"android:elevation"
>
4dp
</item>
<item
name=
"android:textColorPrimary"
>
@color/primary_text
</item>
<item
name=
"android:textColorSecondary"
>
@color/secondary_text
</item>
<item
name=
"actionMenuTextColor"
>
@color/icons
</item>
</style>
</resources>
</resources>
build.gradle
View file @
f5e53cd6
...
@@ -3,9 +3,11 @@
...
@@ -3,9 +3,11 @@
buildscript
{
buildscript
{
repositories
{
repositories
{
jcenter
()
jcenter
()
mavenCentral
()
}
}
dependencies
{
dependencies
{
classpath
'com.android.tools.build:gradle:2.1.3'
classpath
'com.android.tools.build:gradle:2.1.3'
classpath
'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
// in the individual module build.gradle files
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/Remounter.java
View file @
f5e53cd6
...
@@ -17,8 +17,9 @@
...
@@ -17,8 +17,9 @@
package
org
.
sufficientlysecure
.
rootcommands
;
package
org
.
sufficientlysecure
.
rootcommands
;
import
android.util.Log
;
import
org.sufficientlysecure.rootcommands.command.SimpleCommand
;
import
org.sufficientlysecure.rootcommands.command.SimpleCommand
;
import
org.sufficientlysecure.rootcommands.util.Log
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileReader
;
import
java.io.FileReader
;
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/RootCommands.java
View file @
f5e53cd6
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
package
org
.
sufficientlysecure
.
rootcommands
;
package
org
.
sufficientlysecure
.
rootcommands
;
import
org.sufficientlysecure.rootcommands
.util.Log
;
import
android
.util.Log
;
public
class
RootCommands
{
public
class
RootCommands
{
public
static
final
String
TAG
=
"RootCommands"
;
public
static
final
String
TAG
=
"RootCommands"
;
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/Shell.java
View file @
f5e53cd6
...
@@ -17,8 +17,9 @@
...
@@ -17,8 +17,9 @@
package
org
.
sufficientlysecure
.
rootcommands
;
package
org
.
sufficientlysecure
.
rootcommands
;
import
android.util.Log
;
import
org.sufficientlysecure.rootcommands.command.Command
;
import
org.sufficientlysecure.rootcommands.command.Command
;
import
org.sufficientlysecure.rootcommands.util.Log
;
import
org.sufficientlysecure.rootcommands.util.RootAccessDeniedException
;
import
org.sufficientlysecure.rootcommands.util.RootAccessDeniedException
;
import
org.sufficientlysecure.rootcommands.util.Utils
;
import
org.sufficientlysecure.rootcommands.util.Utils
;
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/Toolbox.java
View file @
f5e53cd6
...
@@ -19,12 +19,12 @@ package org.sufficientlysecure.rootcommands;
...
@@ -19,12 +19,12 @@ package org.sufficientlysecure.rootcommands;
import
android.os.StatFs
;
import
android.os.StatFs
;
import
android.os.SystemClock
;
import
android.os.SystemClock
;
import
android.util.Log
;
import
org.sufficientlysecure.rootcommands.command.Command
;
import
org.sufficientlysecure.rootcommands.command.Command
;
import
org.sufficientlysecure.rootcommands.command.ExecutableCommand
;
import
org.sufficientlysecure.rootcommands.command.ExecutableCommand
;
import
org.sufficientlysecure.rootcommands.command.SimpleCommand
;
import
org.sufficientlysecure.rootcommands.command.SimpleCommand
;
import
org.sufficientlysecure.rootcommands.util.BrokenBusyboxException
;
import
org.sufficientlysecure.rootcommands.util.BrokenBusyboxException
;
import
org.sufficientlysecure.rootcommands.util.Log
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileNotFoundException
;
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/Command.java
View file @
f5e53cd6
...
@@ -17,10 +17,11 @@
...
@@ -17,10 +17,11 @@
package
org
.
sufficientlysecure
.
rootcommands
.
command
;
package
org
.
sufficientlysecure
.
rootcommands
.
command
;
import
android.util.Log
;
import
org.sufficientlysecure.rootcommands.RootCommands
;
import
org.sufficientlysecure.rootcommands.RootCommands
;
import
org.sufficientlysecure.rootcommands.Shell
;
import
org.sufficientlysecure.rootcommands.Shell
;
import
org.sufficientlysecure.rootcommands.util.BrokenBusyboxException
;
import
org.sufficientlysecure.rootcommands.util.BrokenBusyboxException
;
import
org.sufficientlysecure.rootcommands.util.Log
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
...
...
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Log.java
deleted
100644 → 0
View file @
4a48f59d
/*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
sufficientlysecure
.
rootcommands
.
util
;
import
org.sufficientlysecure.rootcommands.RootCommands
;
/**
* Wraps Android Logging to enable or disable debug output using Constants
*/
public
final
class
Log
{
public
static
void
v
(
String
tag
,
String
msg
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
v
(
tag
,
msg
);
}
}
public
static
void
v
(
String
tag
,
String
msg
,
Throwable
tr
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
v
(
tag
,
msg
,
tr
);
}
}
public
static
void
d
(
String
tag
,
String
msg
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
d
(
tag
,
msg
);
}
}
public
static
void
d
(
String
tag
,
String
msg
,
Throwable
tr
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
d
(
tag
,
msg
,
tr
);
}
}
public
static
void
i
(
String
tag
,
String
msg
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
i
(
tag
,
msg
);
}
}
public
static
void
i
(
String
tag
,
String
msg
,
Throwable
tr
)
{
if
(
RootCommands
.
DEBUG
)
{
android
.
util
.
Log
.
i
(
tag
,
msg
,
tr
);
}
}
public
static
void
w
(
String
tag
,
String
msg
)
{
android
.
util
.
Log
.
w
(
tag
,
msg
);
}
public
static
void
w
(
String
tag
,
String
msg
,
Throwable
tr
)
{
android
.
util
.
Log
.
w
(
tag
,
msg
,
tr
);
}
public
static
void
w
(
String
tag
,
Throwable
tr
)
{
android
.
util
.
Log
.
w
(
tag
,
tr
);
}
public
static
void
e
(
String
tag
,
String
msg
)
{
android
.
util
.
Log
.
e
(
tag
,
msg
);
}
public
static
void
e
(
String
tag
,
String
msg
,
Throwable
tr
)
{
android
.
util
.
Log
.
e
(
tag
,
msg
,
tr
);
}
}
lib/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Utils.java
View file @
f5e53cd6
...
@@ -18,6 +18,8 @@
...
@@ -18,6 +18,8 @@
package
org
.
sufficientlysecure
.
rootcommands
.
util
;
package
org
.
sufficientlysecure
.
rootcommands
.
util
;
import
android.util.Log
;
import
org.sufficientlysecure.rootcommands.RootCommands
;
import
org.sufficientlysecure.rootcommands.RootCommands
;
import
java.io.File
;
import
java.io.File
;
...
...
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