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
356065d1
Commit
356065d1
authored
Jul 23, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite SuLogAdapter
parent
76e7c562
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
200 deletions
+138
-200
build.gradle
app/build.gradle
+0
-1
SuLogFragment.java
app/src/main/java/com/topjohnwu/magisk/SuLogFragment.java
+5
-6
SectionedAdapter.java
.../java/com/topjohnwu/magisk/adapters/SectionedAdapter.java
+15
-0
SuLogAdapter.java
...main/java/com/topjohnwu/magisk/adapters/SuLogAdapter.java
+87
-134
SuDatabaseHelper.java
.../java/com/topjohnwu/magisk/database/SuDatabaseHelper.java
+30
-15
SuLogEntry.java
.../main/java/com/topjohnwu/magisk/superuser/SuLogEntry.java
+1
-44
No files found.
app/build.gradle
View file @
356065d1
...
...
@@ -53,7 +53,6 @@ dependencies {
implementation
'com.android.support:design:26.0.0-beta2'
implementation
'com.android.support:support-v4:26.0.0-beta2'
implementation
'com.jakewharton:butterknife:8.7.0'
implementation
'com.thoughtbot:expandablerecyclerview:1.4'
implementation
'us.feras.mdv:markdownview:1.1.0'
implementation
'org.bouncycastle:bcprov-jdk15on:1.57'
implementation
'org.bouncycastle:bcpkix-jdk15on:1.57'
...
...
app/src/main/java/com/topjohnwu/magisk/SuLogFragment.java
View file @
356065d1
...
...
@@ -13,9 +13,6 @@ import android.widget.TextView;
import
com.topjohnwu.magisk.adapters.SuLogAdapter
;
import
com.topjohnwu.magisk.components.Fragment
;
import
com.topjohnwu.magisk.superuser.SuLogEntry
;
import
java.util.List
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
...
...
@@ -28,6 +25,7 @@ public class SuLogFragment extends Fragment {
private
Unbinder
unbinder
;
private
MagiskManager
magiskManager
;
private
SuLogAdapter
adapter
;
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
...
...
@@ -48,6 +46,8 @@ public class SuLogFragment extends Fragment {
View
v
=
inflater
.
inflate
(
R
.
layout
.
fragment_su_log
,
container
,
false
);
unbinder
=
ButterKnife
.
bind
(
this
,
v
);
magiskManager
=
getApplication
();
adapter
=
new
SuLogAdapter
(
magiskManager
.
suDB
);
recyclerView
.
setAdapter
(
adapter
);
updateList
();
...
...
@@ -55,13 +55,12 @@ public class SuLogFragment extends Fragment {
}
private
void
updateList
()
{
List
<
SuLogEntry
>
logs
=
magiskManager
.
suDB
.
getLogList
();
adapter
.
notifyDBChanged
();
if
(
logs
.
size
()
==
0
)
{
if
(
adapter
.
getSectionCount
()
==
0
)
{
emptyRv
.
setVisibility
(
View
.
VISIBLE
);
recyclerView
.
setVisibility
(
View
.
GONE
);
}
else
{
recyclerView
.
setAdapter
(
new
SuLogAdapter
(
logs
).
getAdapter
());
emptyRv
.
setVisibility
(
View
.
GONE
);
recyclerView
.
setVisibility
(
View
.
VISIBLE
);
}
...
...
app/src/main/java/com/topjohnwu/magisk/adapters/SectionedAdapter.java
View file @
356065d1
...
...
@@ -48,6 +48,21 @@ public abstract class SectionedAdapter<S extends RecyclerView.ViewHolder, C exte
return
0
;
}
protected
int
getSectionPosition
(
int
section
)
{
return
getItemPosition
(
section
,
-
1
);
}
protected
int
getItemPosition
(
int
section
,
int
position
)
{
int
realPosition
=
0
;
// Previous sections
for
(
int
i
=
0
;
i
<
section
;
++
i
)
{
realPosition
+=
getItemCount
(
i
)
+
1
;
}
// Current section
realPosition
+=
position
+
1
;
return
realPosition
;
}
private
PositionInfo
getPositionInfo
(
int
position
)
{
int
section
=
0
;
while
(
true
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/adapters/SuLogAdapter.java
View file @
356065d1
package
com
.
topjohnwu
.
magisk
.
adapters
;
import
android.
content.Context
;
import
android.
database.Cursor
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.LayoutInflater
;
import
android.view.View
;
...
...
@@ -10,147 +10,125 @@ import android.view.animation.RotateAnimation;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter
;
import
com.thoughtbot.expandablerecyclerview.models.ExpandableGroup
;
import
com.thoughtbot.expandablerecyclerview.viewholders.ChildViewHolder
;
import
com.thoughtbot.expandablerecyclerview.viewholders.GroupViewHolder
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.components.ExpandableViewHolder
;
import
com.topjohnwu.magisk.database.SuDatabaseHelper
;
import
com.topjohnwu.magisk.superuser.SuLogEntry
;
import
java.util.
ArrayList
;
import
java.util.
Collections
;
import
java.util.HashSet
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
SuLogAdapter
{
public
class
SuLogAdapter
extends
SectionedAdapter
<
SuLogAdapter
.
SectionHolder
,
SuLogAdapter
.
LogViewHolder
>
{
private
ExpandableAdapter
adapter
;
private
Set
<
SuLogEntry
>
expandList
=
new
HashSet
<>();
public
SuLogAdapter
(
List
<
SuLogEntry
>
list
)
{
// Separate the logs with date
Map
<
String
,
List
<
SuLogEntry
>>
logEntryMap
=
new
LinkedHashMap
<>();
List
<
SuLogEntry
>
group
;
for
(
SuLogEntry
log
:
list
)
{
String
date
=
log
.
getDateString
();
group
=
logEntryMap
.
get
(
date
);
if
(
group
==
null
)
{
group
=
new
ArrayList
<>();
logEntryMap
.
put
(
date
,
group
);
}
group
.
add
(
log
);
}
// Then format them into expandable groups
List
<
LogGroup
>
logEntryGroups
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
List
<
SuLogEntry
>>
entry
:
logEntryMap
.
entrySet
())
{
logEntryGroups
.
add
(
new
LogGroup
(
entry
.
getKey
(),
entry
.
getValue
()));
}
adapter
=
new
ExpandableAdapter
(
logEntryGroups
);
private
List
<
List
<
Integer
>>
logEntryList
;
private
Set
<
Integer
>
itemExpanded
,
sectionExpanded
;
private
SuDatabaseHelper
suDB
;
private
Cursor
suLogCursor
=
null
;
public
SuLogAdapter
(
SuDatabaseHelper
db
)
{
suDB
=
db
;
logEntryList
=
Collections
.
emptyList
();
sectionExpanded
=
new
HashSet
<>();
itemExpanded
=
new
HashSet
<>();
}
public
RecyclerView
.
Adapter
getAdapter
()
{
return
adapter
;
@Override
public
int
getSectionCount
()
{
return
logEntryList
.
size
();
}
private
class
ExpandableAdapter
extends
ExpandableRecyclerViewAdapter
<
LogGroupViewHolder
,
LogViewHolder
>
{
ExpandableAdapter
(
List
<?
extends
ExpandableGroup
>
groups
)
{
super
(
groups
);
expandableList
.
expandedGroupIndexes
[
0
]
=
true
;
@Override
public
int
getItemCount
(
int
section
)
{
return
sectionExpanded
.
contains
(
section
)
?
logEntryList
.
get
(
section
).
size
()
:
0
;
}
@Override
public
LogGroupViewHolder
onCreateGroupViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
public
SectionHolder
onCreateSectionViewHolder
(
ViewGroup
parent
)
{
View
v
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_sulog_group
,
parent
,
false
);
return
new
LogGroupView
Holder
(
v
);
return
new
Section
Holder
(
v
);
}
@Override
public
LogViewHolder
onCreateChild
ViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
public
LogViewHolder
onCreateItem
ViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
View
v
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_sulog
,
parent
,
false
);
return
new
LogViewHolder
(
v
);
}
@Override
public
void
onBindChildViewHolder
(
LogViewHolder
holder
,
int
flatPosition
,
ExpandableGroup
group
,
int
childIndex
)
{
Context
context
=
holder
.
itemView
.
getContext
();
SuLogEntry
logEntry
=
(
SuLogEntry
)
group
.
getItems
().
get
(
childIndex
);
holder
.
setExpanded
(
expandList
.
contains
(
logEntry
));
holder
.
itemView
.
setOnClickListener
(
view
->
{
if
(
holder
.
getExpanded
())
{
holder
.
collapse
();
expandList
.
remove
(
logEntry
);
public
void
onBindSectionViewHolder
(
SectionHolder
holder
,
int
section
)
{
suLogCursor
.
moveToPosition
(
logEntryList
.
get
(
section
).
get
(
0
));
SuLogEntry
entry
=
new
SuLogEntry
(
suLogCursor
);
holder
.
arrow
.
setRotation
(
sectionExpanded
.
contains
(
section
)
?
180
:
0
);
holder
.
itemView
.
setOnClickListener
(
v
->
{
RotateAnimation
rotate
;
if
(
sectionExpanded
.
contains
(
section
))
{
holder
.
arrow
.
setRotation
(
0
);
rotate
=
new
RotateAnimation
(
180
,
0
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
);
sectionExpanded
.
remove
(
section
);
notifyItemRangeRemoved
(
getItemPosition
(
section
,
0
),
logEntryList
.
get
(
section
).
size
());
}
else
{
holder
.
expand
();
expandList
.
add
(
logEntry
);
rotate
=
new
RotateAnimation
(
0
,
180
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
);
sectionExpanded
.
add
(
section
);
notifyItemRangeChanged
(
getItemPosition
(
section
,
0
),
logEntryList
.
get
(
section
).
size
());
}
rotate
.
setDuration
(
300
);
rotate
.
setFillAfter
(
true
);
holder
.
arrow
.
setAnimation
(
rotate
);
});
holder
.
appName
.
setText
(
logEntry
.
appName
);
holder
.
action
.
setText
(
context
.
getString
(
logEntry
.
action
?
R
.
string
.
grant
:
R
.
string
.
deny
));
holder
.
command
.
setText
(
logEntry
.
command
);
holder
.
fromPid
.
setText
(
String
.
valueOf
(
logEntry
.
fromPid
));
holder
.
toUid
.
setText
(
String
.
valueOf
(
logEntry
.
toUid
));
holder
.
time
.
setText
(
logEntry
.
getTimeString
());
holder
.
date
.
setText
(
entry
.
getDateString
());
}
@Override
public
void
onBindGroupViewHolder
(
LogGroupViewHolder
holder
,
int
flatPosition
,
ExpandableGroup
group
)
{
holder
.
date
.
setText
(
group
.
getTitle
());
if
(
isGroupExpanded
(
flatPosition
))
{
public
void
onBindItemViewHolder
(
LogViewHolder
holder
,
int
section
,
int
position
)
{
int
sqlPosition
=
logEntryList
.
get
(
section
).
get
(
position
);
suLogCursor
.
moveToPosition
(
sqlPosition
);
SuLogEntry
entry
=
new
SuLogEntry
(
suLogCursor
);
holder
.
setExpanded
(
itemExpanded
.
contains
(
sqlPosition
));
holder
.
itemView
.
setOnClickListener
(
view
->
{
if
(
holder
.
mExpanded
)
{
holder
.
collapse
();
itemExpanded
.
remove
(
sqlPosition
);
}
else
{
holder
.
expand
();
itemExpanded
.
add
(
sqlPosition
);
}
}
});
holder
.
appName
.
setText
(
entry
.
appName
);
holder
.
action
.
setText
(
entry
.
action
?
R
.
string
.
grant
:
R
.
string
.
deny
);
holder
.
command
.
setText
(
entry
.
command
);
holder
.
fromPid
.
setText
(
String
.
valueOf
(
entry
.
fromPid
));
holder
.
toUid
.
setText
(
String
.
valueOf
(
entry
.
toUid
));
holder
.
time
.
setText
(
entry
.
getTimeString
());
}
private
class
LogGroup
extends
ExpandableGroup
<
SuLogEntry
>
{
LogGroup
(
String
title
,
List
<
SuLogEntry
>
items
)
{
super
(
title
,
items
);
}
public
void
notifyDBChanged
()
{
if
(
suLogCursor
!=
null
)
suLogCursor
.
close
();
suLogCursor
=
suDB
.
getLogCursor
();
logEntryList
=
suDB
.
getLogStructure
();
itemExpanded
.
clear
();
sectionExpanded
.
clear
();
sectionExpanded
.
add
(
0
);
notifyDataSetChanged
();
}
static
class
LogGroupViewHolder
extends
Group
ViewHolder
{
static
class
SectionHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
date
)
TextView
date
;
@BindView
(
R
.
id
.
arrow
)
ImageView
arrow
;
public
LogGroupView
Holder
(
View
itemView
)
{
Section
Holder
(
View
itemView
)
{
super
(
itemView
);
ButterKnife
.
bind
(
this
,
itemView
);
}
@Override
public
void
expand
()
{
RotateAnimation
rotate
=
new
RotateAnimation
(
360
,
180
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
);
rotate
.
setDuration
(
300
);
rotate
.
setFillAfter
(
true
);
arrow
.
setAnimation
(
rotate
);
}
@Override
public
void
collapse
()
{
RotateAnimation
rotate
=
new
RotateAnimation
(
180
,
360
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
,
Animation
.
RELATIVE_TO_SELF
,
0.5f
);
rotate
.
setDuration
(
300
);
rotate
.
setFillAfter
(
true
);
arrow
.
setAnimation
(
rotate
);
}
}
// Wrapper class
static
class
LogViewHolder
extends
ChildViewHolder
{
private
InternalViewHolder
expandableViewHolder
;
static
class
LogViewHolder
extends
ExpandableViewHolder
{
@BindView
(
R
.
id
.
app_name
)
TextView
appName
;
@BindView
(
R
.
id
.
action
)
TextView
action
;
...
...
@@ -162,13 +140,6 @@ public class SuLogAdapter {
LogViewHolder
(
View
itemView
)
{
super
(
itemView
);
ButterKnife
.
bind
(
this
,
itemView
);
expandableViewHolder
=
new
InternalViewHolder
(
itemView
);
}
private
class
InternalViewHolder
extends
ExpandableViewHolder
{
InternalViewHolder
(
View
itemView
)
{
super
(
itemView
);
}
@Override
...
...
@@ -176,22 +147,4 @@ public class SuLogAdapter {
expandLayout
=
itemView
.
findViewById
(
R
.
id
.
expand_layout
);
}
}
private
boolean
getExpanded
()
{
return
expandableViewHolder
.
mExpanded
;
}
private
void
setExpanded
(
boolean
expanded
)
{
expandableViewHolder
.
setExpanded
(
expanded
);
}
private
void
expand
()
{
expandableViewHolder
.
expand
();
}
private
void
collapse
()
{
expandableViewHolder
.
collapse
();
}
}
}
app/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java
View file @
356065d1
...
...
@@ -4,8 +4,10 @@ import android.content.ContentValues;
import
android.content.Context
;
import
android.content.pm.PackageManager
;
import
android.database.Cursor
;
import
android.database.DatabaseUtils
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteOpenHelper
;
import
android.text.TextUtils
;
import
com.topjohnwu.magisk.MagiskManager
;
import
com.topjohnwu.magisk.superuser.Policy
;
...
...
@@ -13,8 +15,10 @@ import com.topjohnwu.magisk.superuser.SuLogEntry;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.io.File
;
import
java.text.DateFormat
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.List
;
public
class
SuDatabaseHelper
extends
SQLiteOpenHelper
{
...
...
@@ -179,31 +183,42 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
}
}
private
List
<
SuLogEntry
>
getLogList
(
SQLiteDatabase
db
,
String
selection
)
{
try
(
Cursor
c
=
db
.
query
(
LOG_TABLE
,
null
,
selection
,
null
,
null
,
null
,
"time DESC"
))
{
List
<
SuLogEntry
>
ret
=
new
ArrayList
<>(
c
.
getCount
());
public
List
<
List
<
Integer
>>
getLogStructure
()
{
try
(
Cursor
c
=
mDb
.
query
(
LOG_TABLE
,
new
String
[]
{
"time"
},
null
,
null
,
null
,
null
,
"time DESC"
))
{
List
<
List
<
Integer
>>
ret
=
new
ArrayList
<>();
List
<
Integer
>
list
=
null
;
String
dateString
=
null
,
newString
;
while
(
c
.
moveToNext
())
{
ret
.
add
(
new
SuLogEntry
(
c
));
Date
date
=
new
Date
(
c
.
getLong
(
c
.
getColumnIndex
(
"time"
))
*
1000
);
newString
=
DateFormat
.
getDateInstance
(
DateFormat
.
MEDIUM
,
MagiskManager
.
locale
).
format
(
date
);
if
(!
TextUtils
.
equals
(
dateString
,
newString
))
{
dateString
=
newString
;
list
=
new
ArrayList
<>();
ret
.
add
(
list
);
}
list
.
add
(
c
.
getPosition
());
}
return
ret
;
}
}
private
void
migrateLegacyLogList
(
File
oldDB
,
SQLiteDatabase
newDB
)
{
SQLiteDatabase
oldDb
=
SQLiteDatabase
.
openDatabase
(
oldDB
.
getPath
(),
null
,
SQLiteDatabase
.
OPEN_READWRITE
);
List
<
SuLogEntry
>
logs
=
getLogList
(
oldDb
,
null
);
for
(
SuLogEntry
log
:
logs
)
{
newDB
.
insert
(
LOG_TABLE
,
null
,
log
.
getContentValues
());
}
oldDb
.
close
();
public
Cursor
getLogCursor
()
{
return
getLogCursor
(
mDb
);
}
public
List
<
SuLogEntry
>
getLogList
(
)
{
return
getLogList
(
null
);
public
Cursor
getLogCursor
(
SQLiteDatabase
db
)
{
return
db
.
query
(
LOG_TABLE
,
null
,
null
,
null
,
null
,
null
,
"time DESC"
);
}
public
List
<
SuLogEntry
>
getLogList
(
String
selection
)
{
return
getLogList
(
mDb
,
selection
);
private
void
migrateLegacyLogList
(
File
oldDB
,
SQLiteDatabase
newDB
)
{
try
(
SQLiteDatabase
oldDb
=
SQLiteDatabase
.
openDatabase
(
oldDB
.
getPath
(),
null
,
SQLiteDatabase
.
OPEN_READWRITE
);
Cursor
c
=
getLogCursor
(
oldDb
))
{
while
(
c
.
moveToNext
())
{
ContentValues
values
=
new
ContentValues
();
DatabaseUtils
.
cursorRowToContentValues
(
c
,
values
);
newDB
.
insert
(
LOG_TABLE
,
null
,
values
);
}
}
}
public
void
addLog
(
SuLogEntry
log
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/superuser/SuLogEntry.java
View file @
356065d1
...
...
@@ -2,8 +2,6 @@ package com.topjohnwu.magisk.superuser;
import
android.content.ContentValues
;
import
android.database.Cursor
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
com.topjohnwu.magisk.MagiskManager
;
...
...
@@ -11,7 +9,7 @@ import java.text.DateFormat;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
public
class
SuLogEntry
implements
Parcelable
{
public
class
SuLogEntry
{
public
int
fromUid
,
toUid
,
fromPid
;
public
String
packageName
,
appName
,
command
;
...
...
@@ -55,45 +53,4 @@ public class SuLogEntry implements Parcelable {
public
String
getTimeString
()
{
return
new
SimpleDateFormat
(
"h:mm a"
,
MagiskManager
.
locale
).
format
(
date
);
}
public
static
final
Creator
<
SuLogEntry
>
CREATOR
=
new
Creator
<
SuLogEntry
>()
{
@Override
public
SuLogEntry
createFromParcel
(
Parcel
in
)
{
return
new
SuLogEntry
(
in
);
}
@Override
public
SuLogEntry
[]
newArray
(
int
size
)
{
return
new
SuLogEntry
[
size
];
}
};
protected
SuLogEntry
(
Parcel
in
)
{
fromUid
=
in
.
readInt
();
toUid
=
in
.
readInt
();
fromPid
=
in
.
readInt
();
packageName
=
in
.
readString
();
appName
=
in
.
readString
();
command
=
in
.
readString
();
action
=
in
.
readByte
()
!=
0
;
date
=
new
Date
(
in
.
readLong
());
}
@Override
public
int
describeContents
()
{
return
0
;
}
@Override
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeInt
(
fromUid
);
dest
.
writeInt
(
toUid
);
dest
.
writeInt
(
fromPid
);
dest
.
writeString
(
packageName
);
dest
.
writeString
(
appName
);
dest
.
writeString
(
command
);
dest
.
writeByte
((
byte
)
(
action
?
1
:
0
));
dest
.
writeLong
(
date
.
getTime
());
}
}
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