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
c2a188f7
Commit
c2a188f7
authored
Sep 09, 2016
by
d8ahazard
Committed by
GitHub
Sep 09, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4 from d8ahazard/digitalhigh_autodownload
Digitalhigh autodownload
parents
bef43617
1a1d37a2
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1361 additions
and
600 deletions
+1361
-600
BaseModuleFragment.java
...rc/main/java/com/topjohnwu/magisk/BaseModuleFragment.java
+201
-28
BaseRepoFragment.java
app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java
+237
-19
ModulesAdapter.java
app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java
+0
-101
ModulesFragment.java
app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
+16
-9
ReposAdapter.java
app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java
+0
-101
WelcomeActivity.java
app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
+11
-1
Module.java
app/src/main/java/com/topjohnwu/magisk/module/Module.java
+102
-31
Repo.java
app/src/main/java/com/topjohnwu/magisk/module/Repo.java
+206
-65
RepoAdapter.java
...rc/main/java/com/topjohnwu/magisk/module/RepoAdapter.java
+0
-147
RepoHelper.java
...src/main/java/com/topjohnwu/magisk/module/RepoHelper.java
+204
-0
AnimationHelper.java
...main/java/com/topjohnwu/magisk/utils/AnimationHelper.java
+58
-0
GitAgent.java
app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java
+8
-0
Utils.java
app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
+57
-44
WebRequest.java
app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java
+19
-1
ic_done_black.xml
app/src/main/res/drawable/ic_done_black.xml
+9
-0
ic_system_update_alt_black.xml
app/src/main/res/drawable/ic_system_update_alt_black.xml
+9
-0
list_item_module.xml
app/src/main/res/layout/list_item_module.xml
+22
-0
list_item_repo.xml
app/src/main/res/layout/list_item_repo.xml
+61
-1
list_item_repo_expanded.xml
app/src/main/res/layout/list_item_repo_expanded.xml
+67
-0
modules_fragment.xml
app/src/main/res/layout/modules_fragment.xml
+62
-49
single_module_fragment.xml
app/src/main/res/layout/single_module_fragment.xml
+4
-3
dimens.xml
app/src/main/res/values/dimens.xml
+1
-0
strings.xml
app/src/main/res/values/strings.xml
+7
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
;
package
com
.
topjohnwu
.
magisk
;
import
android.animation.Animator
;
import
android.animation.ValueAnimator
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.content.SharedPreferences
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.preference.PreferenceManager
;
import
android.preference.PreferenceManager
;
import
android.support.annotation.Nullable
;
import
android.support.annotation.Nullable
;
import
android.support.design.widget.Snackbar
;
import
android.support.design.widget.Snackbar
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.widget.SwipeRefreshLayout
;
import
android.support.v7.widget.RecyclerView
;
import
android.support.v7.widget.RecyclerView
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.util.Log
;
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.view.ViewTreeObserver
;
import
android.view.WindowManager
;
import
android.widget.CheckBox
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.concurrent.ExecutionException
;
import
butterknife.BindView
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
import
butterknife.ButterKnife
;
...
@@ -28,26 +36,24 @@ public abstract class BaseModuleFragment extends Fragment {
...
@@ -28,26 +36,24 @@ public abstract class BaseModuleFragment extends Fragment {
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
private
SwipeRefreshLayout
mSwipeRefreshLayout
;
private
View
view
;
private
SharedPreferences
prefs
;
private
SharedPreferences
prefs
;
@Nullable
@Nullable
@Override
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
view
=
inflater
.
inflate
(
R
.
layout
.
single_module_fragment
,
container
,
false
);
View
viewMain
=
inflater
.
inflate
(
R
.
layout
.
single_module_fragment
,
container
,
false
);
mSwipeRefreshLayout
=
(
SwipeRefreshLayout
)
view
.
findViewById
(
R
.
id
.
swipeRefreshLayout
);
mSwipeRefreshLayout
.
setOnRefreshListener
(()
->
{
refreshItems
();
});
ButterKnife
.
bind
(
this
,
view
);
ButterKnife
.
bind
(
this
,
view
Main
);
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
prefs
.
registerOnSharedPreferenceChangeListener
(
new
SharedPreferences
.
OnSharedPreferenceChangeListener
()
{
prefs
.
registerOnSharedPreferenceChangeListener
(
new
SharedPreferences
.
OnSharedPreferenceChangeListener
()
{
@Override
@Override
public
void
onSharedPreferenceChanged
(
SharedPreferences
sharedPreferences
,
String
s
)
{
public
void
onSharedPreferenceChanged
(
SharedPreferences
sharedPreferences
,
String
s
)
{
if
(
s
.
contains
(
"updated"
))
{
if
(
s
.
contains
(
"updated"
))
{
view
.
invalidate
();
view
Main
.
invalidate
();
view
.
requestLayout
();
view
Main
.
requestLayout
();
}
}
}
}
...
@@ -56,7 +62,7 @@ public abstract class BaseModuleFragment extends Fragment {
...
@@ -56,7 +62,7 @@ public abstract class BaseModuleFragment extends Fragment {
emptyTv
.
setVisibility
(
View
.
VISIBLE
);
emptyTv
.
setVisibility
(
View
.
VISIBLE
);
recyclerView
.
setVisibility
(
View
.
GONE
);
recyclerView
.
setVisibility
(
View
.
GONE
);
return
view
;
return
view
Main
;
}
}
recyclerView
.
setAdapter
(
new
ModulesAdapter
(
listModules
(),
(
chk
,
position
)
->
{
recyclerView
.
setAdapter
(
new
ModulesAdapter
(
listModules
(),
(
chk
,
position
)
->
{
...
@@ -81,25 +87,192 @@ public abstract class BaseModuleFragment extends Fragment {
...
@@ -81,25 +87,192 @@ public abstract class BaseModuleFragment extends Fragment {
listModules
().
get
(
position
).
deleteRemoveFile
();
listModules
().
get
(
position
).
deleteRemoveFile
();
Snackbar
.
make
(
undeleteBtn
,
R
.
string
.
remove_file_deleted
,
Snackbar
.
LENGTH_SHORT
).
show
();
Snackbar
.
make
(
undeleteBtn
,
R
.
string
.
remove_file_deleted
,
Snackbar
.
LENGTH_SHORT
).
show
();
}));
}));
return
view
;
return
view
Main
;
}
}
void
refreshItems
()
{
Log
.
d
(
"Magisk"
,
"Calling refreshitems for online"
);
protected
abstract
List
<
Module
>
listModules
();
Utils
.
LoadModules
utils
=
new
Utils
.
LoadModules
(
getActivity
(),
true
);
utils
.
execute
();
public
class
ModulesAdapter
extends
RecyclerView
.
Adapter
<
ModulesAdapter
.
ViewHolder
>
{
onItemsLoadComplete
();
view
.
requestLayout
();
private
final
List
<
Module
>
mList
;
List
<
Boolean
>
mExpandedList
;
@BindView
(
R
.
id
.
expand_layout
)
LinearLayout
expandedLayout
;
private
View
viewMain
;
private
Context
context
;
private
final
Utils
.
ItemClickListener
chboxListener
;
private
final
Utils
.
ItemClickListener
deleteBtnListener
;
private
final
Utils
.
ItemClickListener
unDeleteBtnListener
;
public
ModulesAdapter
(
List
<
Module
>
list
,
Utils
.
ItemClickListener
chboxListener
,
Utils
.
ItemClickListener
deleteBtnListener
,
Utils
.
ItemClickListener
undeleteBtnListener
)
{
this
.
mList
=
list
;
mExpandedList
=
new
ArrayList
<>(
mList
.
size
());
for
(
int
i
=
0
;
i
<
mList
.
size
();
i
++)
{
mExpandedList
.
add
(
false
);
}
this
.
chboxListener
=
chboxListener
;
this
.
deleteBtnListener
=
deleteBtnListener
;
this
.
unDeleteBtnListener
=
undeleteBtnListener
;
}
}
@Override
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
viewMain
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_module
,
parent
,
false
);
context
=
parent
.
getContext
();
ButterKnife
.
bind
(
this
,
viewMain
);
return
new
ViewHolder
(
viewMain
);
}
@Override
public
void
onBindViewHolder
(
final
ViewHolder
holder
,
int
position
)
{
final
Module
module
=
mList
.
get
(
position
);
Log
.
d
(
"Magisk"
,
"ModulesAdapter: Trying set up bindview from list pos "
+
position
+
" and "
+
module
.
getName
()
);
void
onItemsLoadComplete
()
{
holder
.
title
.
setText
(
module
.
getName
());
// Update the adapter and notify data set changed
holder
.
versionName
.
setText
(
module
.
getVersion
());
// ...
holder
.
description
.
setText
(
module
.
getDescription
());
// Stop refresh animation
holder
.
checkBox
.
setChecked
(
module
.
isEnabled
());
mSwipeRefreshLayout
.
setRefreshing
(
false
);
holder
.
checkBox
.
setOnCheckedChangeListener
((
compoundButton
,
b
)
->
chboxListener
.
onItemClick
(
compoundButton
,
holder
.
getAdapterPosition
()));
holder
.
delete
.
setOnClickListener
(
view
->
{
if
(
module
.
willBeRemoved
())
{
unDeleteBtnListener
.
onItemClick
(
holder
.
delete
,
holder
.
getAdapterPosition
());
}
else
{
deleteBtnListener
.
onItemClick
(
holder
.
delete
,
holder
.
getAdapterPosition
());
}
}
protected
abstract
List
<
Module
>
listModules
();
updateDeleteButton
(
holder
,
module
);
});
updateDeleteButton
(
holder
,
module
);
}
private
void
updateDeleteButton
(
ViewHolder
holder
,
Module
module
)
{
holder
.
warning
.
setVisibility
(
module
.
willBeRemoved
()
?
View
.
VISIBLE
:
View
.
GONE
);
if
(
module
.
willBeRemoved
())
{
holder
.
delete
.
setImageResource
(
R
.
drawable
.
ic_undelete
);
}
else
{
holder
.
delete
.
setImageResource
(
R
.
drawable
.
ic_delete
);
}
}
@Override
public
int
getItemCount
()
{
return
mList
.
size
();
}
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
title
)
TextView
title
;
@BindView
(
R
.
id
.
version_name
)
TextView
versionName
;
@BindView
(
R
.
id
.
description
)
TextView
description
;
@BindView
(
R
.
id
.
warning
)
TextView
warning
;
@BindView
(
R
.
id
.
checkbox
)
CheckBox
checkBox
;
@BindView
(
R
.
id
.
delete
)
ImageView
delete
;
@BindView
(
R
.
id
.
expand_layout
)
LinearLayout
expandLayout
;
private
ValueAnimator
mAnimator
;
private
int
mMeasuredHeight
;
public
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
WindowManager
windowmanager
=
(
WindowManager
)
context
.
getSystemService
(
Context
.
WINDOW_SERVICE
);
ButterKnife
.
bind
(
this
,
itemView
);
DisplayMetrics
dimension
=
new
DisplayMetrics
();
windowmanager
.
getDefaultDisplay
().
getMetrics
(
dimension
);
final
int
mHeight
=
dimension
.
heightPixels
;
expandLayout
.
getViewTreeObserver
().
addOnPreDrawListener
(
new
ViewTreeObserver
.
OnPreDrawListener
()
{
@Override
public
boolean
onPreDraw
()
{
expandLayout
.
getViewTreeObserver
().
removeOnPreDrawListener
(
this
);
expandLayout
.
setVisibility
(
View
.
GONE
);
final
int
widthSpec
=
View
.
MeasureSpec
.
makeMeasureSpec
(
0
,
View
.
MeasureSpec
.
UNSPECIFIED
);
final
int
heightSpec
=
View
.
MeasureSpec
.
makeMeasureSpec
(
0
,
View
.
MeasureSpec
.
UNSPECIFIED
);
expandLayout
.
measure
(
widthSpec
,
heightSpec
);
mAnimator
=
slideAnimator
(
0
,
expandLayout
.
getMeasuredHeight
());
return
true
;
}
});
viewMain
.
setOnClickListener
(
view
->
{
int
position
=
getAdapterPosition
();
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: CLICK. "
+
position
+
" and "
+
mExpandedList
.
get
(
position
));
if
(
mExpandedList
.
get
(
position
))
{
collapse
(
expandLayout
);
}
else
{
expand
(
expandLayout
);
}
mExpandedList
.
set
(
position
,
!
mExpandedList
.
get
(
position
));
});
if
(!
Shell
.
rootAccess
())
{
checkBox
.
setEnabled
(
false
);
delete
.
setEnabled
(
false
);
}
}
private
void
expand
(
View
view
)
{
// set Visible
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: Expand anim called "
+
mMeasuredHeight
+
" and "
+
view
.
getId
());
view
.
setVisibility
(
View
.
VISIBLE
);
mAnimator
.
start
();
}
private
void
collapse
(
View
view
)
{
int
finalHeight
=
view
.
getHeight
();
ValueAnimator
mAnimator
=
slideAnimator
(
finalHeight
,
0
);
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: Collapse anim called "
+
finalHeight
+
" and "
+
view
.
getId
());
mAnimator
.
addListener
(
new
Animator
.
AnimatorListener
()
{
@Override
public
void
onAnimationEnd
(
Animator
animator
)
{
// Height=0, but it set visibility to GONE
view
.
setVisibility
(
View
.
GONE
);
}
@Override
public
void
onAnimationStart
(
Animator
animator
)
{
}
@Override
public
void
onAnimationCancel
(
Animator
animator
)
{
}
@Override
public
void
onAnimationRepeat
(
Animator
animator
)
{
}
});
mAnimator
.
start
();
}
private
ValueAnimator
slideAnimator
(
int
start
,
int
end
)
{
ValueAnimator
animator
=
ValueAnimator
.
ofInt
(
start
,
end
);
animator
.
addUpdateListener
(
valueAnimator
->
{
// Update Height
int
value
=
(
Integer
)
valueAnimator
.
getAnimatedValue
();
ViewGroup
.
LayoutParams
layoutParams
=
expandLayout
.
getLayoutParams
();
layoutParams
.
height
=
value
;
expandLayout
.
setLayoutParams
(
layoutParams
);
});
return
animator
;
}
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
;
package
com
.
topjohnwu
.
magisk
;
import
android.animation.Animator
;
import
android.animation.ValueAnimator
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.graphics.Color
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.preference.PreferenceManager
;
import
android.support.annotation.Nullable
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.widget.SwipeRefreshLayout
;
import
android.support.v7.widget.RecyclerView
;
import
android.support.v7.widget.RecyclerView
;
import
android.text.util.Linkify
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.util.Log
;
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.view.ViewTreeObserver
;
import
android.view.WindowManager
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Repo
;
import
com.topjohnwu.magisk.module.Repo
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
butterknife.BindView
;
import
butterknife.BindView
;
...
@@ -26,15 +39,11 @@ public abstract class BaseRepoFragment extends Fragment {
...
@@ -26,15 +39,11 @@ public abstract class BaseRepoFragment extends Fragment {
RecyclerView
recyclerView
;
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
empty_rv
)
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
TextView
emptyTv
;
private
SwipeRefreshLayout
mSwipeRefreshLayout
;
@Nullable
@Nullable
@Override
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
View
view
=
inflater
.
inflate
(
R
.
layout
.
single_module_fragment
,
container
,
false
);
View
view
=
inflater
.
inflate
(
R
.
layout
.
single_module_fragment
,
container
,
false
);
mSwipeRefreshLayout
=
(
SwipeRefreshLayout
)
view
.
findViewById
(
R
.
id
.
swipeRefreshLayout
);
mSwipeRefreshLayout
.
setOnRefreshListener
(()
->
{
refreshItems
();
});
ButterKnife
.
bind
(
this
,
view
);
ButterKnife
.
bind
(
this
,
view
);
...
@@ -44,25 +53,234 @@ public abstract class BaseRepoFragment extends Fragment {
...
@@ -44,25 +53,234 @@ public abstract class BaseRepoFragment extends Fragment {
return
view
;
return
view
;
}
}
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: ListRepos size is "
+
listRepos
().
size
());
recyclerView
.
setAdapter
(
new
ReposAdapter
(
listRepos
())
{
recyclerView
.
setAdapter
(
new
ReposAdapter
(
listRepos
())
{
});
});
return
view
;
return
view
;
}
}
void
refreshItems
()
{
Log
.
d
(
"Magisk"
,
"Calling refreshitems for online"
);
protected
abstract
List
<
Repo
>
listRepos
();
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
onItemsLoadComplete
();
public
class
ReposAdapter
extends
RecyclerView
.
Adapter
<
ReposAdapter
.
ViewHolder
>
{
private
final
List
<
Repo
>
mList
;
List
<
Boolean
>
mExpandedList
;
@BindView
(
R
.
id
.
update
)
ImageView
updateImage
;
@BindView
(
R
.
id
.
installed
)
ImageView
installedImage
;
@BindView
(
R
.
id
.
expand_layout
)
LinearLayout
expandedLayout
;
private
View
viewMain
;
private
Context
context
;
private
boolean
mIsInstalled
,
mCanUpdate
;
public
ReposAdapter
(
List
<
Repo
>
list
)
{
this
.
mList
=
list
;
mExpandedList
=
new
ArrayList
<>(
mList
.
size
());
for
(
int
i
=
0
;
i
<
mList
.
size
();
i
++)
{
mExpandedList
.
add
(
false
);
}
}
void
onItemsLoadComplete
()
{
}
// Update the adapter and notify data set changed
// ...
// Stop refresh animation
@Override
mSwipeRefreshLayout
.
setRefreshing
(
false
);
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
viewMain
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_repo
,
parent
,
false
);
ButterKnife
.
bind
(
this
,
viewMain
);
context
=
parent
.
getContext
();
return
new
ViewHolder
(
viewMain
);
}
@Override
public
void
onBindViewHolder
(
final
ViewHolder
holder
,
int
position
)
{
final
Repo
repo
=
mList
.
get
(
position
);
Log
.
d
(
"Magisk"
,
"ReposAdapter: Trying set up bindview from list pos "
+
position
+
" out of a total of "
+
mList
.
size
()
+
" and "
+
repo
.
getId
());
if
(
repo
.
getId
()
!=
null
)
{
TextView
authorView
=
holder
.
author
;
holder
.
title
.
setText
(
repo
.
getName
());
holder
.
versionName
.
setText
(
repo
.
getmVersion
());
holder
.
description
.
setText
(
repo
.
getDescription
());
String
authorString
=
getResources
().
getString
(
R
.
string
.
author
)
+
" "
+
repo
.
getmAuthor
();
holder
.
author
.
setText
(
authorString
);
if
((
repo
.
getmLogUrl
()
!=
null
)
&&
(
repo
.
getmLogUrl
().
equals
(
""
)))
{
holder
.
log
.
setText
(
repo
.
getmLogUrl
());
Linkify
.
addLinks
(
holder
.
log
,
Linkify
.
WEB_URLS
);
}
else
{
holder
.
log
.
setVisibility
(
View
.
GONE
);
}
holder
.
installedStatus
.
setText
(
repo
.
isInstalled
()
?
getResources
().
getString
(
R
.
string
.
module_installed
)
:
getResources
().
getString
(
R
.
string
.
module_not_installed
));
if
(
mExpandedList
.
get
(
position
))
{
holder
.
expandLayout
.
setVisibility
(
View
.
VISIBLE
);
}
else
{
holder
.
expandLayout
.
setVisibility
(
View
.
GONE
);
}
if
(
repo
.
isInstalled
())
{
holder
.
installedStatus
.
setTextColor
(
Color
.
parseColor
(
"#14AD00"
));
holder
.
updateStatus
.
setText
(
repo
.
canUpdate
()
?
getResources
().
getString
(
R
.
string
.
module_update_available
)
:
getResources
().
getString
(
R
.
string
.
module_up_to_date
));
}
Log
.
d
(
"Magisk"
,
"ReposAdapter: Setting up info "
+
repo
.
getId
()
+
" and "
+
repo
.
getDescription
()
+
" and "
+
repo
.
getmVersion
());
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
updateImage
.
setImageResource
(
R
.
drawable
.
ic_system_update_alt_black
);
mCanUpdate
=
prefs
.
getBoolean
(
"repo-isInstalled_"
+
repo
.
getId
(),
false
);
updateImage
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
if
(!
mIsInstalled
|
mCanUpdate
)
{
Utils
.
DownloadReceiver
reciever
=
new
Utils
.
DownloadReceiver
()
{
@Override
public
void
task
(
File
file
)
{
Log
.
d
(
"Magisk"
,
"Task firing"
);
new
Utils
.
FlashZIP
(
context
,
repo
.
getId
(),
file
.
toString
()).
execute
();
}
};
String
filename
=
repo
.
getId
().
replace
(
" "
,
""
)
+
".zip"
;
Utils
.
downloadAndReceive
(
context
,
reciever
,
repo
.
getmZipUrl
(),
filename
);
}
else
{
Toast
.
makeText
(
context
,
repo
.
getId
()
+
" is already installed."
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
});
if
(
prefs
.
contains
(
"repo-isInstalled_"
+
repo
.
getId
()))
{
mIsInstalled
=
prefs
.
getBoolean
(
"repo-isInstalled_"
+
repo
.
getId
(),
false
);
// if (mIsInstalled) {
// installedImage.setImageResource(R.drawable.ic_done_black);
// }
}
}
}
@Override
public
int
getItemCount
()
{
return
mList
.
size
();
}
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
title
)
TextView
title
;
@BindView
(
R
.
id
.
version_name
)
TextView
versionName
;
@BindView
(
R
.
id
.
description
)
TextView
description
;
@BindView
(
R
.
id
.
author
)
TextView
author
;
@BindView
(
R
.
id
.
log
)
TextView
log
;
@BindView
(
R
.
id
.
installedStatus
)
TextView
installedStatus
;
@BindView
(
R
.
id
.
updateStatus
)
TextView
updateStatus
;
@BindView
(
R
.
id
.
expand_layout
)
LinearLayout
expandLayout
;
private
ValueAnimator
mAnimator
;
private
int
mMeasuredHeight
;
public
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
WindowManager
windowmanager
=
(
WindowManager
)
context
.
getSystemService
(
Context
.
WINDOW_SERVICE
);
ButterKnife
.
bind
(
this
,
itemView
);
DisplayMetrics
dimension
=
new
DisplayMetrics
();
windowmanager
.
getDefaultDisplay
().
getMetrics
(
dimension
);
final
int
mHeight
=
dimension
.
heightPixels
;
expandLayout
.
getViewTreeObserver
().
addOnPreDrawListener
(
new
ViewTreeObserver
.
OnPreDrawListener
()
{
@Override
public
boolean
onPreDraw
()
{
expandLayout
.
getViewTreeObserver
().
removeOnPreDrawListener
(
this
);
expandLayout
.
setVisibility
(
View
.
GONE
);
final
int
widthSpec
=
View
.
MeasureSpec
.
makeMeasureSpec
(
0
,
View
.
MeasureSpec
.
UNSPECIFIED
);
final
int
heightSpec
=
View
.
MeasureSpec
.
makeMeasureSpec
(
0
,
View
.
MeasureSpec
.
UNSPECIFIED
);
expandLayout
.
measure
(
widthSpec
,
heightSpec
);
mAnimator
=
slideAnimator
(
0
,
expandLayout
.
getMeasuredHeight
());
return
true
;
}
});
viewMain
.
setOnClickListener
(
view
->
{
int
position
=
getAdapterPosition
();
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: CLICK. "
+
position
+
" and "
+
mExpandedList
.
get
(
position
));
if
(
mExpandedList
.
get
(
position
))
{
collapse
(
expandLayout
);
}
else
{
expand
(
expandLayout
);
}
mExpandedList
.
set
(
position
,
!
mExpandedList
.
get
(
position
));
});
}
private
void
expand
(
View
view
)
{
// set Visible
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: Expand anim called "
+
mMeasuredHeight
+
" and "
+
view
.
getId
());
view
.
setVisibility
(
View
.
VISIBLE
);
mAnimator
.
start
();
}
private
void
collapse
(
View
view
)
{
int
finalHeight
=
view
.
getHeight
();
ValueAnimator
mAnimator
=
slideAnimator
(
finalHeight
,
0
);
Log
.
d
(
"Magisk"
,
"BaseRepoFragment: Collapse anim called "
+
finalHeight
+
" and "
+
view
.
getId
());
mAnimator
.
addListener
(
new
Animator
.
AnimatorListener
()
{
@Override
public
void
onAnimationEnd
(
Animator
animator
)
{
// Height=0, but it set visibility to GONE
view
.
setVisibility
(
View
.
GONE
);
}
@Override
public
void
onAnimationStart
(
Animator
animator
)
{
}
@Override
public
void
onAnimationCancel
(
Animator
animator
)
{
}
@Override
public
void
onAnimationRepeat
(
Animator
animator
)
{
}
});
mAnimator
.
start
();
}
private
ValueAnimator
slideAnimator
(
int
start
,
int
end
)
{
ValueAnimator
animator
=
ValueAnimator
.
ofInt
(
start
,
end
);
animator
.
addUpdateListener
(
valueAnimator
->
{
// Update Height
int
value
=
(
Integer
)
valueAnimator
.
getAnimatedValue
();
ViewGroup
.
LayoutParams
layoutParams
=
expandLayout
.
getLayoutParams
();
layoutParams
.
height
=
value
;
expandLayout
.
setLayoutParams
(
layoutParams
);
});
return
animator
;
}
}
}
}
protected
abstract
List
<
Repo
>
listRepos
();
}
}
app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java
deleted
100644 → 0
View file @
bef43617
package
com
.
topjohnwu
.
magisk
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.util.List
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
ModulesAdapter
extends
RecyclerView
.
Adapter
<
ModulesAdapter
.
ViewHolder
>
{
private
final
List
<
Module
>
mList
;
private
final
Utils
.
ItemClickListener
chboxListener
;
private
final
Utils
.
ItemClickListener
deleteBtnListener
;
private
final
Utils
.
ItemClickListener
unDeleteBtnListener
;
public
ModulesAdapter
(
List
<
Module
>
list
,
Utils
.
ItemClickListener
chboxListener
,
Utils
.
ItemClickListener
deleteBtnListener
,
Utils
.
ItemClickListener
undeleteBtnListener
)
{
this
.
mList
=
list
;
this
.
chboxListener
=
chboxListener
;
this
.
deleteBtnListener
=
deleteBtnListener
;
this
.
unDeleteBtnListener
=
undeleteBtnListener
;
}
@Override
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
View
view
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_module
,
parent
,
false
);
return
new
ViewHolder
(
view
);
}
@Override
public
void
onBindViewHolder
(
final
ViewHolder
holder
,
int
position
)
{
final
Module
module
=
mList
.
get
(
position
);
holder
.
title
.
setText
(
module
.
getName
());
holder
.
versionName
.
setText
(
module
.
getVersion
());
holder
.
description
.
setText
(
module
.
getDescription
());
holder
.
checkBox
.
setChecked
(
module
.
isEnabled
());
holder
.
checkBox
.
setOnCheckedChangeListener
((
compoundButton
,
b
)
->
chboxListener
.
onItemClick
(
compoundButton
,
holder
.
getAdapterPosition
()));
holder
.
delete
.
setOnClickListener
(
view
->
{
if
(
module
.
willBeRemoved
())
{
unDeleteBtnListener
.
onItemClick
(
holder
.
delete
,
holder
.
getAdapterPosition
());
}
else
{
deleteBtnListener
.
onItemClick
(
holder
.
delete
,
holder
.
getAdapterPosition
());
}
updateDeleteButton
(
holder
,
module
);
});
updateDeleteButton
(
holder
,
module
);
}
private
void
updateDeleteButton
(
ViewHolder
holder
,
Module
module
)
{
holder
.
warning
.
setVisibility
(
module
.
willBeRemoved
()
?
View
.
VISIBLE
:
View
.
GONE
);
if
(
module
.
willBeRemoved
())
{
holder
.
delete
.
setImageResource
(
R
.
drawable
.
ic_undelete
);
}
else
{
holder
.
delete
.
setImageResource
(
R
.
drawable
.
ic_delete
);
}
}
@Override
public
int
getItemCount
()
{
return
mList
.
size
();
}
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
title
)
TextView
title
;
@BindView
(
R
.
id
.
version_name
)
TextView
versionName
;
@BindView
(
R
.
id
.
description
)
TextView
description
;
@BindView
(
R
.
id
.
warning
)
TextView
warning
;
@BindView
(
R
.
id
.
checkbox
)
CheckBox
checkBox
;
@BindView
(
R
.
id
.
delete
)
ImageView
delete
;
public
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
ButterKnife
.
bind
(
this
,
itemView
);
if
(!
Shell
.
rootAccess
())
{
checkBox
.
setEnabled
(
false
);
delete
.
setEnabled
(
false
);
}
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
View file @
c2a188f7
...
@@ -14,6 +14,7 @@ import android.support.v4.app.Fragment;
...
@@ -14,6 +14,7 @@ import android.support.v4.app.Fragment;
import
android.support.v4.app.FragmentManager
;
import
android.support.v4.app.FragmentManager
;
import
android.support.v4.app.FragmentPagerAdapter
;
import
android.support.v4.app.FragmentPagerAdapter
;
import
android.support.v4.view.ViewPager
;
import
android.support.v4.view.ViewPager
;
import
android.support.v4.widget.SwipeRefreshLayout
;
import
android.util.Log
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.LayoutInflater
;
import
android.view.Menu
;
import
android.view.Menu
;
...
@@ -40,7 +41,7 @@ public class ModulesFragment extends Fragment {
...
@@ -40,7 +41,7 @@ public class ModulesFragment extends Fragment {
public
static
List
<
Module
>
listModulesCache
=
new
ArrayList
<>();
public
static
List
<
Module
>
listModulesCache
=
new
ArrayList
<>();
public
static
List
<
Repo
>
listModulesDownload
=
new
ArrayList
<>();
public
static
List
<
Repo
>
listModulesDownload
=
new
ArrayList
<>();
private
static
final
int
FILE_SELECT_CODE
=
0
;
private
static
final
int
FILE_SELECT_CODE
=
0
;
private
File
input
;
private
int
viewPagePosition
;
@BindView
(
R
.
id
.
progressBar
)
ProgressBar
progressBar
;
@BindView
(
R
.
id
.
progressBar
)
ProgressBar
progressBar
;
@BindView
(
R
.
id
.
fab
)
FloatingActionButton
fabio
;
@BindView
(
R
.
id
.
fab
)
FloatingActionButton
fabio
;
...
@@ -51,18 +52,16 @@ public class ModulesFragment extends Fragment {
...
@@ -51,18 +52,16 @@ public class ModulesFragment extends Fragment {
@Override
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
View
view
=
inflater
.
inflate
(
R
.
layout
.
modules_fragment
,
container
,
false
);
View
view
=
inflater
.
inflate
(
R
.
layout
.
modules_fragment
,
container
,
false
);
ButterKnife
.
bind
(
this
,
view
);
ButterKnife
.
bind
(
this
,
view
);
new
Utils
.
LoadModules
(
getActivity
(),
false
).
execute
();
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
if
(
prefs
.
contains
(
"hasCachedRepos"
))
{
new
Utils
.
LoadModules
(
getActivity
(),
false
).
execute
();
}
else
{
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
}
new
updateUI
().
execute
();
new
updateUI
().
execute
();
setHasOptionsMenu
(
true
);
setHasOptionsMenu
(
true
);
return
view
;
return
view
;
}
}
@Override
@Override
public
void
onCreateOptionsMenu
(
Menu
menu
,
MenuInflater
inflater
)
{
public
void
onCreateOptionsMenu
(
Menu
menu
,
MenuInflater
inflater
)
{
super
.
onCreateOptionsMenu
(
menu
,
inflater
);
super
.
onCreateOptionsMenu
(
menu
,
inflater
);
...
@@ -100,13 +99,15 @@ public class ModulesFragment extends Fragment {
...
@@ -100,13 +99,15 @@ public class ModulesFragment extends Fragment {
public
boolean
onOptionsItemSelected
(
MenuItem
item
)
{
public
boolean
onOptionsItemSelected
(
MenuItem
item
)
{
switch
(
item
.
getItemId
())
{
switch
(
item
.
getItemId
())
{
case
R
.
id
.
force_reload
:
case
R
.
id
.
force_reload
:
viewPagePosition
=
tabLayout
.
getSelectedTabPosition
();
listModules
.
clear
();
listModules
.
clear
();
listModulesCache
.
clear
();
listModulesCache
.
clear
();
listModulesDownload
.
clear
();
listModulesDownload
.
clear
();
progressBar
.
setVisibility
(
View
.
VISIBLE
);
progressBar
.
setVisibility
(
View
.
VISIBLE
);
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
()));
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
()));
tabLayout
.
setupWithViewPager
(
viewPager
);
tabLayout
.
setupWithViewPager
(
viewPager
);
new
Utils
.
LoadModules
(
getActivity
(),
false
).
execute
();
viewPager
.
setCurrentItem
(
viewPagePosition
);
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
new
updateUI
().
execute
();
new
updateUI
().
execute
();
break
;
break
;
}
}
...
@@ -114,6 +115,11 @@ public class ModulesFragment extends Fragment {
...
@@ -114,6 +115,11 @@ public class ModulesFragment extends Fragment {
return
super
.
onOptionsItemSelected
(
item
);
return
super
.
onOptionsItemSelected
(
item
);
}
}
void
selectPage
(
int
pageIndex
){
tabLayout
.
setScrollPosition
(
pageIndex
,
0
f
,
true
);
viewPager
.
setCurrentItem
(
pageIndex
);
}
public
static
class
NormalModuleFragment
extends
BaseModuleFragment
{
public
static
class
NormalModuleFragment
extends
BaseModuleFragment
{
@Override
@Override
...
@@ -153,9 +159,10 @@ public class ModulesFragment extends Fragment {
...
@@ -153,9 +159,10 @@ public class ModulesFragment extends Fragment {
super
.
onPostExecute
(
v
);
super
.
onPostExecute
(
v
);
progressBar
.
setVisibility
(
View
.
GONE
);
progressBar
.
setVisibility
(
View
.
GONE
);
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
()));
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
()));
tabLayout
.
setupWithViewPager
(
viewPager
);
tabLayout
.
setupWithViewPager
(
viewPager
);
selectPage
(
viewPagePosition
);
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java
deleted
100644 → 0
View file @
bef43617
package
com
.
topjohnwu
.
magisk
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.preference.PreferenceManager
;
import
android.support.v7.widget.RecyclerView
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Repo
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.io.File
;
import
java.util.List
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
ReposAdapter
extends
RecyclerView
.
Adapter
<
ReposAdapter
.
ViewHolder
>
{
private
final
List
<
Repo
>
mList
;
private
View
view
;
private
Context
context
;
public
ReposAdapter
(
List
<
Repo
>
list
)
{
this
.
mList
=
list
;
}
@Override
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
view
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_repo
,
parent
,
false
);
context
=
parent
.
getContext
();
return
new
ViewHolder
(
view
);
}
@Override
public
void
onBindViewHolder
(
final
ViewHolder
holder
,
int
position
)
{
final
Repo
repo
=
mList
.
get
(
position
);
holder
.
title
.
setText
(
repo
.
getName
());
holder
.
versionName
.
setText
(
repo
.
getVersion
());
holder
.
description
.
setText
(
repo
.
getDescription
());
view
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
if
(!
prefs
.
contains
(
"isInstalled_"
+
repo
.
getName
()))
{
Utils
.
DownloadReceiver
reciever
=
new
Utils
.
DownloadReceiver
()
{
@Override
public
void
task
(
File
file
)
{
Log
.
d
(
"Magisk"
,
"Task firing"
);
new
Utils
.
FlashZIP
(
context
,
repo
.
getName
(),
file
.
toString
()).
execute
();
}
};
String
filename
=
repo
.
getName
().
replace
(
" "
,
""
)
+
".zip"
;
Utils
.
downloadAndReceive
(
context
,
reciever
,
repo
.
getZipUrl
(),
filename
);
}
else
{
Toast
.
makeText
(
context
,
repo
.
getName
()
+
" is already installed."
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
});
}
@Override
public
int
getItemCount
()
{
return
mList
.
size
();
}
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
title
)
TextView
title
;
@BindView
(
R
.
id
.
version_name
)
TextView
versionName
;
@BindView
(
R
.
id
.
description
)
TextView
description
;
public
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
ButterKnife
.
bind
(
this
,
itemView
);
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java
View file @
c2a188f7
...
@@ -4,10 +4,12 @@ import android.Manifest;
...
@@ -4,10 +4,12 @@ import android.Manifest;
import
android.app.Activity
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.Intent
;
import
android.content.SharedPreferences
;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.Handler
;
import
android.preference.PreferenceManager
;
import
android.support.annotation.IdRes
;
import
android.support.annotation.IdRes
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.NonNull
;
import
android.support.design.widget.NavigationView
;
import
android.support.design.widget.NavigationView
;
...
@@ -58,7 +60,15 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
...
@@ -58,7 +60,15 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
}
}
new
Utils
.
Initialize
(
this
).
execute
();
new
Utils
.
Initialize
(
this
).
execute
();
new
Utils
.
CheckUpdates
(
this
).
execute
();
new
Utils
.
CheckUpdates
(
this
).
execute
();
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
);
if
(!
prefs
.
contains
(
"oauth_key"
))
{
}
if
(!
prefs
.
contains
(
"hasCachedRepos"
))
{
new
Utils
.
LoadModules
(
this
,
true
).
execute
();
}
else
{
new
Utils
.
LoadModules
(
getApplication
(),
false
).
execute
();
new
Utils
.
LoadModules
(
getApplication
(),
false
).
execute
();
}
setSupportActionBar
(
toolbar
);
setSupportActionBar
(
toolbar
);
...
...
app/src/main/java/com/topjohnwu/magisk/module/Module.java
View file @
c2a188f7
...
@@ -17,59 +17,126 @@ public class Module {
...
@@ -17,59 +17,126 @@ public class Module {
private
String
mName
=
null
;
private
String
mName
=
null
;
private
String
mVersion
=
"(No version provided)"
;
private
String
mVersion
=
"(No version provided)"
;
private
String
mDescription
=
"(No description provided)"
;
private
String
mDescription
=
"(No description provided)"
;
private
String
mUrl
=
null
;
private
String
mUrl
,
mSupportUrl
,
mDonateUrl
,
mZipUrl
,
mBaseUrl
,
mManifestUrl
,
mAuthor
;
private
boolean
mEnable
,
mRemove
,
mUpdateAvailable
,
mIsOnline
;
private
boolean
mEnable
;
private
boolean
mRemove
;
private
String
mId
;
private
String
mId
;
private
int
mVersionCode
;
private
int
mVersionCode
;
public
Module
(
String
path
,
Context
context
)
{
public
Module
(
String
path
,
Context
context
)
{
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
Map
<
String
,?>
keys
=
prefs
.
getAll
();
for
(
Map
.
Entry
<
String
,?>
entry
:
keys
.
entrySet
()){
if
(
entry
.
getValue
().
toString
().
contains
(
path
))
{
Log
.
d
(
"Magisk"
,
"Hey, look a matching path, this guy's name is "
+
entry
.
getKey
().
replace
(
"path_"
,
""
));
}
}
mRemoveFile
=
path
+
"/remove"
;
mRemoveFile
=
path
+
"/remove"
;
mDisableFile
=
path
+
"/disable"
;
mDisableFile
=
path
+
"/disable"
;
for
(
String
line
:
Utils
.
readFile
(
path
+
"/module.prop"
))
{
for
(
String
line
:
Utils
.
readFile
(
path
+
"/module.prop"
))
{
String
[]
p
art
s
=
line
.
split
(
"="
,
2
);
String
[]
p
rop
s
=
line
.
split
(
"="
,
2
);
if
(
p
art
s
.
length
!=
2
)
{
if
(
p
rop
s
.
length
!=
2
)
{
continue
;
continue
;
}
}
String
key
=
p
art
s
[
0
].
trim
();
String
key
=
p
rop
s
[
0
].
trim
();
if
(
key
.
charAt
(
0
)
==
'#'
)
{
if
(
key
.
charAt
(
0
)
==
'#'
)
{
continue
;
continue
;
}
}
String
value
=
parts
[
1
].
trim
();
String
value
=
props
[
1
].
trim
();
switch
(
key
)
{
switch
(
props
[
0
])
{
case
"versionCode"
:
this
.
mVersionCode
=
Integer
.
valueOf
(
props
[
1
]);
break
;
case
"name"
:
case
"name"
:
mName
=
value
;
this
.
mName
=
value
;
break
;
case
"author"
:
this
.
mAuthor
=
value
;
break
;
case
"id"
:
this
.
mId
=
value
;
break
;
break
;
case
"version"
:
case
"version"
:
mVersion
=
value
;
this
.
mVersion
=
value
;
break
;
break
;
case
"description"
:
case
"description"
:
mDescription
=
value
;
this
.
mDescription
=
value
;
break
;
break
;
case
"
id
"
:
case
"
donate
"
:
mId
=
value
;
this
.
mDonateUrl
=
value
;
break
;
break
;
case
"versionCode"
:
case
"support"
:
try
{
this
.
mSupportUrl
=
value
;
mVersionCode
=
Integer
.
parseInt
(
value
);
break
;
}
catch
(
NumberFormatException
e
)
{
case
"donateUrl"
:
mVersionCode
=
0
;
this
.
mDonateUrl
=
value
;
}
break
;
case
"zipUrl"
:
this
.
mZipUrl
=
value
;
break
;
case
"baseUrl"
:
this
.
mBaseUrl
=
value
;
break
;
case
"manifestUrl"
:
this
.
mManifestUrl
=
value
;
break
;
break
;
default
:
Log
.
d
(
"Magisk"
,
"Module: Manifest string not recognized: "
+
props
[
0
]);
break
;
}
}
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
if
(
this
.
mId
!=
null
&&
!
this
.
mId
.
isEmpty
())
{
String
preferenceString
=
"repo_"
+
this
.
mId
;
String
preferenceKey
=
prefs
.
getString
(
preferenceString
,
"nope"
);
Log
.
d
(
"Magisk"
,
"Module: Checking for preference named "
+
preferenceString
);
if
(!
preferenceKey
.
equals
(
"nope"
))
{
Log
.
d
(
"Magisk"
,
"Module: repo_"
+
mId
+
" found."
);
String
entryString
=
prefs
.
getString
(
"repo_"
+
mId
,
""
);
String
[]
subStrings
=
entryString
.
split
(
"\n"
);
for
(
String
subKeys
:
subStrings
)
{
String
[]
idEntry
=
subKeys
.
split
(
"="
,
2
);
if
(
idEntry
[
0
].
equals
(
"id"
))
{
if
(
idEntry
.
length
!=
2
)
{
continue
;
}
}
if
(
idEntry
[
1
].
equals
(
mId
))
{
Log
.
d
(
"Magisk"
,
"Module: Hey, I know I'm online..."
);
mIsOnline
=
true
;
}
else
mIsOnline
=
false
;
}
if
(
idEntry
[
0
].
equals
(
"versionCode"
))
{
if
(
idEntry
.
length
!=
2
)
{
continue
;
}
if
(
Integer
.
valueOf
(
idEntry
[
1
])
>
mVersionCode
)
{
mUpdateAvailable
=
true
;
Log
.
d
(
"Magisk"
,
"Module: Hey, I have an update..."
);
}
else
mUpdateAvailable
=
false
;
}
}
}
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
if
(
mIsOnline
)
{
editor
.
putBoolean
(
"repo-isInstalled_"
+
mId
,
true
);
}
else
{
editor
.
putBoolean
(
"repo-isInstalled_"
+
mId
,
false
);
}
if
(
mUpdateAvailable
)
{
editor
.
putBoolean
(
"repo-canUpdate_"
+
mId
,
true
);
}
else
{
editor
.
putBoolean
(
"repo-canUpdate_"
+
mId
,
false
);
}
editor
.
apply
();
}
}
if
(
mName
==
null
)
{
if
(
mName
==
null
)
{
...
@@ -86,11 +153,11 @@ public class Module {
...
@@ -86,11 +153,11 @@ public class Module {
public
Module
(
Repo
repo
)
{
public
Module
(
Repo
repo
)
{
mName
=
repo
.
getName
();
mName
=
repo
.
getName
();
mVersion
=
repo
.
getVersion
();
mVersion
=
repo
.
get
m
Version
();
mDescription
=
repo
.
getDescription
();
mDescription
=
repo
.
getDescription
();
mId
=
"foo"
;
mId
=
repo
.
getId
()
;
mVersionCode
=
111
;
mVersionCode
=
repo
.
getmVersionCode
()
;
mUrl
=
repo
.
getZipUrl
();
mUrl
=
repo
.
get
m
ZipUrl
();
mEnable
=
true
;
mEnable
=
true
;
mRemove
=
false
;
mRemove
=
false
;
...
@@ -134,4 +201,8 @@ public class Module {
...
@@ -134,4 +201,8 @@ public class Module {
return
mRemove
;
return
mRemove
;
}
}
public
boolean
isOnline
()
{
return
mIsOnline
;
}
public
boolean
isUpdateAvailable
()
{
return
mUpdateAvailable
;
};
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/module/Repo.java
View file @
c2a188f7
...
@@ -5,124 +5,265 @@ import android.content.SharedPreferences;
...
@@ -5,124 +5,265 @@ import android.content.SharedPreferences;
import
android.preference.PreferenceManager
;
import
android.preference.PreferenceManager
;
import
android.util.Log
;
import
android.util.Log
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.WebRequest
;
import
com.topjohnwu.magisk.utils.WebRequest
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Date
;
public
class
Repo
{
public
class
Repo
{
public
String
name
;
private
String
mBaseUrl
;
public
String
baseUrl
,
zipUrl
,
manifestUrl
,
logUrl
,
manifest
,
version
,
moduleName
,
moduleDescription
,
moduleAuthor
,
moduleAuthorUrl
;
private
String
mZipUrl
;
public
Date
lastUpdate
;
private
String
mLogUrl
;
public
Boolean
usesRoot
,
usesXposed
;
private
String
mManifestUrl
;
private
String
mVersion
;
private
String
mName
;
private
String
mDescription
;
private
String
mAuthor
;
public
String
mAuthorUrl
;
private
String
mId
;
private
String
mVersionCode
;
private
String
mSupportUrl
;
private
String
mDonateUrl
;
private
String
lastUpdate
;
private
Context
appContext
;
private
Context
appContext
;
private
SharedPreferences
prefs
;
private
boolean
mIsInstalled
,
mCanUpdate
;
public
Repo
(
String
manifestString
,
Context
context
)
{
appContext
=
context
;
ParseProps
(
manifestString
);
}
public
Repo
(
String
name
,
String
url
,
Date
updated
,
Context
context
)
{
public
Repo
(
String
name
,
String
url
,
Date
updated
,
Context
context
)
{
appContext
=
context
;
appContext
=
context
;
this
.
name
=
name
;
this
.
mName
=
name
;
this
.
baseUrl
=
url
;
this
.
mBaseUrl
=
url
;
this
.
lastUpdate
=
updated
;
this
.
lastUpdate
=
updated
.
toString
();
this
.
fetch
();
this
.
fetch
();
}
}
public
Repo
(
String
moduleName
,
String
moduleDescription
,
String
zipUrl
,
Date
lastUpdated
,
Context
context
)
{
public
Repo
(
String
moduleName
,
String
moduleDescription
,
String
zipUrl
,
Date
lastUpdated
,
Context
context
)
{
Log
.
d
(
"Magisk"
,
"Hey, I'm a repo! My name is "
+
moduleName
);
appContext
=
context
;
appContext
=
context
;
this
.
z
ipUrl
=
zipUrl
;
this
.
mZ
ipUrl
=
zipUrl
;
this
.
m
odule
Description
=
moduleDescription
;
this
.
mDescription
=
moduleDescription
;
this
.
m
odule
Name
=
moduleName
;
this
.
mName
=
moduleName
;
this
.
lastUpdate
=
lastUpdated
;
this
.
lastUpdate
=
lastUpdated
.
toString
()
;
this
.
fetch
();
}
}
public
void
fetch
()
{
public
void
fetch
()
{
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
WebRequest
webreq
=
new
WebRequest
();
WebRequest
webreq
=
new
WebRequest
();
// Construct initial url for contents
// Construct initial url for contents
Log
.
d
(
"Magisk"
,
"Manifest string is: "
+
baseUrl
+
"/contents/"
);
Log
.
d
(
"Magisk"
,
"Repo: Fetch called, Manifest string is: "
+
mBaseUrl
+
"/contents?access_token="
+
Utils
.
procFile
(
appContext
.
getString
(
R
.
string
.
some_string
),
appContext
));
String
repoString
=
webreq
.
makeWebServiceCall
(
baseUrl
+
"/contents/"
,
WebRequest
.
GET
);
String
repoString
=
webreq
.
makeWebServiceCall
(
mBaseUrl
+
"/contents?access_token="
+
Utils
.
procFile
(
appContext
.
getString
(
R
.
string
.
some_string
),
appContext
),
WebRequest
.
GET
);
try
{
try
{
JSONArray
repoArray
=
new
JSONArray
(
repoString
);
JSONArray
repoArray
=
new
JSONArray
(
repoString
);
for
(
int
f
=
0
;
f
<
repoArray
.
length
();
f
++)
{
for
(
int
f
=
0
;
f
<
repoArray
.
length
();
f
++)
{
JSONObject
jsonobject
=
repoArray
.
getJSONObject
(
f
);
JSONObject
jsonobject
=
repoArray
.
getJSONObject
(
f
);
String
name
=
jsonobject
.
getString
(
"name"
);
String
name
=
jsonobject
.
getString
(
"name"
);
if
(
name
.
contains
(
".zip"
))
{
if
(
name
.
contains
(
".zip"
))
{
this
.
z
ipUrl
=
jsonobject
.
getString
(
"download_url"
);
this
.
mZ
ipUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"module.
json
"
))
{
}
else
if
(
name
.
equals
(
"module.
prop
"
))
{
this
.
manifestUrl
=
jsonobject
.
getString
(
"download_url"
);
this
.
m
M
anifestUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"
C
hangelog.txt"
))
{
}
else
if
(
name
.
equals
(
"
c
hangelog.txt"
))
{
this
.
l
ogUrl
=
jsonobject
.
getString
(
"download_url"
);
this
.
mL
ogUrl
=
jsonobject
.
getString
(
"download_url"
);
}
}
}
}
}
catch
(
JSONException
e
)
{
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
Log
.
d
(
"Magisk"
,
"Inner fetch: "
+
repoString
);
Log
.
d
(
"Magisk"
,
"Repo: Inner fetch: "
+
mManifestUrl
+
"?access_token="
+
Utils
.
procFile
(
appContext
.
getString
(
R
.
string
.
some_string
),
appContext
));
try
{
WebRequest
propReq
=
new
WebRequest
();
WebRequest
jsonReq
=
new
WebRequest
();
String
manifestString
=
propReq
.
makeWebServiceCall
(
mManifestUrl
,
WebRequest
.
GET
,
true
);
// Construct initial url for contents
Log
.
d
(
"Magisk"
,
"Repo: parseprops called from fetch for string "
+
manifestString
);
String
manifestString
=
webreq
.
makeWebServiceCall
(
this
.
manifestUrl
,
WebRequest
.
GET
);
JSONObject
manifestObject
=
new
JSONObject
(
manifestString
);
if
(
ParseProps
(
manifestString
))
{
Log
.
d
(
"Magisk"
,
"Object: "
+
manifestObject
.
toString
());
PutProps
(
manifestString
);
version
=
manifestObject
.
getString
(
"versionCode"
);
}
moduleName
=
manifestObject
.
getString
(
"moduleName"
);
moduleDescription
=
manifestObject
.
getString
(
"moduleDescription"
);
}
moduleAuthor
=
manifestObject
.
getString
(
"moduleAuthor"
);
usesRoot
=
Boolean
.
getBoolean
(
manifestObject
.
getString
(
"usesRoot"
));
private
void
PutProps
(
String
manifestString
)
{
usesXposed
=
Boolean
.
getBoolean
(
manifestObject
.
getString
(
"usesXposed"
));
manifestString
=
manifestString
+
"zipUrl="
+
mZipUrl
+
"\nbaseUrl="
+
mBaseUrl
+
"\nlogUrl="
+
mLogUrl
+
"\nmanifestUrl="
+
mManifestUrl
;
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
String
prefsString
=
"[{\"moduleDescription\":\""
+
moduleDescription
+
"\","
editor
.
putString
(
"repo_"
+
mId
,
manifestString
);
+
"\"moduleName\":\""
+
moduleName
+
"\","
+
"\"moduleAuthor\":\""
+
moduleAuthor
+
"\","
+
"\"moduleAuthorUrl\":\""
+
moduleAuthorUrl
+
"\","
+
"\"usesRoot\":\""
+
usesRoot
+
"\","
+
"\"usesXposed\":\""
+
usesXposed
+
"\","
+
"\"zipUrl\":\""
+
zipUrl
+
"\","
+
"\"lastUpdate\":\""
+
lastUpdate
+
"\","
+
"\"logUrl\":\""
+
logUrl
+
"\"}]"
;
editor
.
putString
(
"module_"
+
moduleName
,
prefsString
);
editor
.
putBoolean
(
"hasCachedRepos"
,
true
);
editor
.
putBoolean
(
"hasCachedRepos"
,
true
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyyMMdd_HHmmss"
);
editor
.
putString
(
"updated_"
+
mId
,
this
.
lastUpdate
.
toString
());
editor
.
putString
(
"updated"
,
sdf
.
toString
());
Log
.
d
(
"Magisk"
,
"Storing Preferences: "
+
manifestString
);
Log
.
d
(
"Magisk"
,
"Storing Preferences: "
+
prefsString
);
editor
.
apply
();
editor
.
apply
();
}
private
boolean
ParseProps
(
String
string
)
{
}
catch
(
JSONException
e
)
{
if
((
string
.
length
()
<=
1
)
|
(!
string
.
contains
(
"id"
)))
{
e
.
printStackTrace
();
return
false
;
}
else
{
String
lines
[]
=
string
.
split
(
"\\n"
);
for
(
String
line
:
lines
)
{
if
(
line
!=
""
)
{
String
props
[]
=
line
.
split
(
"="
);
switch
(
props
[
0
])
{
case
"versionCode"
:
this
.
mVersionCode
=
props
[
1
];
break
;
case
"name"
:
this
.
mName
=
props
[
1
];
break
;
case
"author"
:
this
.
mAuthor
=
props
[
1
];
break
;
case
"id"
:
this
.
mId
=
props
[
1
];
break
;
case
"version"
:
this
.
mVersion
=
props
[
1
];
break
;
case
"description"
:
this
.
mDescription
=
props
[
1
];
break
;
case
"donate"
:
this
.
mDonateUrl
=
props
[
1
];
break
;
case
"support"
:
this
.
mSupportUrl
=
props
[
1
];
break
;
case
"donateUrl"
:
this
.
mDonateUrl
=
props
[
1
];
break
;
case
"zipUrl"
:
this
.
mZipUrl
=
props
[
1
];
break
;
case
"baseUrl"
:
this
.
mBaseUrl
=
props
[
1
];
break
;
case
"manifestUrl"
:
this
.
mManifestUrl
=
props
[
1
];
break
;
case
"logUrl"
:
this
.
mLogUrl
=
props
[
1
];
break
;
default
:
Log
.
d
(
"Magisk"
,
"Manifest string not recognized: "
+
props
[
0
]);
break
;
}
}
}
}
}
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
if
(
prefs
.
contains
(
"repo-isInstalled_"
+
this
.
mId
))
{
mIsInstalled
=
prefs
.
getBoolean
(
"repo-isInstalled_"
+
this
.
mId
,
false
);
}
if
(
prefs
.
contains
(
"repo-canUpdate_"
+
this
.
mId
))
{
mCanUpdate
=
prefs
.
getBoolean
(
"repo-canUpdate_"
+
this
.
mId
,
false
);
}
if
(
prefs
.
contains
(
"updated_"
+
this
.
mId
))
{
lastUpdate
=
prefs
.
getString
(
"updated_"
+
this
.
mId
,
""
);
}
return
this
.
mId
!=
null
;
}
}
public
String
getStringProperty
(
String
mValue
)
{
switch
(
mValue
)
{
case
"author"
:
return
mAuthor
;
case
"id"
:
return
mId
;
case
"version"
:
return
mVersion
;
case
"description"
:
return
mDescription
;
case
"supportUrl"
:
return
mSupportUrl
;
case
"donateUrl"
:
return
mDonateUrl
;
case
"baseeUrl"
:
return
mBaseUrl
;
case
"zipUrl"
:
return
mZipUrl
;
default
:
return
null
;
}
}
public
String
getName
()
{
public
String
getName
()
{
return
m
odule
Name
;
return
mName
;
}
}
public
String
getVersion
()
{
public
String
getmVersion
()
{
return
version
;
return
mVersion
;
}
public
int
getmVersionCode
()
{
return
Integer
.
valueOf
(
mVersionCode
);
}
}
public
String
getDescription
()
{
public
String
getDescription
()
{
return
m
odule
Description
;
return
mDescription
;
}
}
public
String
get
ZipUrl
()
{
public
String
get
Id
()
{
return
zipUrl
;
return
mId
;
}
}
public
String
get
Log
Url
()
{
public
String
get
mZip
Url
()
{
return
log
Url
;
return
mZip
Url
;
}
}
public
String
getmBaseUrl
()
{
return
mBaseUrl
;
}
public
String
getmLogUrl
()
{
return
mLogUrl
;
}
public
String
getmAuthor
()
{
return
mAuthor
;
}
public
String
getmDonateUrl
()
{
return
mDonateUrl
;
}
public
String
getmManifestUrl
()
{
return
mManifestUrl
;
}
public
String
getmSupportUrl
()
{
return
mSupportUrl
;
}
public
String
getLastUpdate
()
{
return
lastUpdate
;
}
public
boolean
isInstalled
()
{
return
mIsInstalled
;
}
public
boolean
canUpdate
()
{
return
mCanUpdate
;
}
}
}
app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java
deleted
100644 → 0
View file @
bef43617
package
com
.
topjohnwu
.
magisk
.
module
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.os.AsyncTask
;
import
android.preference.PreferenceManager
;
import
android.util.Log
;
import
android.widget.Toast
;
import
com.topjohnwu.magisk.utils.WebRequest
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
public
class
RepoAdapter
{
private
String
[]
result
;
private
static
String
url
=
"https://api.github.com/orgs/Magisk-Modules-Repo/repos"
;
private
static
List
<
Repo
>
repos
=
new
ArrayList
<
Repo
>();
private
static
final
String
TAG_ID
=
"id"
;
private
static
final
String
TAG_NAME
=
"name"
;
private
Context
activityContext
;
private
Date
updatedDate
,
currentDate
;
public
List
<
Repo
>
listRepos
(
Context
context
,
boolean
refresh
)
{
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
if
(!
prefs
.
contains
(
"hasCachedRepos"
)
|
refresh
)
{
activityContext
=
context
;
new
MyAsyncTask
().
execute
();
List
<
String
>
out
=
null
;
}
else
{
Log
.
d
(
"Magisk"
,
"Building from cache"
);
Map
<
String
,
?>
map
=
prefs
.
getAll
();
repos
.
clear
();
for
(
Map
.
Entry
<
String
,
?>
entry
:
map
.
entrySet
())
{
if
(
entry
.
getKey
().
contains
(
"module_"
))
{
String
repoString
=
entry
.
getValue
().
toString
().
replace
(
"""
,
"\""
);
JSONArray
repoArray
=
null
;
try
{
repoArray
=
new
JSONArray
(
repoString
);
for
(
int
f
=
0
;
f
<
repoArray
.
length
();
f
++)
{
JSONObject
jsonobject
=
repoArray
.
getJSONObject
(
f
);
String
name
=
entry
.
getKey
().
replace
(
"module_"
,
""
);
name
=
name
.
replace
(
" "
,
""
);
String
moduleName
,
moduleDescription
,
zipUrl
;
moduleName
=
jsonobject
.
getString
(
"moduleName"
);
moduleDescription
=
jsonobject
.
getString
(
"moduleDescription"
);
zipUrl
=
jsonobject
.
getString
(
"zipUrl"
);
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
);
try
{
updatedDate
=
format
.
parse
(
jsonobject
.
getString
(
"lastUpdate"
));
}
catch
(
ParseException
e
)
{
e
.
printStackTrace
();
}
repos
.
add
(
new
Repo
(
name
,
moduleDescription
,
zipUrl
,
updatedDate
,
activityContext
));
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
}
}
}
return
repos
;
}
class
MyAsyncTask
extends
AsyncTask
<
String
,
String
,
Void
>
{
@Override
protected
void
onPreExecute
()
{
super
.
onPreExecute
();
}
@Override
protected
void
onProgressUpdate
(
String
...
values
)
{
super
.
onProgressUpdate
(
values
);
Toast
.
makeText
(
activityContext
,
"Refreshing online modules"
,
Toast
.
LENGTH_SHORT
).
show
();
}
@Override
protected
Void
doInBackground
(
String
...
params
)
{
publishProgress
();
// Creating service handler class instance
WebRequest
webreq
=
new
WebRequest
();
// Making a request to url and getting response
String
jsonStr
=
webreq
.
makeWebServiceCall
(
url
,
WebRequest
.
GET
);
Log
.
d
(
"Magisk"
,
"doInBackground Running, String: "
+
jsonStr
+
" Url: "
+
url
);
try
{
repos
.
clear
();
JSONArray
jsonArray
=
new
JSONArray
(
jsonStr
);
for
(
int
i
=
0
;
i
<
jsonArray
.
length
();
i
++)
{
JSONObject
jsonobject
=
jsonArray
.
getJSONObject
(
i
);
String
name
=
jsonobject
.
getString
(
"name"
);
String
url
=
jsonobject
.
getString
(
"url"
);
String
lastUpdate
=
jsonobject
.
getString
(
"updated_at"
);
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
);
try
{
updatedDate
=
format
.
parse
(
lastUpdate
);
}
catch
(
ParseException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
if
(!
name
.
contains
(
"Repo.github.io"
))
{
repos
.
add
(
new
Repo
(
name
,
url
,
updatedDate
,
activityContext
));
}
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
protected
void
onPostExecute
(
Void
v
)
{
}
// protected void onPostExecute(Void v)
}
//class MyAsyncTask extends AsyncTask<String, String, Void>
protected
void
onPreExecute
()
{
}
}
app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java
0 → 100644
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
.
module
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.os.AsyncTask
;
import
android.preference.PreferenceManager
;
import
android.util.Log
;
import
android.widget.Toast
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.WebRequest
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
public
class
RepoHelper
{
private
String
[]
result
;
private
static
String
url
=
"https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token="
;
private
static
List
<
Repo
>
repos
=
new
ArrayList
<
Repo
>();
private
static
final
String
TAG_ID
=
"id"
;
private
static
final
String
TAG_NAME
=
"name"
;
private
static
String
TAG
=
"Magisk"
;
private
String
mName
,
mId
,
mUrl
;
private
Context
activityContext
;
private
Date
updatedDate
,
currentDate
;
private
SharedPreferences
prefs
;
private
boolean
apiFail
;
public
List
<
Repo
>
listRepos
(
Context
context
,
boolean
refresh
)
{
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
activityContext
=
context
;
if
(!
prefs
.
contains
(
"hasCachedRepos"
)
|
refresh
)
{
Log
.
d
(
TAG
,
"RepoHelper: Building from web"
);
new
MyAsyncTask
().
execute
();
List
<
String
>
out
=
null
;
}
else
{
Log
.
d
(
TAG
,
"RepoHelper: Building from cache"
);
BuildFromCache
();
}
return
repos
;
}
private
void
BuildFromCache
()
{
repos
.
clear
();
Map
<
String
,
?>
map
=
prefs
.
getAll
();
for
(
Map
.
Entry
<
String
,
?>
entry
:
map
.
entrySet
())
{
if
(
entry
.
getKey
().
contains
(
"repo_"
))
{
Log
.
d
(
"Magisk"
,
"RepoHelper: found entry for repo "
+
entry
.
getKey
());
String
repoString
=
entry
.
getValue
().
toString
().
replace
(
"""
,
"\""
);
String
[]
repoStrings
=
repoString
.
split
(
"\n"
);
for
(
String
string
:
repoStrings
)
{
String
[]
splitStrings
=
string
.
split
(
"="
);
switch
(
splitStrings
[
0
])
{
case
(
"id"
):
mId
=
splitStrings
[
1
];
break
;
case
(
"baseUrl"
):
mUrl
=
splitStrings
[
1
];
break
;
default
:
break
;
}
}
Log
.
d
(
"Magisk"
,
"RepoHelper: adding repo with id of "
+
mId
);
repos
.
add
(
new
Repo
(
repoString
,
activityContext
));
}
}
}
class
MyAsyncTask
extends
AsyncTask
<
String
,
String
,
Void
>
{
@Override
protected
void
onPreExecute
()
{
super
.
onPreExecute
();
}
@Override
protected
void
onProgressUpdate
(
String
...
values
)
{
super
.
onProgressUpdate
(
values
);
Toast
.
makeText
(
activityContext
,
"Refreshing online modules"
,
Toast
.
LENGTH_SHORT
).
show
();
}
@Override
protected
Void
doInBackground
(
String
...
params
)
{
publishProgress
();
// Creating service handler class instance
WebRequest
webreq
=
new
WebRequest
();
// Making a request to url and getting response
String
token
=
activityContext
.
getString
(
R
.
string
.
some_string
);
String
jsonStr
=
webreq
.
makeWebServiceCall
(
url
+
Utils
.
procFile
(
token
,
activityContext
),
WebRequest
.
GET
);
Log
.
d
(
"Magisk"
,
"doInBackground Running, String: "
+
jsonStr
+
" Url: "
+
url
);
if
(
jsonStr
!=
null
&&
!
jsonStr
.
isEmpty
())
{
try
{
repos
.
clear
();
JSONArray
jsonArray
=
new
JSONArray
(
jsonStr
);
for
(
int
i
=
0
;
i
<
jsonArray
.
length
();
i
++)
{
JSONObject
jsonobject
=
jsonArray
.
getJSONObject
(
i
);
String
name
=
jsonobject
.
getString
(
"name"
);
String
url
=
jsonobject
.
getString
(
"url"
);
String
lastUpdate
=
jsonobject
.
getString
(
"updated_at"
);
String
mId
=
""
;
String
cacheUpdate
=
""
;
String
manifestString
=
""
;
boolean
doUpdate
=
true
;
boolean
hasCachedDate
=
false
;
SimpleDateFormat
format
=
new
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
);
Map
<
String
,
?>
map
=
prefs
.
getAll
();
for
(
Map
.
Entry
<
String
,
?>
entry
:
map
.
entrySet
())
{
if
(
entry
.
getValue
().
toString
().
contains
(
url
))
{
Log
.
d
(
"Magisk"
,
"RepoHelper: found matching URL"
);
manifestString
=
entry
.
getValue
().
toString
();
String
[]
entryStrings
=
entry
.
getValue
().
toString
().
split
(
"\n"
);
for
(
String
valueString
:
entryStrings
)
{
String
[]
valueSub
=
valueString
.
split
(
"="
);
if
(
valueSub
[
0
].
equals
(
"id"
))
{
mId
=
valueSub
[
1
];
Log
.
d
(
"Magisk"
,
"RepoHelper: Got id for package of "
+
mId
);
if
(
prefs
.
contains
(
"updated_"
+
mId
))
{
cacheUpdate
=
prefs
.
getString
(
"updated_"
+
mId
,
""
);
hasCachedDate
=
true
;
}
}
}
}
}
try
{
updatedDate
=
format
.
parse
(
lastUpdate
);
Log
.
d
(
"Magisk"
,
"RepoHelper: Dates found, online is "
+
updatedDate
+
" and cached is "
+
cacheUpdate
);
if
(
hasCachedDate
)
{
doUpdate
=
!
cacheUpdate
.
equals
(
updatedDate
.
toString
());
Log
.
d
(
"Magisk"
,
"RepoHelper: DoUpdate is "
+
doUpdate
);
}
}
catch
(
ParseException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
if
(!
name
.
contains
(
"Repo.github.io"
))
{
if
(
doUpdate
)
{
repos
.
add
(
new
Repo
(
name
,
url
,
updatedDate
,
activityContext
));
Log
.
d
(
TAG
,
"RepoHelper: Trying to add new repo for online refresh - "
+
name
);
}
else
{
repos
.
add
(
new
Repo
(
manifestString
,
activityContext
));
Log
.
d
(
TAG
,
"RepoHelper: Trying to add new repo using manifestString of "
+
mId
);
}
}
for
(
int
f
=
0
;
f
<
repos
.
size
();
f
++)
{
repos
.
get
(
f
).
fetch
();
}
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
apiFail
=
false
;
}
else
{
apiFail
=
true
;
}
return
null
;
}
protected
void
onPostExecute
(
Void
v
)
{
if
(
apiFail
)
{
Toast
.
makeText
(
activityContext
,
"GitHub API Limit reached, please try refreshing again in an hour."
,
Toast
.
LENGTH_LONG
).
show
();
}
else
{
BuildFromCache
();
}
}
// protected void onPostExecute(Void v)
}
//class MyAsyncTask extends AsyncTask<String, String, Void>
protected
void
onPreExecute
()
{
}
}
app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java
0 → 100644
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
.
utils
;
import
android.view.View
;
import
android.view.animation.Animation
;
import
android.view.animation.Transformation
;
import
android.widget.LinearLayout
;
public
class
AnimationHelper
{
public
static
void
expand
(
final
View
v
)
{
v
.
measure
(
LinearLayout
.
LayoutParams
.
MATCH_PARENT
,
LinearLayout
.
LayoutParams
.
WRAP_CONTENT
);
final
int
targetHeight
=
v
.
getMeasuredHeight
();
v
.
getLayoutParams
().
height
=
0
;
v
.
setVisibility
(
View
.
VISIBLE
);
Animation
a
=
new
Animation
()
{
@Override
protected
void
applyTransformation
(
float
interpolatedTime
,
Transformation
t
)
{
v
.
getLayoutParams
().
height
=
interpolatedTime
==
1
?
LinearLayout
.
LayoutParams
.
WRAP_CONTENT
:
(
int
)
(
targetHeight
*
interpolatedTime
);
v
.
requestLayout
();
}
@Override
public
boolean
willChangeBounds
()
{
return
true
;
}
};
// 1dp/ms
a
.
setDuration
((
int
)
(
targetHeight
/
v
.
getContext
().
getResources
().
getDisplayMetrics
().
density
));
v
.
startAnimation
(
a
);
}
public
static
void
collapse
(
final
View
v
)
{
final
int
initialHeight
=
v
.
getMeasuredHeight
();
Animation
a
=
new
Animation
()
{
@Override
protected
void
applyTransformation
(
float
interpolatedTime
,
Transformation
t
)
{
if
(
interpolatedTime
==
1
)
{
v
.
setVisibility
(
View
.
GONE
);
}
else
{
v
.
getLayoutParams
().
height
=
initialHeight
-
(
int
)
(
initialHeight
*
interpolatedTime
);
v
.
requestLayout
();
}
}
@Override
public
boolean
willChangeBounds
()
{
return
true
;
}
};
// 1dp/ms
a
.
setDuration
((
int
)
(
initialHeight
/
v
.
getContext
().
getResources
().
getDisplayMetrics
().
density
));
v
.
startAnimation
(
a
);
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java
0 → 100644
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
.
utils
;
public
class
GitAgent
{
}
app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
View file @
c2a188f7
...
@@ -10,6 +10,7 @@ import android.content.Intent;
...
@@ -10,6 +10,7 @@ import android.content.Intent;
import
android.content.IntentFilter
;
import
android.content.IntentFilter
;
import
android.content.SharedPreferences
;
import
android.content.SharedPreferences
;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager
;
import
android.content.res.Resources
;
import
android.database.Cursor
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.net.Uri
;
import
android.os.AsyncTask
;
import
android.os.AsyncTask
;
...
@@ -18,6 +19,7 @@ import android.preference.PreferenceManager;
...
@@ -18,6 +19,7 @@ import android.preference.PreferenceManager;
import
android.support.design.widget.Snackbar
;
import
android.support.design.widget.Snackbar
;
import
android.support.v4.app.ActivityCompat
;
import
android.support.v4.app.ActivityCompat
;
import
android.support.v7.app.AlertDialog
;
import
android.support.v7.app.AlertDialog
;
import
android.util.Base64
;
import
android.util.Log
;
import
android.util.Log
;
import
android.view.View
;
import
android.view.View
;
import
android.widget.Toast
;
import
android.widget.Toast
;
...
@@ -25,7 +27,7 @@ import android.widget.Toast;
...
@@ -25,7 +27,7 @@ import android.widget.Toast;
import
com.topjohnwu.magisk.ModulesFragment
;
import
com.topjohnwu.magisk.ModulesFragment
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Repo
Adapt
er
;
import
com.topjohnwu.magisk.module.Repo
Help
er
;
import
com.topjohnwu.magisk.module.Repo
;
import
com.topjohnwu.magisk.module.Repo
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
...
@@ -36,17 +38,28 @@ import java.io.BufferedReader;
...
@@ -36,17 +38,28 @@ import java.io.BufferedReader;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
java.io.InputStreamReader
;
import
java.io.UnsupportedEncodingException
;
import
java.net.HttpURLConnection
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URL
;
import
java.text.ParseException
;
import
java.security.InvalidKeyException
;
import
java.text.SimpleDateFormat
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.spec.InvalidKeySpecException
;
import
java.util.List
;
import
java.util.List
;
import
javax.crypto.BadPaddingException
;
import
javax.crypto.Cipher
;
import
javax.crypto.IllegalBlockSizeException
;
import
javax.crypto.NoSuchPaddingException
;
import
javax.crypto.SecretKey
;
import
javax.crypto.SecretKeyFactory
;
import
javax.crypto.spec.DESKeySpec
;
public
class
Utils
{
public
class
Utils
{
public
static
int
magiskVersion
,
remoteMagiskVersion
=
-
1
,
remoteAppVersion
=
-
1
;
public
static
int
magiskVersion
,
remoteMagiskVersion
=
-
1
,
remoteAppVersion
=
-
1
;
public
static
String
magiskLink
,
magiskChangelog
,
appChangelog
,
appLink
,
phhLink
,
supersuLink
;
public
static
String
magiskLink
,
magiskChangelog
,
appChangelog
,
appLink
,
phhLink
,
supersuLink
;
private
Context
appContext
;
private
Context
appContext
;
private
static
final
String
TAG
=
"Magisk"
;
public
static
final
String
MAGISK_PATH
=
"/magisk"
;
public
static
final
String
MAGISK_PATH
=
"/magisk"
;
public
static
final
String
MAGISK_CACHE_PATH
=
"/cache/magisk"
;
public
static
final
String
MAGISK_CACHE_PATH
=
"/cache/magisk"
;
...
@@ -372,17 +385,49 @@ public class Utils {
...
@@ -372,17 +385,49 @@ public class Utils {
}
}
}
}
public
static
String
procFile
(
String
value
,
Context
context
)
{
String
cryptoPass
=
context
.
getResources
().
getString
(
R
.
string
.
pass
);
try
{
DESKeySpec
keySpec
=
new
DESKeySpec
(
cryptoPass
.
getBytes
(
"UTF8"
));
SecretKeyFactory
keyFactory
=
SecretKeyFactory
.
getInstance
(
"DES"
);
SecretKey
key
=
keyFactory
.
generateSecret
(
keySpec
);
byte
[]
encrypedPwdBytes
=
Base64
.
decode
(
value
,
Base64
.
DEFAULT
);
// cipher is not thread safe
Cipher
cipher
=
Cipher
.
getInstance
(
"DES"
);
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
);
byte
[]
decrypedValueBytes
=
(
cipher
.
doFinal
(
encrypedPwdBytes
));
String
decrypedValue
=
new
String
(
decrypedValueBytes
);
return
decrypedValue
;
}
catch
(
InvalidKeyException
e
)
{
e
.
printStackTrace
();
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvalidKeySpecException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchAlgorithmException
e
)
{
e
.
printStackTrace
();
}
catch
(
BadPaddingException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchPaddingException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalBlockSizeException
e
)
{
e
.
printStackTrace
();
}
return
value
;
}
public
static
class
LoadModules
extends
AsyncTask
<
Void
,
Void
,
Void
>
{
public
static
class
LoadModules
extends
AsyncTask
<
Void
,
Void
,
Void
>
{
private
Context
mContext
;
private
Context
mContext
;
private
boolean
doReload
;
private
boolean
doReload
;
public
LoadModules
(
Context
context
,
boolean
reload
)
{
public
LoadModules
(
Context
context
,
boolean
reload
)
{
Log
.
d
(
"Magisk"
,
"LoadModules created, online is "
+
reload
);
mContext
=
context
;
mContext
=
context
;
doReload
=
reload
;
doReload
=
reload
;
}
}
@Override
@Override
...
@@ -391,29 +436,26 @@ public class Utils {
...
@@ -391,29 +436,26 @@ public class Utils {
ModulesFragment
.
listModulesCache
.
clear
();
ModulesFragment
.
listModulesCache
.
clear
();
ModulesFragment
.
listModulesDownload
.
clear
();
ModulesFragment
.
listModulesDownload
.
clear
();
List
<
String
>
magisk
=
getModList
(
MAGISK_PATH
);
List
<
String
>
magisk
=
getModList
(
MAGISK_PATH
);
Log
.
d
(
"Magisk"
,
"
Reload called, online mode set to "
+
doReload
);
Log
.
d
(
"Magisk"
,
"
Utils: Reload called, loading modules from"
+
(
doReload
?
" the internet "
:
" cache"
)
);
List
<
String
>
magiskCache
=
getModList
(
MAGISK_CACHE_PATH
);
List
<
String
>
magiskCache
=
getModList
(
MAGISK_CACHE_PATH
);
RepoAdapter
mr
=
new
RepoAdapter
();
RepoHelper
mr
=
new
RepoHelper
();
List
<
Repo
>
magiskRepos
=
mr
.
listRepos
(
mContext
,
doReload
);
List
<
Repo
>
magiskRepos
=
mr
.
listRepos
(
mContext
,
doReload
);
for
(
String
mod
:
magisk
)
{
for
(
String
mod
:
magisk
)
{
Log
.
d
(
"Magisk"
,
"Utils: Adding module from string "
+
mod
);
ModulesFragment
.
listModules
.
add
(
new
Module
(
mod
,
mContext
));
ModulesFragment
.
listModules
.
add
(
new
Module
(
mod
,
mContext
));
}
}
for
(
String
mod
:
magiskCache
)
{
for
(
String
mod
:
magiskCache
)
{
Log
.
d
(
"Magisk"
,
"Utils: Adding cache module from string "
+
mod
);
ModulesFragment
.
listModulesCache
.
add
(
new
Module
(
mod
,
mContext
));
ModulesFragment
.
listModulesCache
.
add
(
new
Module
(
mod
,
mContext
));
}
}
for
(
Repo
repo
:
magiskRepos
)
{
for
(
Repo
repo
:
magiskRepos
)
{
Log
.
d
(
"Magisk"
,
"Utils: Adding repo from string "
+
repo
.
getId
());
ModulesFragment
.
listModulesDownload
.
add
(
repo
);
ModulesFragment
.
listModulesDownload
.
add
(
repo
);
}
}
return
null
;
return
null
;
}
}
@Override
protected
void
onPostExecute
(
Void
aVoid
)
{
super
.
onPostExecute
(
aVoid
);
}
}
}
public
static
class
FlashZIP
extends
AsyncTask
<
Void
,
Void
,
Boolean
>
{
public
static
class
FlashZIP
extends
AsyncTask
<
Void
,
Void
,
Boolean
>
{
...
@@ -460,35 +502,6 @@ public class Utils {
...
@@ -460,35 +502,6 @@ public class Utils {
if
(!
result
)
{
if
(!
result
)
{
Toast
.
makeText
(
mContext
,
mContext
.
getString
(
R
.
string
.
manual_install
,
mPath
),
Toast
.
LENGTH_LONG
).
show
();
Toast
.
makeText
(
mContext
,
mContext
.
getString
(
R
.
string
.
manual_install
,
mPath
),
Toast
.
LENGTH_LONG
).
show
();
return
;
return
;
}
else
{
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
mContext
);
String
jsonString
=
prefs
.
getString
(
"module_"
+
mName
,
""
);
String
retSplit
[]
=
ret
.
toString
().
split
(
"Using path:"
);
String
ret2Split
[]
=
retSplit
[
1
].
split
(
","
);
String
ret3Split
[]
=
ret2Split
[
0
].
split
(
"/"
);
String
finalSplit
=
"/"
+
ret3Split
[
1
]
+
"/"
+
ret3Split
[
2
];
Log
.
d
(
"Magisk"
,
"Damn, all that work for one path "
+
finalSplit
);
if
(!
jsonString
.
equals
(
""
))
{
JSONArray
repoArray
=
null
;
try
{
repoArray
=
new
JSONArray
(
jsonString
);
for
(
int
f
=
0
;
f
<
repoArray
.
length
();
f
++)
{
JSONObject
jsonobject
=
repoArray
.
getJSONObject
(
f
);
String
name
=
mName
;
Boolean
installed
=
true
;
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putBoolean
(
"isInstalled_"
+
mName
,
true
);
editor
.
putString
(
"path_"
+
mName
,
finalSplit
);
editor
.
apply
();
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
}
}
}
done
();
done
();
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java
View file @
c2a188f7
package
com
.
topjohnwu
.
magisk
.
utils
;
package
com
.
topjohnwu
.
magisk
.
utils
;
import
android.util.Log
;
import
java.io.BufferedReader
;
import
java.io.BufferedReader
;
import
java.io.BufferedWriter
;
import
java.io.BufferedWriter
;
import
java.io.InputStreamReader
;
import
java.io.InputStreamReader
;
...
@@ -18,6 +20,7 @@ public class WebRequest {
...
@@ -18,6 +20,7 @@ public class WebRequest {
static
String
response
=
null
;
static
String
response
=
null
;
public
final
static
int
GET
=
1
;
public
final
static
int
GET
=
1
;
public
final
static
int
POST
=
2
;
public
final
static
int
POST
=
2
;
private
boolean
addNewLine
;
//Constructor with no parameter
//Constructor with no parameter
public
WebRequest
()
{
public
WebRequest
()
{
...
@@ -31,7 +34,18 @@ public class WebRequest {
...
@@ -31,7 +34,18 @@ public class WebRequest {
* @requestmethod - http request method
* @requestmethod - http request method
*/
*/
public
String
makeWebServiceCall
(
String
url
,
int
requestmethod
)
{
public
String
makeWebServiceCall
(
String
url
,
int
requestmethod
)
{
addNewLine
=
false
;
Log
.
d
(
"Magisk"
,
"WebRequest: Service call received for URL "
+
url
);
return
this
.
makeWebServiceCall
(
url
,
requestmethod
,
null
);
return
this
.
makeWebServiceCall
(
url
,
requestmethod
,
null
);
}
public
String
makeWebServiceCall
(
String
url
,
int
requestmethod
,
boolean
addNewLines
)
{
addNewLine
=
addNewLines
;
Log
.
d
(
"Magisk"
,
"WebRequest: Service call(bool) received for URL "
+
url
);
return
this
.
makeWebServiceCall
(
url
,
requestmethod
,
null
);
}
}
/**
/**
...
@@ -90,8 +104,12 @@ public class WebRequest {
...
@@ -90,8 +104,12 @@ public class WebRequest {
String
line
;
String
line
;
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
conn
.
getInputStream
()));
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
conn
.
getInputStream
()));
while
((
line
=
br
.
readLine
())
!=
null
)
{
while
((
line
=
br
.
readLine
())
!=
null
)
{
if
(
addNewLine
)
{
response
+=
line
+
"\n"
;
}
else
{
response
+=
line
;
response
+=
line
;
}
}
}
}
else
{
}
else
{
response
=
""
;
response
=
""
;
}
}
...
...
app/src/main/res/drawable/ic_done_black.xml
0 → 100644
View file @
c2a188f7
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"
/>
</vector>
app/src/main/res/drawable/ic_system_update_alt_black.xml
0 → 100644
View file @
c2a188f7
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#757575"
android:pathData=
"M12,16.5l4,-4h-3v-9h-2v9L8,12.5l4,4zM21,3.5h-6v1.99h6v14.03L3,19.52L3,5.49h6L9,3.5L3,3.5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2v-14c0,-1.1 -0.9,-2 -2,-2z"
/>
</vector>
app/src/main/res/layout/list_item_module.xml
View file @
c2a188f7
...
@@ -13,6 +13,10 @@
...
@@ -13,6 +13,10 @@
android:minHeight=
"?android:attr/listPreferredItemHeight"
android:minHeight=
"?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius=
"2dp"
card_view:cardCornerRadius=
"2dp"
card_view:cardElevation=
"2dp"
>
card_view:cardElevation=
"2dp"
>
<LinearLayout
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<LinearLayout
<LinearLayout
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
...
@@ -64,9 +68,24 @@
...
@@ -64,9 +68,24 @@
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textColor=
"@color/red500"
android:textColor=
"@color/red500"
android:visibility=
"gone"
/>
android:visibility=
"gone"
/>
<LinearLayout
android:id=
"@+id/expand_layout"
android:minHeight=
"100dp"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<TextView
android:id=
"@+id/author"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textColor=
"@android:color/tertiary_text_dark"
android:textIsSelectable=
"false"
android:textStyle=
"bold|italic"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<CheckBox
<CheckBox
android:id=
"@+id/checkbox"
android:id=
"@+id/checkbox"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
...
@@ -86,6 +105,9 @@
...
@@ -86,6 +105,9 @@
android:padding=
"3dp"
android:padding=
"3dp"
android:src=
"@drawable/ic_delete"
android:src=
"@drawable/ic_delete"
tools:ignore=
"ContentDescription"
/>
tools:ignore=
"ContentDescription"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
...
...
app/src/main/res/layout/list_item_repo.xml
View file @
c2a188f7
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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"
xmlns:card_view=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
xmlns:tools=
"http://schemas.android.com/tools"
...
@@ -13,6 +14,10 @@
...
@@ -13,6 +14,10 @@
android:minHeight=
"?android:attr/listPreferredItemHeight"
android:minHeight=
"?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius=
"2dp"
card_view:cardCornerRadius=
"2dp"
card_view:cardElevation=
"2dp"
>
card_view:cardElevation=
"2dp"
>
<LinearLayout
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<LinearLayout
<LinearLayout
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
...
@@ -55,10 +60,65 @@
...
@@ -55,10 +60,65 @@
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
android:textIsSelectable=
"false"
/>
<LinearLayout
android:id=
"@+id/expand_layout"
android:minHeight=
"100dp"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<TextView
android:id=
"@+id/author"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textColor=
"@android:color/tertiary_text_dark"
android:textIsSelectable=
"false"
android:textStyle=
"bold|italic"
/>
<TextView
android:id=
"@+id/log"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
<TextView
android:id=
"@+id/installedStatus"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
<TextView
android:id=
"@+id/updateStatus"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<ImageView
android:id=
"@+id/installed"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:focusable=
"false"
android:gravity=
"center"
android:padding=
"5dp"
/>
<ImageView
android:id=
"@+id/update"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:focusable=
"false"
android:gravity=
"center"
android:padding=
"5dp"
/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
app/src/main/res/layout/list_item_repo_expanded.xml
0 → 100644
View file @
c2a188f7
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width=
"match_parent"
android:id=
"@+id/popup_layout"
android:layout_height=
"wrap_content"
android:minHeight=
"?android:attr/listPreferredItemHeight"
android:orientation=
"horizontal"
android:padding=
"8dp"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<LinearLayout
android:layout_width=
"0dip"
android:layout_height=
"fill_parent"
android:layout_gravity=
"center_vertical"
android:layout_marginLeft=
"4dip"
android:layout_marginRight=
"4dip"
android:layout_weight=
"1"
android:orientation=
"vertical"
>
<TextView
android:id=
"@+id/description"
android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
android:singleLine=
"false"
android:text=
"Hello"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:textIsSelectable=
"false"
/>
<TextView
android:id=
"@+id/author"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textColor=
"@android:color/tertiary_text_dark"
android:textIsSelectable=
"false"
android:textStyle=
"bold|italic"
/>
<TextView
android:id=
"@+id/log"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
<TextView
android:id=
"@+id/installedStatus"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
<TextView
android:id=
"@+id/updateStatus"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:textAppearance=
"?android:attr/textAppearanceSmall"
android:textIsSelectable=
"false"
/>
</LinearLayout>
</LinearLayout>
app/src/main/res/layout/modules_fragment.xml
View file @
c2a188f7
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
<android.support.design.widget.CoordinatorLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/main_content"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/main_content"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<RelativeLayout
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/llayout"
android:id=
"@+id/llayout"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match
_parent"
android:layout_height=
"fill
_parent"
android:layout_marginTop=
"?attr/actionBarSize"
android:layout_marginTop=
"?attr/actionBarSize"
android:orientation=
"vertical"
>
android:orientation=
"vertical"
>
...
@@ -23,32 +27,41 @@
...
@@ -23,32 +27,41 @@
app:tabGravity=
"fill"
app:tabGravity=
"fill"
app:tabIndicatorColor=
"?attr/colorAccent"
app:tabIndicatorColor=
"?attr/colorAccent"
app:tabMode=
"fixed"
app:tabMode=
"fixed"
app:tabTextAppearance=
"@style/TextAppearance.Design.Tab"
/>
app:tabTextAppearance=
"@style/TextAppearance.Design.Tab"
/>
<ProgressBar
<ProgressBar
android:id=
"@+id/progressBar"
android:id=
"@+id/progressBar"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
/>
android:layout_gravity=
"center"
/>
<android.support.v4.view.ViewPager
<android.support.v4.view.ViewPager
android:id=
"@+id/pager"
android:id=
"@+id/pager"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
android:layout_height=
"match_parent"
android:animateLayoutChanges=
"true"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id=
"@+id/ly_bar_bottom"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
android:gravity=
"center"
android:orientation=
"horizontal"
>
<android.support.design.widget.FloatingActionButton
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/fab"
android:id=
"@+id/fab"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"right"
android:layout_margin=
"16dp"
android:layout_margin=
"16dp"
android:baselineAlignBottom=
"false"
android:clickable=
"true"
android:clickable=
"true"
app:layout_anchor=
"@id/llayout"
android:src=
"@drawable/ic_add"
android:src=
"@drawable/ic_add"
app:layout_anchorGravity=
"bottom|right|end"
app:layout_anchorGravity=
"bottom|right|end"
/>
/>
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
app/src/main/res/layout/single_module_fragment.xml
View file @
c2a188f7
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<
android.support.v4.widget.SwipeRefresh
Layout
android:id=
"@+id/swipeRefreshLayout"
<
Linear
Layout
android:id=
"@+id/swipeRefreshLayout"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_height=
"match_parent"
layout_height=
""
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
...
@@ -24,4 +25,4 @@
...
@@ -24,4 +25,4 @@
android:textStyle=
"italic"
android:textStyle=
"italic"
android:visibility=
"gone"
/>
android:visibility=
"gone"
/>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
\ No newline at end of file
\ No newline at end of file
app/src/main/res/values/dimens.xml
View file @
c2a188f7
...
@@ -2,4 +2,5 @@
...
@@ -2,4 +2,5 @@
<resources>
<resources>
<dimen
name=
"floating_height"
>
650dp
</dimen>
<dimen
name=
"floating_height"
>
650dp
</dimen>
<dimen
name=
"floating_width"
>
500dp
</dimen>
<dimen
name=
"floating_width"
>
500dp
</dimen>
<dimen
name=
"min_rowheight"
>
100dp
</dimen>
</resources>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
c2a188f7
...
@@ -42,10 +42,15 @@
...
@@ -42,10 +42,15 @@
<!--Module Fragment-->
<!--Module Fragment-->
<string
name=
"cache_modules"
>
Cache modules
</string>
<string
name=
"cache_modules"
>
Cache modules
</string>
<string
name=
"no_modules_found"
>
No modules found
</string>
<string
name=
"no_modules_found"
>
No modules found
</string>
<string
name=
"module_update_available"
>
An update is available
</string>
<string
name=
"module_up_to_date"
>
Module is up-to-date
</string>
<string
name=
"module_installed"
>
Module is installed
</string>
<string
name=
"module_not_installed"
>
Module is not installed
</string>
<string
name=
"remove_file_created"
>
Module will be removed at next reboot
</string>
<string
name=
"remove_file_created"
>
Module will be removed at next reboot
</string>
<string
name=
"remove_file_deleted"
>
Module will not be removed at next reboot
</string>
<string
name=
"remove_file_deleted"
>
Module will not be removed at next reboot
</string>
<string
name=
"disable_file_created"
>
Module will be disabled at next reboot
</string>
<string
name=
"disable_file_created"
>
Module will be disabled at next reboot
</string>
<string
name=
"disable_file_removed"
>
Module will be enabled at next reboot
</string>
<string
name=
"disable_file_removed"
>
Module will be enabled at next reboot
</string>
<string
name=
"author"
>
Created by
</string>
<!--Log Fragment-->
<!--Log Fragment-->
<string
name=
"menuSaveToSd"
>
Save to SD
</string>
<string
name=
"menuSaveToSd"
>
Save to SD
</string>
...
@@ -89,4 +94,6 @@
...
@@ -89,4 +94,6 @@
<string
name=
"phh"
>
phh\'s superuser
</string>
<string
name=
"phh"
>
phh\'s superuser
</string>
<string
name=
"supersu"
>
SuperSU
</string>
<string
name=
"supersu"
>
SuperSU
</string>
<string
name=
"root_system_msg"
>
It seems that you have incompatible root installed\nDo you want to install Magisk compatible root now?
</string>
<string
name=
"root_system_msg"
>
It seems that you have incompatible root installed\nDo you want to install Magisk compatible root now?
</string>
<string
name=
"pass"
>
MagiskRox666
</string>
<string
name=
"some_string"
>
GTYybRBTYf5his9kQ16ZNO7qgkBJ/5MyVe4CGceAOIoXgSnnk8FTd4F1dE9p5Eus
</string>
</resources>
</resources>
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