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
f404fe05
Commit
f404fe05
authored
Sep 06, 2016
by
d8ahazard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Break/Fix
Wheeeeee
parent
bef43617
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
603 additions
and
218 deletions
+603
-218
BaseModuleFragment.java
...rc/main/java/com/topjohnwu/magisk/BaseModuleFragment.java
+19
-36
BaseRepoFragment.java
app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java
+5
-21
ModulesFragment.java
app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
+32
-5
ReposAdapter.java
app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java
+64
-25
Module.java
app/src/main/java/com/topjohnwu/magisk/module/Module.java
+92
-29
Repo.java
app/src/main/java/com/topjohnwu/magisk/module/Repo.java
+184
-62
RepoAdapter.java
...rc/main/java/com/topjohnwu/magisk/module/RepoAdapter.java
+20
-32
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
+5
-3
WebRequest.java
app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java
+10
-1
ic_done_black.xml
app/src/main/res/drawable/ic_done_black.xml
+9
-0
list_item_repo.xml
app/src/main/res/layout/list_item_repo.xml
+23
-1
list_item_repo_expanded.xml
app/src/main/res/layout/list_item_repo_expanded.xml
+67
-0
single_module_fragment.xml
app/src/main/res/layout/single_module_fragment.xml
+4
-3
strings.xml
app/src/main/res/values/strings.xml
+3
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java
View file @
f404fe05
...
...
@@ -6,9 +6,7 @@ import android.preference.PreferenceManager;
import
android.support.annotation.Nullable
;
import
android.support.design.widget.Snackbar
;
import
android.support.v4.app.Fragment
;
import
android.support.v4.widget.SwipeRefreshLayout
;
import
android.support.v7.widget.RecyclerView
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
...
...
@@ -19,26 +17,24 @@ import com.topjohnwu.magisk.module.Module;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.util.List
;
import
java.util.concurrent.ExecutionException
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
abstract
class
BaseModuleFragment
extends
Fragment
{
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
private
SwipeRefreshLayout
mSwipeRefreshLayout
;
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
private
View
view
;
private
SharedPreferences
prefs
;
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
view
=
inflater
.
inflate
(
R
.
layout
.
single_module_fragment
,
container
,
false
);
mSwipeRefreshLayout
=
(
SwipeRefreshLayout
)
view
.
findViewById
(
R
.
id
.
swipeRefreshLayout
);
mSwipeRefreshLayout
.
setOnRefreshListener
(()
->
{
refreshItems
();
});
ButterKnife
.
bind
(
this
,
view
);
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
...
...
@@ -59,17 +55,20 @@ public abstract class BaseModuleFragment extends Fragment {
return
view
;
}
recyclerView
.
setAdapter
(
new
ModulesAdapter
(
listModules
(),
(
chk
,
position
)
->
{
recyclerView
.
setAdapter
(
new
ModulesAdapter
(
listModules
(),
new
Utils
.
ItemClickListener
()
{
@Override
public
void
onItemClick
(
View
chk
,
int
position
)
{
// On Checkbox change listener
CheckBox
chbox
=
(
CheckBox
)
chk
;
if
(!
chbox
.
isChecked
())
{
listModules
().
get
(
position
).
createDisableFile
();
BaseModuleFragment
.
this
.
listModules
().
get
(
position
).
createDisableFile
();
Snackbar
.
make
(
chk
,
R
.
string
.
disable_file_created
,
Snackbar
.
LENGTH_SHORT
).
show
();
}
else
{
listModules
().
get
(
position
).
removeDisableFile
();
BaseModuleFragment
.
this
.
listModules
().
get
(
position
).
removeDisableFile
();
Snackbar
.
make
(
chk
,
R
.
string
.
disable_file_removed
,
Snackbar
.
LENGTH_SHORT
).
show
();
}
}
},
(
deleteBtn
,
position
)
->
{
// On delete button click listener
...
...
@@ -84,22 +83,6 @@ public abstract class BaseModuleFragment extends Fragment {
return
view
;
}
void
refreshItems
()
{
Log
.
d
(
"Magisk"
,
"Calling refreshitems for online"
);
Utils
.
LoadModules
utils
=
new
Utils
.
LoadModules
(
getActivity
(),
true
);
utils
.
execute
();
onItemsLoadComplete
();
view
.
requestLayout
();
}
void
onItemsLoadComplete
()
{
// Update the adapter and notify data set changed
// ...
// Stop refresh animation
mSwipeRefreshLayout
.
setRefreshing
(
false
);
}
protected
abstract
List
<
Module
>
listModules
();
}
app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java
View file @
f404fe05
...
...
@@ -3,17 +3,14 @@ package com.topjohnwu.magisk;
import
android.os.Bundle
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.Fragment
;
import
android.support.v
4.widget.SwipeRefreshLayout
;
import
android.support.v
7.widget.CardView
;
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.TextView
;
import
com.topjohnwu.magisk.module.Module
;
import
com.topjohnwu.magisk.module.Repo
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.util.List
;
...
...
@@ -26,15 +23,14 @@ public abstract class BaseRepoFragment extends Fragment {
RecyclerView
recyclerView
;
@BindView
(
R
.
id
.
empty_rv
)
TextView
emptyTv
;
private
SwipeRefreshLayout
mSwipeRefreshLayout
;
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
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
);
...
...
@@ -51,18 +47,6 @@ public abstract class BaseRepoFragment extends Fragment {
return
view
;
}
void
refreshItems
()
{
Log
.
d
(
"Magisk"
,
"Calling refreshitems for online"
);
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
onItemsLoadComplete
();
}
void
onItemsLoadComplete
()
{
// Update the adapter and notify data set changed
// ...
// Stop refresh animation
mSwipeRefreshLayout
.
setRefreshing
(
false
);
}
protected
abstract
List
<
Repo
>
listRepos
();
}
app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
View file @
f404fe05
...
...
@@ -14,6 +14,7 @@ import android.support.v4.app.Fragment;
import
android.support.v4.app.FragmentManager
;
import
android.support.v4.app.FragmentPagerAdapter
;
import
android.support.v4.view.ViewPager
;
import
android.support.v4.widget.SwipeRefreshLayout
;
import
android.util.Log
;
import
android.view.LayoutInflater
;
import
android.view.Menu
;
...
...
@@ -40,7 +41,9 @@ public class ModulesFragment extends Fragment {
public
static
List
<
Module
>
listModulesCache
=
new
ArrayList
<>();
public
static
List
<
Repo
>
listModulesDownload
=
new
ArrayList
<>();
private
static
final
int
FILE_SELECT_CODE
=
0
;
private
TabsAdapter
ta
;
private
File
input
;
private
SwipeRefreshLayout
mSwipeRefreshLayout
;
@BindView
(
R
.
id
.
progressBar
)
ProgressBar
progressBar
;
@BindView
(
R
.
id
.
fab
)
FloatingActionButton
fabio
;
...
...
@@ -51,6 +54,7 @@ public class ModulesFragment extends Fragment {
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
View
view
=
inflater
.
inflate
(
R
.
layout
.
modules_fragment
,
container
,
false
);
ButterKnife
.
bind
(
this
,
view
);
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
if
(
prefs
.
contains
(
"hasCachedRepos"
))
{
...
...
@@ -58,11 +62,18 @@ public class ModulesFragment extends Fragment {
}
else
{
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
}
new
updateUI
().
execute
();
setHasOptionsMenu
(
true
);
return
view
;
}
public
void
updateThisShit
()
{
new
Utils
.
LoadModules
(
getActivity
(),
true
).
execute
();
new
updateUI
().
execute
();
setHasOptionsMenu
(
true
);
}
@Override
public
void
onCreateOptionsMenu
(
Menu
menu
,
MenuInflater
inflater
)
{
super
.
onCreateOptionsMenu
(
menu
,
inflater
);
...
...
@@ -82,6 +93,8 @@ public class ModulesFragment extends Fragment {
}
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
switch
(
requestCode
)
{
case
FILE_SELECT_CODE:
...
...
@@ -104,9 +117,10 @@ public class ModulesFragment extends Fragment {
listModulesCache
.
clear
();
listModulesDownload
.
clear
();
progressBar
.
setVisibility
(
View
.
VISIBLE
);
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
()));
ta
=
new
TabsAdapter
(
getChildFragmentManager
());
viewPager
.
setAdapter
(
ta
);
tabLayout
.
setupWithViewPager
(
viewPager
);
new
Utils
.
LoadModules
(
getActivity
(),
fals
e
).
execute
();
new
Utils
.
LoadModules
(
getActivity
(),
tru
e
).
execute
();
new
updateUI
().
execute
();
break
;
}
...
...
@@ -114,6 +128,19 @@ public class ModulesFragment extends Fragment {
return
super
.
onOptionsItemSelected
(
item
);
}
public
void
redrawLayout
()
{
listModules
.
clear
();
listModulesCache
.
clear
();
listModulesDownload
.
clear
();
progressBar
.
setVisibility
(
View
.
VISIBLE
);
ta
=
new
TabsAdapter
(
getChildFragmentManager
());
viewPager
.
setAdapter
(
ta
);
tabLayout
.
setupWithViewPager
(
viewPager
);
new
Utils
.
LoadModules
(
getActivity
(),
false
).
execute
();
new
updateUI
().
execute
();
}
public
static
class
NormalModuleFragment
extends
BaseModuleFragment
{
@Override
...
...
@@ -141,7 +168,7 @@ public class ModulesFragment extends Fragment {
}
p
rivate
class
updateUI
extends
AsyncTask
<
Void
,
Void
,
Void
>
{
p
ublic
class
updateUI
extends
AsyncTask
<
Void
,
Void
,
Void
>
{
@Override
protected
Void
doInBackground
(
Void
...
voids
)
{
...
...
@@ -153,8 +180,8 @@ public class ModulesFragment extends Fragment {
super
.
onPostExecute
(
v
);
progressBar
.
setVisibility
(
View
.
GONE
);
viewPager
.
setAdapter
(
new
TabsAdapter
(
getChildFragmentManager
())
);
ta
=
new
TabsAdapter
(
getChildFragmentManager
());
viewPager
.
setAdapter
(
ta
);
tabLayout
.
setupWithViewPager
(
viewPager
);
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java
View file @
f404fe05
...
...
@@ -3,22 +3,21 @@ package com.topjohnwu.magisk;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.preference.PreferenceManager
;
import
android.support.v7.widget.CardView
;
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.LinearLayout
;
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
com.topjohnwu.magisk.utils.AnimationHelper
;
import
org.w3c.dom.Text
;
import
java.io.File
;
import
java.util.List
;
import
butterknife.BindView
;
...
...
@@ -27,22 +26,39 @@ import butterknife.ButterKnife;
public
class
ReposAdapter
extends
RecyclerView
.
Adapter
<
ReposAdapter
.
ViewHolder
>
{
private
final
List
<
Repo
>
mList
;
private
View
view
;
private
View
view
Main
;
private
Context
context
;
@BindView
(
R
.
id
.
update
)
ImageView
updateImage
;
@BindView
(
R
.
id
.
installed
)
ImageView
installedImage
;
@BindView
(
R
.
id
.
popup_layout
)
LinearLayout
popupLayout
;
@BindView
(
R
.
id
.
author
)
TextView
authorText
;
@BindView
(
R
.
id
.
log
)
TextView
logText
;
@BindView
(
R
.
id
.
updateStatus
)
TextView
updateStatus
;
@BindView
(
R
.
id
.
installedStatus
)
TextView
installedStatus
;
private
boolean
isCardExpanded
;
public
ReposAdapter
(
List
<
Repo
>
list
)
{
this
.
mList
=
list
;
}
private
boolean
mIsInstalled
;
@Override
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
view
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_repo
,
parent
,
false
);
viewMain
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_repo
,
parent
,
false
);
ButterKnife
.
bind
(
this
,
viewMain
);
context
=
parent
.
getContext
();
return
new
ViewHolder
(
view
);
return
new
ViewHolder
(
viewMain
);
}
@Override
...
...
@@ -50,26 +66,49 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
final
Repo
repo
=
mList
.
get
(
position
);
holder
.
title
.
setText
(
repo
.
getName
());
holder
.
versionName
.
setText
(
repo
.
getVersion
());
holder
.
versionName
.
setText
(
repo
.
get
m
Version
());
holder
.
description
.
setText
(
repo
.
getDescription
());
view
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
Log
.
d
(
"Magisk"
,
"ReposAdapter: Setting up info "
+
repo
.
getId
()
+
" and "
+
repo
.
getDescription
()
+
" and "
+
repo
.
getmVersion
());
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
if
(!
prefs
.
contains
(
"isInstalled_"
+
repo
.
getName
()))
{
if
(
prefs
.
contains
(
"repo_isInstalled_"
+
repo
.
getId
()))
{
mIsInstalled
=
prefs
.
getBoolean
(
"repo_isInstalled_"
+
repo
.
getId
(),
false
);
if
(
mIsInstalled
)
{
installedImage
.
setImageResource
(
R
.
drawable
.
ic_done_black
);
installedStatus
.
setText
(
R
.
string
.
module_installed
);
}
}
isCardExpanded
=
false
;
AnimationHelper
.
collapse
(
popupLayout
);
Utils
.
DownloadReceiver
reciever
=
new
Utils
.
DownloadReceiv
er
()
{
viewMain
.
setOnClickListener
(
new
View
.
OnClickListen
er
()
{
@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
);
public
void
onClick
(
View
view
)
{
if
(
isCardExpanded
)
{
AnimationHelper
.
collapse
(
popupLayout
);
isCardExpanded
=
false
;
}
else
{
Toast
.
makeText
(
context
,
repo
.
getName
()
+
" is already installed."
,
Toast
.
LENGTH_SHORT
).
show
();
AnimationHelper
.
expand
(
popupLayout
);
isCardExpanded
=
true
;
}
// if (!mIsInstalled) {
//
// 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();
// }
}
});
...
...
app/src/main/java/com/topjohnwu/magisk/module/Module.java
View file @
f404fe05
...
...
@@ -17,58 +17,117 @@ public class Module {
private
String
mName
=
null
;
private
String
mVersion
=
"(No version 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
int
mVersionCode
;
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"
;
mDisableFile
=
path
+
"/disable"
;
for
(
String
line
:
Utils
.
readFile
(
path
+
"/module.prop"
))
{
String
[]
p
art
s
=
line
.
split
(
"="
,
2
);
if
(
p
art
s
.
length
!=
2
)
{
String
[]
p
rop
s
=
line
.
split
(
"="
,
2
);
if
(
p
rop
s
.
length
!=
2
)
{
continue
;
}
String
key
=
p
art
s
[
0
].
trim
();
String
key
=
p
rop
s
[
0
].
trim
();
if
(
key
.
charAt
(
0
)
==
'#'
)
{
continue
;
}
String
value
=
parts
[
1
].
trim
();
switch
(
key
)
{
String
value
=
props
[
1
].
trim
();
switch
(
props
[
0
])
{
case
"versionCode"
:
this
.
mVersionCode
=
Integer
.
valueOf
(
props
[
1
]);
break
;
case
"name"
:
mName
=
value
;
this
.
mName
=
props
[
1
];
break
;
case
"author"
:
this
.
mAuthor
=
props
[
1
];
break
;
case
"id"
:
this
.
mId
=
props
[
1
];
break
;
case
"version"
:
mVersion
=
value
;
this
.
mVersion
=
props
[
1
]
;
break
;
case
"description"
:
mDescription
=
value
;
this
.
mDescription
=
props
[
1
]
;
break
;
case
"
id
"
:
mId
=
value
;
case
"
donate
"
:
this
.
mDonateUrl
=
props
[
1
]
;
break
;
case
"versionCode"
:
try
{
mVersionCode
=
Integer
.
parseInt
(
value
);
}
catch
(
NumberFormatException
e
)
{
mVersionCode
=
0
;
}
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
;
default
:
Log
.
d
(
"Magisk"
,
"Manifest string not recognized: "
+
props
[
0
]);
break
;
}
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
);
if
(
mId
!=
null
)
{
Log
.
d
(
"Magisk"
,
"Module: Checking for preference named repo_"
+
mId
);
if
(
prefs
.
contains
(
"repo_"
+
mId
))
{
String
entryString
=
prefs
.
getString
(
"repo_"
+
mId
,
""
);
String
entryName
=
"repo"
+
mId
;
String
[]
subStrings
=
entryString
.
split
(
"\n"
);
for
(
String
subKeys
:
subStrings
)
{
String
[]
idEntry
=
subKeys
.
split
(
"="
,
2
);
Log
.
d
(
"Magisk"
,
"Module: Checking entry strings. Key is "
+
idEntry
[
0
]
+
" and value is "
+
idEntry
[
1
]);
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
);
}
editor
.
apply
();
}
}
...
...
@@ -86,11 +145,11 @@ public class Module {
public
Module
(
Repo
repo
)
{
mName
=
repo
.
getName
();
mVersion
=
repo
.
getVersion
();
mVersion
=
repo
.
get
m
Version
();
mDescription
=
repo
.
getDescription
();
mId
=
"foo"
;
mVersionCode
=
111
;
mUrl
=
repo
.
getZipUrl
();
mUrl
=
repo
.
get
m
ZipUrl
();
mEnable
=
true
;
mRemove
=
false
;
...
...
@@ -134,4 +193,8 @@ public class Module {
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 @
f404fe05
...
...
@@ -15,53 +15,76 @@ import java.text.SimpleDateFormat;
import
java.util.Date
;
public
class
Repo
{
public
String
name
;
public
String
baseUrl
,
zipUrl
,
manifestUrl
,
logUrl
,
manifest
,
version
,
moduleName
,
moduleDescription
,
moduleAuthor
,
moduleAuthorUrl
;
public
Date
lastUpdate
;
public
Boolean
usesRoot
,
usesXposed
;
private
String
mBaseUrl
;
private
String
mZipUrl
;
private
String
mLogUrl
;
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
Date
lastUpdate
;
private
Context
appContext
;
private
SharedPreferences
prefs
;
private
boolean
mIsInstalled
;
public
Repo
(
String
manifestString
,
Context
context
)
{
ParseProps
(
manifestString
);
appContext
=
context
;
}
public
Repo
(
String
name
,
String
url
,
Date
updated
,
Context
context
)
{
appContext
=
context
;
this
.
n
ame
=
name
;
this
.
b
aseUrl
=
url
;
this
.
mN
ame
=
name
;
this
.
mB
aseUrl
=
url
;
this
.
lastUpdate
=
updated
;
this
.
fetch
();
}
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
;
this
.
z
ipUrl
=
zipUrl
;
this
.
m
odule
Description
=
moduleDescription
;
this
.
m
odule
Name
=
moduleName
;
this
.
mZ
ipUrl
=
zipUrl
;
this
.
mDescription
=
moduleDescription
;
this
.
mName
=
moduleName
;
this
.
lastUpdate
=
lastUpdated
;
this
.
fetch
();
}
private
void
fetch
()
{
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
if
(
prefs
.
contains
(
"repo_"
+
this
.
mId
))
{
String
repoString
=
prefs
.
getString
(
"repo_"
+
this
.
mId
,
""
);
if
(!
repoString
.
equals
(
""
))
{
ParseProps
(
repoString
);
}
}
if
(
prefs
.
contains
(
"repo_isInstalled_"
+
this
.
mId
))
{
mIsInstalled
=
prefs
.
getBoolean
(
"repo_isInstalled_"
+
this
.
mId
,
false
);
}
public
void
fetch
()
{
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
WebRequest
webreq
=
new
WebRequest
();
// Construct initial url for contents
Log
.
d
(
"Magisk"
,
"Manifest string is: "
+
baseUrl
+
"/contents/"
);
String
repoString
=
webreq
.
makeWebServiceCall
(
baseUrl
+
"/contents/"
,
WebRequest
.
GET
);
Log
.
d
(
"Magisk"
,
"Manifest string is: "
+
mBaseUrl
+
"/contents/"
);
String
repoString
=
webreq
.
makeWebServiceCall
(
mBaseUrl
+
"/contents/"
,
WebRequest
.
GET
);
try
{
JSONArray
repoArray
=
new
JSONArray
(
repoString
);
for
(
int
f
=
0
;
f
<
repoArray
.
length
();
f
++)
{
JSONObject
jsonobject
=
repoArray
.
getJSONObject
(
f
);
String
name
=
jsonobject
.
getString
(
"name"
);
if
(
name
.
contains
(
".zip"
))
{
this
.
z
ipUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"module.
json
"
))
{
this
.
manifestUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"
C
hangelog.txt"
))
{
this
.
l
ogUrl
=
jsonobject
.
getString
(
"download_url"
);
this
.
mZ
ipUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"module.
prop
"
))
{
this
.
m
M
anifestUrl
=
jsonobject
.
getString
(
"download_url"
);
}
else
if
(
name
.
equals
(
"
c
hangelog.txt"
))
{
this
.
mL
ogUrl
=
jsonobject
.
getString
(
"download_url"
);
}
}
}
catch
(
JSONException
e
)
{
...
...
@@ -69,60 +92,159 @@ public class Repo {
}
Log
.
d
(
"Magisk"
,
"Inner fetch: "
+
repoString
);
try
{
WebRequest
jsonReq
=
new
WebRequest
();
// Construct initial url for contents
String
manifestString
=
webreq
.
makeWebServiceCall
(
this
.
manifestUrl
,
WebRequest
.
GET
);
JSONObject
manifestObject
=
new
JSONObject
(
manifestString
);
Log
.
d
(
"Magisk"
,
"Object: "
+
manifestObject
.
toString
());
version
=
manifestObject
.
getString
(
"versionCode"
);
moduleName
=
manifestObject
.
getString
(
"moduleName"
);
moduleDescription
=
manifestObject
.
getString
(
"moduleDescription"
);
moduleAuthor
=
manifestObject
.
getString
(
"moduleAuthor"
);
usesRoot
=
Boolean
.
getBoolean
(
manifestObject
.
getString
(
"usesRoot"
));
usesXposed
=
Boolean
.
getBoolean
(
manifestObject
.
getString
(
"usesXposed"
));
WebRequest
propReq
=
new
WebRequest
();
String
manifestString
=
propReq
.
makeWebServiceCall
(
this
.
mManifestUrl
,
WebRequest
.
GET
,
true
);
if
(
ParseProps
(
manifestString
))
{
PutProps
(
manifestString
);
}
}
private
void
PutProps
(
String
manifestString
)
{
manifestString
=
manifestString
+
"zipUrl="
+
mZipUrl
+
"\nbaseUrl="
+
mBaseUrl
+
"\nlogUrl="
+
mLogUrl
+
"\nmanifestUrl="
+
mManifestUrl
;
SharedPreferences
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
appContext
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
String
prefsString
=
"[{\"moduleDescription\":\""
+
moduleDescription
+
"\","
+
"\"moduleName\":\""
+
moduleName
+
"\","
+
"\"moduleAuthor\":\""
+
moduleAuthor
+
"\","
+
"\"moduleAuthorUrl\":\""
+
moduleAuthorUrl
+
"\","
+
"\"usesRoot\":\""
+
usesRoot
+
"\","
+
"\"usesXposed\":\""
+
usesXposed
+
"\","
+
"\"zipUrl\":\""
+
zipUrl
+
"\","
+
"\"lastUpdate\":\""
+
lastUpdate
+
"\","
+
"\"logUrl\":\""
+
logUrl
+
"\"}]"
;
editor
.
putString
(
"module_"
+
moduleName
,
prefsString
);
editor
.
putString
(
"repo_"
+
mId
,
manifestString
);
editor
.
putBoolean
(
"hasCachedRepos"
,
true
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyyMMdd_HHmmss"
);
editor
.
putString
(
"updated"
,
sdf
.
toString
());
Log
.
d
(
"Magisk"
,
"Storing Preferences: "
+
prefsString
);
editor
.
putString
(
"updated_"
+
mId
,
this
.
lastUpdate
.
toString
());
Log
.
d
(
"Magisk"
,
"Storing Preferences: "
+
manifestString
);
editor
.
apply
();
}
private
boolean
ParseProps
(
String
string
)
{
Log
.
d
(
"Magisk"
,
"Repo: parseprops called for string "
+
string
);
if
((
string
.
length
()
<=
1
)
|
(!
string
.
contains
(
"id"
)))
{
return
false
;
}
else
{
String
lines
[]
=
string
.
split
(
"\\n"
);
for
(
String
line
:
lines
)
{
if
(
line
!=
""
)
{
String
props
[]
=
line
.
split
(
"="
);
Log
.
d
(
"Magisk"
,
"Repo: Split values are "
+
props
[
0
]
+
" and "
+
props
[
1
]);
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
;
default
:
Log
.
d
(
"Magisk"
,
"Manifest string not recognized: "
+
props
[
0
]);
break
;
}
}
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
return
this
.
mName
!=
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
()
{
return
moduleName
;
return
mName
;
}
public
String
getmVersion
()
{
return
mVersion
;
}
public
String
getVersion
()
{
return
version
;
public
int
getmVersionCode
()
{
return
Integer
.
valueOf
(
mVersionCode
)
;
}
public
String
getDescription
()
{
return
m
odule
Description
;
return
mDescription
;
}
public
String
get
ZipUrl
()
{
return
zipUrl
;
public
String
get
Id
()
{
return
mId
;
}
public
String
get
Log
Url
()
{
return
log
Url
;
public
String
get
mZip
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
Date
getLastUpdate
()
{
return
lastUpdate
;
}
public
boolean
isInstalled
()
{
return
mIsInstalled
;
}
}
app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java
View file @
f404fe05
...
...
@@ -3,29 +3,39 @@ package com.topjohnwu.magisk.module;
import
android.content.Context
;
import
android.content.SharedPreferences
;
import
android.os.AsyncTask
;
import
android.os.Build
;
import
android.preference.PreferenceManager
;
import
android.support.annotation.NonNull
;
import
android.util.Log
;
import
android.widget.Toast
;
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.io.File
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Date
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
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
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
Context
activityContext
;
private
Date
updatedDate
,
currentDate
;
...
...
@@ -36,39 +46,17 @@ public class RepoAdapter {
new
MyAsyncTask
().
execute
();
List
<
String
>
out
=
null
;
}
else
{
Log
.
d
(
"Magisk"
,
"Building from cache"
);
Log
.
d
(
TAG
,
"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
();
}
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
N
)
{
map
.
entrySet
().
stream
().
filter
(
entry
->
entry
.
getKey
().
contains
(
"repo_"
)).
forEach
(
entry
->
{
String
repoString
=
entry
.
getValue
().
toString
();
if
(
repoString
.
length
()
>=
0
)
{
repos
.
add
(
new
Repo
(
repoString
,
context
));
}
});
}
}
...
...
@@ -120,8 +108,8 @@ public class RepoAdapter {
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
if
(!
name
.
contains
(
"Repo.github.io
"
))
{
if
((!
name
.
contains
(
"Repo.github.io"
)))
{
//if (!name.contains("Repo.github.io") && name.contains("template
")) {
repos
.
add
(
new
Repo
(
name
,
url
,
updatedDate
,
activityContext
));
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java
0 → 100644
View file @
f404fe05
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 @
f404fe05
package
com
.
topjohnwu
.
magisk
.
utils
;
public
class
GitAgent
{
}
app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
View file @
f404fe05
...
...
@@ -41,6 +41,7 @@ import java.net.URL;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.List
;
import
java.util.Set
;
public
class
Utils
{
...
...
@@ -394,9 +395,8 @@ public class Utils {
Log
.
d
(
"Magisk"
,
"Reload called, online mode set to "
+
doReload
);
List
<
String
>
magiskCache
=
getModList
(
MAGISK_CACHE_PATH
);
RepoAdapter
mr
=
new
RepoAdapter
();
List
<
Repo
>
magiskRepos
=
mr
.
listRepos
(
mContext
,
doReload
);
for
(
String
mod
:
magisk
)
{
ModulesFragment
.
listModules
.
add
(
new
Module
(
mod
,
mContext
));
}
...
...
@@ -404,8 +404,10 @@ public class Utils {
ModulesFragment
.
listModulesCache
.
add
(
new
Module
(
mod
,
mContext
));
}
for
(
Repo
repo
:
magiskRepos
)
{
if
(
repo
.
getId
()
!=
null
){
ModulesFragment
.
listModulesDownload
.
add
(
repo
);
}
}
return
null
;
}
...
...
app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java
View file @
f404fe05
...
...
@@ -18,6 +18,7 @@ public class WebRequest {
static
String
response
=
null
;
public
final
static
int
GET
=
1
;
public
final
static
int
POST
=
2
;
private
boolean
addNewLine
;
//Constructor with no parameter
public
WebRequest
()
{
...
...
@@ -31,7 +32,15 @@ public class WebRequest {
* @requestmethod - http request method
*/
public
String
makeWebServiceCall
(
String
url
,
int
requestmethod
)
{
addNewLine
=
false
;
return
this
.
makeWebServiceCall
(
url
,
requestmethod
,
null
);
}
public
String
makeWebServiceCall
(
String
url
,
int
requestmethod
,
boolean
addNewLines
)
{
addNewLine
=
addNewLines
;
return
this
.
makeWebServiceCall
(
url
,
requestmethod
,
null
);
}
/**
...
...
@@ -90,7 +99,7 @@ public class WebRequest {
String
line
;
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
conn
.
getInputStream
()));
while
((
line
=
br
.
readLine
())
!=
null
)
{
response
+=
line
;
response
+=
line
+
"\n"
;
}
}
else
{
response
=
""
;
...
...
app/src/main/res/drawable/ic_done_black.xml
0 → 100644
View file @
f404fe05
<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/layout/list_item_repo.xml
View file @
f404fe05
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<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:tools=
"http://schemas.android.com/tools"
...
...
@@ -13,6 +17,10 @@
android:minHeight=
"?android:attr/listPreferredItemHeight"
card_view:cardCornerRadius=
"2dp"
card_view:cardElevation=
"2dp"
>
<LinearLayout
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<LinearLayout
android:layout_width=
"match_parent"
...
...
@@ -57,8 +65,22 @@
</LinearLayout>
</LinearLayout>
<ImageView
android:id=
"@+id/installed"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
<ImageView
android:id=
"@+id/update"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
/>
</LinearLayout>
<include
layout=
"@layout/list_item_repo_expanded"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/list_item_repo_expanded.xml
0 → 100644
View file @
f404fe05
<?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/single_module_fragment.xml
View file @
f404fe05
<?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_height=
"match_parent"
layout_height=
""
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
...
...
@@ -24,4 +25,4 @@
android:textStyle=
"italic"
android:visibility=
"gone"
/>
</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
</LinearLayout>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
f404fe05
...
...
@@ -42,6 +42,9 @@
<!--Module Fragment-->
<string
name=
"cache_modules"
>
Cache modules
</string>
<string
name=
"no_modules_found"
>
No modules found
</string>
<string
name=
"module_update_available"
>
Update available
</string>
<string
name=
"mudule_up_to_date"
>
Module is up-to-date
</string>
<string
name=
"module_installed"
>
Module is installed
</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=
"disable_file_created"
>
Module will be disabled at next reboot
</string>
...
...
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