2017-01-28 01:10:50 +08:00
|
|
|
package com.topjohnwu.magisk.adapters;
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
import android.support.v7.widget.RecyclerView;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.animation.Animation;
|
|
|
|
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;
|
2017-06-20 17:55:33 +08:00
|
|
|
import com.topjohnwu.magisk.components.ExpandableViewHolder;
|
2017-01-28 01:10:50 +08:00
|
|
|
import com.topjohnwu.magisk.superuser.SuLogEntry;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
import java.util.List;
|
2017-01-29 20:50:58 +01:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
2017-01-28 01:10:50 +08:00
|
|
|
|
|
|
|
import butterknife.BindView;
|
|
|
|
import butterknife.ButterKnife;
|
|
|
|
|
|
|
|
public class SuLogAdapter {
|
|
|
|
|
|
|
|
private ExpandableAdapter adapter;
|
2017-01-29 20:50:58 +01:00
|
|
|
private Set<SuLogEntry> expandList = new HashSet<>();
|
2017-01-28 01:10:50 +08:00
|
|
|
|
|
|
|
public SuLogAdapter(List<SuLogEntry> list) {
|
|
|
|
|
|
|
|
// Separate the logs with date
|
2017-01-29 20:50:58 +01:00
|
|
|
Map<String, List<SuLogEntry>> logEntryMap = new LinkedHashMap<>();
|
|
|
|
List<SuLogEntry> group;
|
2017-01-28 01:10:50 +08:00
|
|
|
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
|
2017-01-29 20:50:58 +01:00
|
|
|
List<LogGroup> logEntryGroups = new ArrayList<>();
|
|
|
|
for (Map.Entry<String, List<SuLogEntry>> entry : logEntryMap.entrySet()) {
|
2017-01-28 01:10:50 +08:00
|
|
|
logEntryGroups.add(new LogGroup(entry.getKey(), entry.getValue()));
|
|
|
|
}
|
|
|
|
adapter = new ExpandableAdapter(logEntryGroups);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public RecyclerView.Adapter getAdapter() {
|
|
|
|
return adapter;
|
|
|
|
}
|
|
|
|
|
|
|
|
private class ExpandableAdapter
|
|
|
|
extends ExpandableRecyclerViewAdapter<LogGroupViewHolder, LogViewHolder> {
|
|
|
|
|
|
|
|
ExpandableAdapter(List<? extends ExpandableGroup> groups) {
|
|
|
|
super(groups);
|
|
|
|
expandableList.expandedGroupIndexes[0] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public LogGroupViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
|
|
|
|
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sulog_group, parent, false);
|
|
|
|
return new LogGroupViewHolder(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public LogViewHolder onCreateChildViewHolder(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 -> {
|
2017-06-20 17:55:33 +08:00
|
|
|
if (holder.getExpanded()) {
|
2017-01-28 01:10:50 +08:00
|
|
|
holder.collapse();
|
|
|
|
expandList.remove(logEntry);
|
|
|
|
} else {
|
|
|
|
holder.expand();
|
|
|
|
expandList.add(logEntry);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
holder.appName.setText(logEntry.appName);
|
2017-01-28 06:13:07 +08:00
|
|
|
holder.action.setText(context.getString(logEntry.action ? R.string.grant : R.string.deny));
|
2017-01-28 01:10:50 +08:00
|
|
|
holder.command.setText(logEntry.command);
|
|
|
|
holder.fromPid.setText(String.valueOf(logEntry.fromPid));
|
|
|
|
holder.toUid.setText(String.valueOf(logEntry.toUid));
|
|
|
|
holder.time.setText(logEntry.getTimeString());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBindGroupViewHolder(LogGroupViewHolder holder, int flatPosition, ExpandableGroup group) {
|
|
|
|
holder.date.setText(group.getTitle());
|
2017-02-21 03:30:37 +08:00
|
|
|
if (isGroupExpanded(flatPosition)) {
|
|
|
|
holder.expand();
|
|
|
|
}
|
2017-01-28 01:10:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class LogGroup extends ExpandableGroup<SuLogEntry> {
|
|
|
|
LogGroup(String title, List<SuLogEntry> items) {
|
|
|
|
super(title, items);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static class LogGroupViewHolder extends GroupViewHolder {
|
|
|
|
|
|
|
|
@BindView(R.id.date) TextView date;
|
|
|
|
@BindView(R.id.arrow) ImageView arrow;
|
|
|
|
|
|
|
|
public LogGroupViewHolder(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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
// Wrapper class
|
2017-01-28 01:10:50 +08:00
|
|
|
static class LogViewHolder extends ChildViewHolder {
|
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
private InternalViewHolder expandableViewHolder;
|
|
|
|
|
2017-01-28 01:10:50 +08:00
|
|
|
@BindView(R.id.app_name) TextView appName;
|
|
|
|
@BindView(R.id.action) TextView action;
|
|
|
|
@BindView(R.id.time) TextView time;
|
|
|
|
@BindView(R.id.fromPid) TextView fromPid;
|
|
|
|
@BindView(R.id.toUid) TextView toUid;
|
|
|
|
@BindView(R.id.command) TextView command;
|
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
LogViewHolder(View itemView) {
|
2017-01-28 01:10:50 +08:00
|
|
|
super(itemView);
|
|
|
|
ButterKnife.bind(this, itemView);
|
2017-06-20 17:55:33 +08:00
|
|
|
expandableViewHolder = new InternalViewHolder(itemView);
|
|
|
|
}
|
2017-01-28 01:10:50 +08:00
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
private class InternalViewHolder extends ExpandableViewHolder {
|
2017-01-28 01:10:50 +08:00
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
InternalViewHolder(View itemView) {
|
|
|
|
super(itemView);
|
|
|
|
}
|
2017-01-28 01:10:50 +08:00
|
|
|
|
2017-06-20 17:55:33 +08:00
|
|
|
@Override
|
|
|
|
public void setExpandLayout(View itemView) {
|
|
|
|
expandLayout = itemView.findViewById(R.id.expand_layout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean getExpanded() {
|
|
|
|
return expandableViewHolder.mExpanded;
|
2017-01-28 01:10:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void setExpanded(boolean expanded) {
|
2017-06-20 17:55:33 +08:00
|
|
|
expandableViewHolder.setExpanded(expanded);
|
2017-01-28 01:10:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void expand() {
|
2017-06-20 17:55:33 +08:00
|
|
|
expandableViewHolder.expand();
|
2017-01-28 01:10:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void collapse() {
|
2017-06-20 17:55:33 +08:00
|
|
|
expandableViewHolder.collapse();
|
2017-01-28 01:10:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|