package com.majeur.applicationsinfo;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.content.pm.PathPermission;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.majeur.applicationsinfo.utils.Tuple;
import com.majeur.applicationsinfo.utils.Utils;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DetailFragment extends Fragment {
static final String FRAGMENT_TAG = "fragment_detail";
static final String EXTRA_PACKAGE_NAME = "pkg";
private static final String UID_STATS_PATH = "/proc/uid_stat/";
private static final String UID_STATS_TR = "tcp_rcv";
private static final String UID_STATS_RC = "tcp_snd";
private static final int HEADER = 0;
private static final int ACTIVITIES = 1;
private static final int SERVICES = 2;
private static final int RECEIVERS = 3;
private static final int PROVIDERS = 4;
private static final int USES_PERMISSIONS = 5;
private static final int PERMISSIONS = 6;
private static final int FEATURES = 7;
private static final int CONFIGURATION = 8;
private static final int SIGNATURES = 9;
private PackageManager mPackageManager;
private String mPackageName;
private LayoutInflater mLayoutInflater;
private PackageInfo mPackageInfo;
private PackageStats mPackageStats;
private DetailOverflowMenu mDetailOverflowMenu;
private int mColorGrey1;
private int mColorGrey2;
private TypedArray mGroupTitleIds;
private SimpleDateFormat mDateFormatter = new SimpleDateFormat("EE LLL dd yyyy kk:mm:ss");
public static DetailFragment getInstance(String packageName) {
DetailFragment detailFragment = new DetailFragment();
Bundle args = new Bundle();
args.putString(DetailFragment.EXTRA_PACKAGE_NAME, packageName);
detailFragment.setArguments(args);
return detailFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPackageManager = getActivity().getPackageManager();
mPackageName = getArguments().getString(EXTRA_PACKAGE_NAME);
mColorGrey1 = getResources().getColor(R.color.grey_1);
mColorGrey2 = getResources().getColor(R.color.grey_2);
mDetailOverflowMenu = new DetailOverflowMenu(getActivity(), mPackageName);
mGroupTitleIds = getResources().obtainTypedArray(R.array.group_titles);
mPackageInfo = getPackageInfo(mPackageName);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLayoutInflater = inflater;
ExpandableListView listView = new ExpandableListView(getActivity());
listView.setGroupIndicator(null);
if (mPackageInfo == null) {
Toast.makeText(getActivity(), R.string.app_not_installed, Toast.LENGTH_LONG).show();
} else {
listView.setAdapter(new Adapter());
}
return listView;
}
@Override
public void onDetach() {
super.onDetach();
mDetailOverflowMenu = null;
}
private PackageInfo getPackageInfo(String packageName) {
try {
return mPackageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS
| PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS | PackageManager.GET_PROVIDERS
| PackageManager.GET_SERVICES | PackageManager.GET_URI_PERMISSION_PATTERNS
| PackageManager.GET_SIGNATURES | PackageManager.GET_CONFIGURATIONS);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
/**
* Used to finish when user clicks on {@link android.app.ActionBar} arrow
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
//onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Create and populate header view
*/
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
private View getHeaderView(ViewGroup viewGroup) {
View headerView = mLayoutInflater.inflate(R.layout.detail_header, viewGroup, false);
ApplicationInfo applicationInfo = mPackageInfo.applicationInfo;
TextView labelView = (TextView) headerView.findViewById(R.id.label);
CharSequence label = applicationInfo.loadLabel(mPackageManager);
if (getActivity() instanceof DetailActivity) {
//Application is not in multi-pane mode, use ActionBar for label
getActivity().setTitle(label);
labelView.setVisibility(View.GONE);
} else {
//Application is in multi-pane mode, ActionBar is already used, use field in header
//to display label
labelView.setText(label);
}
TextView packageNameView = (TextView) headerView.findViewById(R.id.packageName);
packageNameView.setText(mPackageName);
ImageView iconView = (ImageView) headerView.findViewById(R.id.icon);
iconView.setImageDrawable(applicationInfo.loadIcon(mPackageManager));
if (Utils.isApi20()) {
ImageView bannerView = (ImageView) headerView.findViewById(R.id.banner);
bannerView.setImageDrawable(applicationInfo.loadBanner(mPackageManager));
}
TextView versionView = (TextView) headerView.findViewById(R.id.version);
versionView.setText(mPackageInfo.versionName + " (" + mPackageInfo.versionCode + ")");
TextView pathView = (TextView) headerView.findViewById(R.id.path);
pathView.setText(applicationInfo.sourceDir);
TextView isSystemAppView = (TextView) headerView.findViewById(R.id.isSystem);
boolean isSystemApp = (mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
isSystemAppView.setText(isSystemApp ? R.string.system : R.string.user);
TextView installDateView = (TextView) headerView.findViewById(R.id.installed_date);
installDateView.setText(getString(R.string.installation) + ": " + getTime(mPackageInfo.firstInstallTime));
TextView updateDateView = (TextView) headerView.findViewById(R.id.update_date);
updateDateView.setText(getString(R.string.update) + ": " + getTime(mPackageInfo.lastUpdateTime));
ImageButton overflowButton = (ImageButton) headerView.findViewById(R.id.detail_overflow);
mDetailOverflowMenu.setView(overflowButton);
TextView sharedUserId = (TextView) headerView.findViewById(R.id.sharedUserId);
sharedUserId.setText(getString(R.string.shared_user_id) + ": " + mPackageInfo.sharedUserId);
Tuple<String, String> uidNetStats = getNetStats(applicationInfo.uid);
TextView netStatsTransmittedView = (TextView) headerView.findViewById(R.id.netstats_transmitted);
netStatsTransmittedView.setText(getString(R.string.netstats_transmitted) + ": "
+ uidNetStats.getFirst());
TextView netStatsReceivedView = (TextView) headerView.findViewById(R.id.netstats_received);
netStatsReceivedView.setText(getString(R.string.netstats_received) + ": "
+ uidNetStats.getSecond());
if (mPackageStats == null)
getPackageSizeInfo(headerView);
else
onPackageStatsLoaded(headerView);
return headerView;
}
private String getReadableSize(long size) {
return Formatter.formatFileSize(getActivity(), size);
}
private Tuple<String, String> getNetStats(int uid) {
Tuple<String, String> tuple = new Tuple<>(getReadableSize(0), getReadableSize(0));
File uidStatsDir = new File(UID_STATS_PATH + uid);
if (uidStatsDir.exists() && uidStatsDir.isDirectory()) {
for (File child : uidStatsDir.listFiles()) {
if (child.getName().equals(UID_STATS_TR))
tuple.setFirst(getReadableSize(Long.parseLong(Utils.getFileContent(child))));
else if (child.getName().equals(UID_STATS_RC))
tuple.setSecond(getReadableSize(Long.parseLong(Utils.getFileContent(child))));
}
}
return tuple;
}
public String getTime(long time) {
Date date = new Date(time);
return mDateFormatter.format(date);
}
/**
* Load package sizes and update views if success
*
* @param view
*/
private void getPackageSizeInfo(final View view) {
try {
Method getPackageSizeInfo = PackageManager.class.getMethod(
"getPackageSizeInfo", String.class, IPackageStatsObserver.class);
getPackageSizeInfo.invoke(mPackageManager, mPackageName, new IPackageStatsObserver.Stub() {
@Override
public void onGetStatsCompleted(final PackageStats pStats, boolean succeeded)
throws RemoteException {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mPackageStats = pStats;
onPackageStatsLoaded(view);
}
});
}
});
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* Update size views
*
* @param headerView
*/
private void onPackageStatsLoaded(View headerView) {
if (mPackageStats == null)
return;
TextView sizeCodeView = (TextView) headerView.findViewById(R.id.size_code);
sizeCodeView.setText(getReadableSize(mPackageStats.codeSize));
TextView sizeCacheView = (TextView) headerView.findViewById(R.id.size_cache);
sizeCacheView.setText(getReadableSize(mPackageStats.cacheSize));
TextView sizeDataView = (TextView) headerView.findViewById(R.id.size_data);
sizeDataView.setText(getReadableSize(mPackageStats.dataSize));
TextView sizeExtCodeView = (TextView) headerView.findViewById(R.id.size_ext_code);
sizeExtCodeView.setText(getReadableSize(mPackageStats.externalCodeSize));
TextView sizeExtCacheView = (TextView) headerView.findViewById(R.id.size_ext_cache);
sizeExtCacheView.setText(getReadableSize(mPackageStats.externalCacheSize));
TextView sizeExtDataView = (TextView) headerView.findViewById(R.id.size_ext_data);
sizeExtDataView.setText(getReadableSize(mPackageStats.externalDataSize));
TextView sizeObb = (TextView) headerView.findViewById(R.id.size_ext_obb);
sizeObb.setText(getReadableSize(mPackageStats.externalObbSize));
TextView sizeMedia = (TextView) headerView.findViewById(R.id.size_ext_media);
sizeMedia.setText(getReadableSize(mPackageStats.externalMediaSize));
}
private class Adapter extends BaseExpandableListAdapter {
/**
* Returning total group titles count plus one for the header
*/
@Override
public int getGroupCount() {
return mGroupTitleIds.length() + 1;
}
/**
* {@link com.majeur.applicationsinfo.utils.Utils} method is used to prevent {@link java.lang.NullPointerException} when arrays are null.
* In this case, we make sure that returned length is zero.
*/
@Override
public int getChildrenCount(int parentIndex) {
return Utils.getArrayLengthSafely(getNeededArray(parentIndex));
}
/**
* Return corresponding section's array
*/
private Object[] getNeededArray(int index) {
switch (index) {
case HEADER:
return null;
case ACTIVITIES:
return mPackageInfo.activities;
case SERVICES:
return mPackageInfo.services;
case RECEIVERS:
return mPackageInfo.receivers;
case PROVIDERS:
return mPackageInfo.providers;
case USES_PERMISSIONS:
return mPackageInfo.requestedPermissions;
case PERMISSIONS:
return mPackageInfo.permissions;
case FEATURES:
return mPackageInfo.reqFeatures;
case CONFIGURATION:
return mPackageInfo.configPreferences;
case SIGNATURES:
return mPackageInfo.signatures;
default:
return null;
}
}
/**
* For HEADER value we return header view. In other case, we return simple {@link android.widget.TextView} with group title,
* note that index in {@link android.content.res.TypedArray} is shifted to adapter implementation.
*/
@Override
public View getGroupView(int groupIndex, boolean b, View view, ViewGroup viewGroup) {
if (groupIndex == HEADER)
return getHeaderView(viewGroup);
TextView textView;
if (view instanceof TextView)
textView = (TextView) view;
else
textView = (TextView) mLayoutInflater.inflate(R.layout.group_title_view, null);
textView.setText(mGroupTitleIds.getString(groupIndex - 1) + " (" + getChildrenCount(groupIndex) + ")");
return textView;
}
/**
* Child click is not used
*/
@Override
public boolean isChildSelectable(int i, int i2) {
return false;
}
/**
* ViewHolder to use recycled views efficiently. Fields names are not expressive because we use
* the same holder for any kind of view, and view are not all sames.
*/
class ViewHolder {
int currentViewType = -1;
TextView textView1;
TextView textView2;
TextView textView3;
TextView textView4;
TextView textView5;
TextView textView6;
ImageView imageView;
Button button;
}
/**
* We return corresponding view, recycled view implementation is done in each method
*/
@Override
public View getChildView(int groupIndex, int childIndex, boolean b, View view, ViewGroup viewGroup) {
switch (groupIndex) {
case ACTIVITIES:
return getActivityView(viewGroup, view, childIndex);
case SERVICES:
return getServicesView(viewGroup, view, childIndex);
case RECEIVERS:
return getReceiverView(viewGroup, view, childIndex);
case PROVIDERS:
return getProviderView(viewGroup, view, childIndex);
case USES_PERMISSIONS:
return getUsesPermissionsView(view, childIndex);
case PERMISSIONS:
return getPermissionsView(viewGroup, view, childIndex);
case FEATURES:
return getFeaturesView(viewGroup, view, childIndex);
case CONFIGURATION:
return getConfigurationView(viewGroup, view, childIndex);
case SIGNATURES:
return getSignatureView(view, childIndex);
default:
return null;
}
}
/**
* See below checkIfConvertViewMatch method.
* Bored view inflation / creation.
*/
private View getActivityView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, ACTIVITIES)) {
convertView = mLayoutInflater.inflate(R.layout.detail_activities, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = ACTIVITIES;
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.icon);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.label);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.taskAffinity);
viewHolder.textView4 = (TextView) convertView.findViewById(R.id.launchMode);
viewHolder.textView5 = (TextView) convertView.findViewById(R.id.orientation);
viewHolder.textView6 = (TextView) convertView.findViewById(R.id.softInput);
viewHolder.button = (Button) convertView.findViewById(R.id.launch);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ActivityInfo activityInfo = mPackageInfo.activities[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Label
viewHolder.textView1.setText(activityInfo.loadLabel(mPackageManager));
//Name
viewHolder.textView2.setText(activityInfo.name.replaceFirst(mPackageName, ""));
//Icon
viewHolder.imageView.setImageDrawable(activityInfo.loadIcon(mPackageManager));
//TaskAffinity
viewHolder.textView3.setText(getString(R.string.taskAffinity) + ": " + activityInfo.taskAffinity);
//LaunchMode
viewHolder.textView4.setText(getString(R.string.launch_mode) + ": " + Utils.getLaunchMode(activityInfo.launchMode));
//Orientation
viewHolder.textView5.setText(getString(R.string.orientation) + ": " + Utils.getOrientationString(activityInfo.screenOrientation));
//SoftInput
viewHolder.textView6.setText(getString(R.string.softInput) + ": " + Utils.getSoftInputString(activityInfo.softInputMode));
Button launch = viewHolder.button;
boolean isExported = activityInfo.exported;
launch.setEnabled(isExported);
if (isExported) {
launch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClassName(mPackageName, activityInfo.name);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}
}
});
}
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getServicesView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, SERVICES)) {
convertView = mLayoutInflater.inflate(R.layout.detail_activities, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = SERVICES;
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.icon);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.label);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.launchMode);
convertView.findViewById(R.id.taskAffinity).setVisibility(View.GONE);
convertView.findViewById(R.id.orientation).setVisibility(View.GONE);
convertView.findViewById(R.id.softInput).setVisibility(View.GONE);
convertView.findViewById(R.id.launch).setVisibility(View.GONE);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ServiceInfo serviceInfo = mPackageInfo.services[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Label
viewHolder.textView1.setText(serviceInfo.loadLabel(mPackageManager));
//Name
viewHolder.textView2.setText(serviceInfo.name.replaceFirst(mPackageName, ""));
//Icon
viewHolder.imageView.setImageDrawable(serviceInfo.loadIcon(mPackageManager));
//Flags
viewHolder.textView3.setText(getString(R.string.flags) + ": " + Utils.getServiceFlagsString(serviceInfo.flags));
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getReceiverView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, RECEIVERS)) {
convertView = mLayoutInflater.inflate(R.layout.detail_activities, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = RECEIVERS;
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.icon);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.label);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.taskAffinity);
viewHolder.textView4 = (TextView) convertView.findViewById(R.id.launchMode);
viewHolder.textView5 = (TextView) convertView.findViewById(R.id.orientation);
viewHolder.textView6 = (TextView) convertView.findViewById(R.id.softInput);
convertView.findViewById(R.id.launch).setVisibility(View.GONE);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ActivityInfo activityInfo = mPackageInfo.receivers[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Label
viewHolder.textView1.setText(activityInfo.loadLabel(mPackageManager));
//Name
viewHolder.textView2.setText(activityInfo.name.replaceFirst(mPackageName, ""));
//Icon
viewHolder.imageView.setImageDrawable(activityInfo.loadIcon(mPackageManager));
//TaskAffinity
viewHolder.textView3.setText(getString(R.string.taskAffinity) + ": " + activityInfo.taskAffinity);
//LaunchMode
viewHolder.textView4.setText(getString(R.string.launch_mode) + ": " + Utils.getLaunchMode(activityInfo.launchMode));
//Orientation
viewHolder.textView5.setText(getString(R.string.orientation) + ": " + Utils.getOrientationString(activityInfo.screenOrientation));
//SoftInput
viewHolder.textView6.setText(getString(R.string.softInput) + ": " + Utils.getSoftInputString(activityInfo.softInputMode));
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getProviderView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, PROVIDERS)) {
convertView = mLayoutInflater.inflate(R.layout.detail_activities, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = PROVIDERS;
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.icon);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.label);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.launchMode);
viewHolder.textView4 = (TextView) convertView.findViewById(R.id.orientation);
viewHolder.textView5 = (TextView) convertView.findViewById(R.id.softInput);
viewHolder.textView6 = (TextView) convertView.findViewById(R.id.taskAffinity);
convertView.findViewById(R.id.launch).setVisibility(View.GONE);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ProviderInfo providerInfo = mPackageInfo.providers[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Label
viewHolder.textView1.setText(providerInfo.loadLabel(mPackageManager));
//Name
viewHolder.textView2.setText(providerInfo.name.replaceFirst(mPackageName, ""));
//Icon
viewHolder.imageView.setImageDrawable(providerInfo.loadIcon(mPackageManager));
//Uri permission
viewHolder.textView3.setText(getString(R.string.grant_uri_permission) + ": " + providerInfo.grantUriPermissions);
//Path permissions
PathPermission[] pathPermissions = providerInfo.pathPermissions;
String finalString;
if (pathPermissions != null) {
StringBuilder builder = new StringBuilder();
String read = getString(R.string.read);
String write = getString(R.string.write);
for (PathPermission permission : pathPermissions) {
builder.append(read + ": " + permission.getReadPermission());
builder.append("/");
builder.append(write + ": " + permission.getWritePermission());
builder.append(", ");
}
Utils.checkStringBuilderEnd(builder);
finalString = builder.toString();
} else
finalString = "null";
viewHolder.textView4.setText(getString(R.string.path_permissions) + ": " + finalString);
//Pattern matchers
PatternMatcher[] patternMatchers = providerInfo.uriPermissionPatterns;
String finalString1;
if (patternMatchers != null) {
StringBuilder builder = new StringBuilder();
for (PatternMatcher patternMatcher : patternMatchers) {
builder.append(patternMatcher.toString());
builder.append(", ");
}
Utils.checkStringBuilderEnd(builder);
finalString1 = builder.toString();
} else
finalString1 = "null";
viewHolder.textView5.setText(getString(R.string.patterns_allowed) + ": " + finalString1);
//Authority
viewHolder.textView6.setText(getString(R.string.authority) + ": " + providerInfo.authority);
return convertView;
}
/**
* We do not need complex views, Use recycled view if possible
*/
private View getUsesPermissionsView(View convertView, int index) {
if (!(convertView instanceof TextView)) {
convertView = new TextView(getActivity());
}
TextView textView = (TextView) convertView;
textView.setTextIsSelectable(true);
textView.setText(mPackageInfo.requestedPermissions[index]);
textView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
int size = getActivity().getResources().getDimensionPixelSize(R.dimen.header_text_margin);
textView.setPadding(size, 0, size, 0);
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getPermissionsView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, PERMISSIONS)) {
convertView = mLayoutInflater.inflate(R.layout.detail_activities, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = PERMISSIONS;
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.icon);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.label);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.taskAffinity);
viewHolder.textView4 = (TextView) convertView.findViewById(R.id.launchMode);
viewHolder.textView5 = (TextView) convertView.findViewById(R.id.orientation);
convertView.findViewById(R.id.softInput).setVisibility(View.GONE);
convertView.findViewById(R.id.launch).setVisibility(View.GONE);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final PermissionInfo permissionInfo = mPackageInfo.permissions[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Label
viewHolder.textView1.setText(permissionInfo.loadLabel(mPackageManager));
//Name
viewHolder.textView2.setText(permissionInfo.name.replaceFirst(mPackageName, ""));
//Icon
viewHolder.imageView.setImageDrawable(permissionInfo.loadIcon(mPackageManager));
//Description
viewHolder.textView3.setText(permissionInfo.loadDescription(mPackageManager));
//LaunchMode
viewHolder.textView4.setText(getString(R.string.group) + ": " + permissionInfo.group);
//Protection level
viewHolder.textView5.setText(getString(R.string.protection_level) + ": " + Utils.getProtectionLevelString(permissionInfo.protectionLevel));
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getFeaturesView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, FEATURES)) {
convertView = mLayoutInflater.inflate(R.layout.detail_features, viewGroup, false);
viewHolder = new ViewHolder();
viewHolder.currentViewType = FEATURES;
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.flags);
viewHolder.textView3 = (TextView) convertView.findViewById(R.id.gles_ver);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final FeatureInfo featureInfo = mPackageInfo.reqFeatures[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//Name
viewHolder.textView1.setText(featureInfo.name);
//Falgs
viewHolder.textView2.setText(getString(R.string.flags) + ": " + Utils.getFeatureFlagsString(featureInfo.flags));
//GLES ver
viewHolder.textView3.setText(getString(R.string.gles_ver) + ": " + featureInfo.reqGlEsVersion);
return convertView;
}
/**
* Boring view inflation / creation
*/
private View getConfigurationView(ViewGroup viewGroup, View convertView, int index) {
ViewHolder viewHolder;
if (!checkIfConvertViewMatch(convertView, CONFIGURATION)) {
convertView = mLayoutInflater.inflate(R.layout.detail_features, viewGroup);
viewHolder = new ViewHolder();
viewHolder.currentViewType = CONFIGURATION;
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.name);
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.flags);
convertView.findViewById(R.id.gles_ver).setVisibility(View.GONE);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ConfigurationInfo configurationInfo = mPackageInfo.configPreferences[index];
convertView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
//GLES ver
viewHolder.textView1.setText(getString(R.string.gles_ver) + ": " + configurationInfo.reqGlEsVersion);
//Falg
viewHolder.textView2.setText(getString(R.string.input_features) + ": " +
Utils.getInputFeaturesString(configurationInfo.reqInputFeatures));
return convertView;
}
/**
* We do not need complex views, Use recycled view if possible
*/
private View getSignatureView(View convertView, int index) {
if (!(convertView instanceof TextView)) {
convertView = new TextView(getActivity());
}
TextView textView = (TextView) convertView;
textView.setText(mPackageInfo.signatures[index].toCharsString());
textView.setBackgroundColor(index % 2 == 0 ? mColorGrey1 : mColorGrey2);
textView.setTextIsSelectable(true);
int size = getActivity().getResources().getDimensionPixelSize(R.dimen.header_text_margin);
textView.setPadding(size, 0, size, 0);
return convertView;
}
/**
* Here we check if recycled view match requested type. Tag can be null if recycled view comes from
* groups that doesn't implement {@link ViewHolder}, such as groups that use only a simple text view.
*/
private boolean checkIfConvertViewMatch(View convertView, int requestedGroup) {
return convertView != null && convertView.getTag() != null && ((ViewHolder) convertView.getTag()).currentViewType == requestedGroup;
}
/**
* Unused methods
*/
@Override
public Object getGroup(int i) {
return null;
}
@Override
public Object getChild(int i, int i2) {
return null;
}
@Override
public long getGroupId(int i) {
return 0;
}
@Override
public long getChildId(int i, int i2) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
}
}