package com.zte.appopscontrol; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import com.zte.appopscontrol.AppFragment.AppListAdapter; import com.zte.appopscontrol.AppFragment.AppListLoader; import com.zte.appopscontrol.AppFragment.PackageIntentReceiver; import com.zte.appopscontrol.AppOpsState2.OpsTemplate; import com.zte.appopscontrol.AppOpsUtils.AppInfo; import com.zte.appopscontrol.AppOpsUtils.PermInfo; import com.zte.appopscontrol.applications.AppOpsState; import com.zte.appopscontrol.privacyguard.PrivacyGuardManager; import android.app.Activity; import android.app.AppOpsManager; import android.app.Fragment; import android.app.ListFragment; import android.app.LoaderManager; import android.content.AsyncTaskLoader; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.Loader; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.SectionIndexer; import android.widget.TextView; public class PermissionFragment extends Fragment implements OnItemClickListener, LoaderManager.LoaderCallbacks<List<PermInfo>> { private String mCurrentPkgName; private ListView mListView; private View mContentView; private LinearLayout mProgressContainer; private PackageManager mPm; private static Activity mActivity; private AppOpsManager mAppOps; private AppOpsState mState; private static List<AppOpsState2> mStates = new ArrayList<AppOpsState2>(); private PermListAdapter mAdapter; private PermListLoader mAsyncTask; public PermissionFragment() { } public class PermListAdapter extends BaseAdapter { private LayoutInflater mInflater; private Context mContext; private List<PermInfo> mPermList = new ArrayList<PermInfo>(); public PermListAdapter(Context context) { mContext = context; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public void setDataAndNotify(List<PermInfo> permList) { mPermList = permList; notifyDataSetChanged(); } @Override public int getCount() { return mPermList.size(); } @Override public Object getItem(int position) { return mPermList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { AppViewHolder appHolder; if (convertView == null) { convertView = mInflater.inflate(R.layout.perm_fragment_list_item, null); // creates a ViewHolder and children references appHolder = new AppViewHolder(); appHolder.mPermLabel = (TextView) convertView.findViewById(R.id.perm_label); appHolder.mPermIcon = (ImageView) convertView.findViewById(R.id.perm_icon); appHolder.mAppCount = (TextView) convertView.findViewById(R.id.perm_count); convertView.setTag(appHolder); } else { appHolder = (AppViewHolder) convertView.getTag(); } // Bind the data efficiently with the holder PermInfo permInfo = mPermList.get(position); appHolder.mPermLabel.setText(permInfo.getLabel()); appHolder.mPermIcon.setImageDrawable(permInfo.getIcon()); int appCount = permInfo.getAppCount(); int sysAppCount = permInfo.getSysAppCount(); String sysCountUnit = sysAppCount > 1 ? getString(R.string.app_count_unit_plural) : getString(R.string.app_count_unit_single); String userCountUnit = (appCount-sysAppCount) > 1 ? getString(R.string.app_count_unit_plural) : getString(R.string.app_count_unit_single); String appCountStr = getString(R.string.app_system) + " " +sysCountUnit +": " + String.valueOf(sysAppCount) + " " + getString(R.string.app_user) + " " + userCountUnit + ": " + String.valueOf(appCount-sysAppCount); appHolder.mAppCount.setText(appCountStr); return convertView; } } /** * Helper class to look for interesting changes to the installed apps * so that the loader can be updated. */ public static class PackageIntentReceiver extends BroadcastReceiver { final PermListLoader mLoader; public PackageIntentReceiver(PermListLoader loader) { mLoader = loader; IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addDataScheme("package"); mLoader.getContext().registerReceiver(this, filter); // Register for events related to sdcard installation. IntentFilter sdFilter = new IntentFilter(); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); mLoader.getContext().registerReceiver(this, sdFilter); // register for refresh ui event (reload sys app or not) IntentFilter refreshFilter = new IntentFilter(); refreshFilter.addAction(AppOpsControlActivity.ACTION_APPOPS_REFRESH_UI); mLoader.getContext().registerReceiver(this, refreshFilter); } @Override public void onReceive(Context context, Intent intent) { // Tell the loader about the change. mLoader.onContentChanged(); } } /** * An asynchronous task to load . */ public static class PermListLoader extends AsyncTaskLoader<List<PermInfo>> { List<PermInfo> mPerms; PackageIntentReceiver mPackageObserver; public PermListLoader(Context context) { super(context); } @Override public List<PermInfo> loadInBackground() { List<PermInfo> permList = new ArrayList<PermInfo>(); for(int index = 0; index < AppOpsState2.ALL_TEMPLATES.length; index ++){ AppOpsState2 state = mStates.get(index); state.buildState(AppOpsState2.ALL_TEMPLATES[index]); String perm = AppOpsManager.opToPermission(AppOpsState2.ALL_TEMPLATES[index].ops[0]); Drawable drawIcon = mActivity.getResources().getDrawable(AppOpsState2.TEMPLATES_ICON[index]); /*String lastPermGroup = ""; Drawable drawIcon = getActivity().getResources().getDrawable( android.R.drawable.sym_def_app_icon); if (perm != null) { try { PermissionInfo pi = mPm.getPermissionInfo(perm, 0); if (pi.group != null && !lastPermGroup.equals(pi.group)) { lastPermGroup = pi.group; PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0); if (pgi.icon != 0) { drawIcon = pgi.loadIcon(mPm); } } } catch (NameNotFoundException e) { } }*/ String label = mActivity.getResources().getString(AppOpsState2.ALL_TEMPLATES[index].resId); PermInfo permItem = new PermInfo(mActivity,label,drawIcon); permItem.setmApps(state.mApps); permItem.setAppCount(state.mApps!=null ? state.mApps.size():0); int sysCount = 0; for(int i=0; i<state.mApps.size(); i++) { if( (state.mApps.get(i).getAppEntry().getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) != 0) { sysCount++; } } permItem.setSysAppCount(sysCount); permList.add(permItem); } //caculate /* // get the origin data CharSequence[] originPermArrary = getActivity().getResources().getTextArray(R.array.app_ops_labels); // encrypt the data to get view quickly List<PermInfo> permList = new ArrayList<PermInfo>(); List<String> strList = new ArrayList<String>(); Drawable drawIcon = getActivity().getResources().getDrawable( android.R.drawable.sym_def_app_icon); for (int index=0; index < originPermArrary.length; index++) { String str = originPermArrary[index].toString(); if(strList.contains(str))continue; else strList.add(str); String lastPermGroup = ""; //get each permission (manifest scale) String perm = AppOpsManager.opToPermission(index); if (perm != null) { try { PermissionInfo pi = mPm.getPermissionInfo(perm, 0); if (pi.group != null && !lastPermGroup.equals(pi.group)) { lastPermGroup = pi.group; PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(pi.group, 0); if (pgi.icon != 0) { drawIcon = pgi.loadIcon(mPm); } } } catch (NameNotFoundException e) { } } PermInfo permItem = new PermInfo(getActivity(),str,drawIcon); permItem.setAppCount(1111); permList.add(permItem); } */ return permList; } /** * Called when there is new data to deliver to the client. The * super class will take care of delivering it; the implementation * here just adds a little more logic. */ @Override public void deliverResult(List<PermInfo> perms) { List<PermInfo> oldApps = perms; mPerms = perms; if (isStarted()) { // If the Loader is currently started, we can immediately // deliver its results. super.deliverResult(perms); } } /** * Handles a request to start the Loader. */ @Override protected void onStartLoading() { // We don't monitor changed when loading is stopped, so need // to always reload at this point. onContentChanged(); if (mPerms != null) { // If we currently have a result available, deliver it // immediately. deliverResult(mPerms); } // Start watching for changes in the app data. if (mPackageObserver == null) { mPackageObserver = new PackageIntentReceiver(this); } if (takeContentChanged() || mPerms == null) { // If the data has changed since the last time it was loaded // or is not currently available, start a load. forceLoad(); } } /** * Handles a request to stop the Loader. */ @Override protected void onStopLoading() { // Attempt to cancel the current load task if possible. cancelLoad(); } } private void setListShown(boolean shown) { if (shown) { mListView.setVisibility(View.VISIBLE); mProgressContainer.setVisibility(View.GONE); } else { mListView.setVisibility(View.GONE); mProgressContainer.setVisibility(View.VISIBLE); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContentView = inflater.inflate(R.layout.perm_fragment, null); mProgressContainer = (LinearLayout) mContentView.findViewById(R.id.progressContainer); //TextView emptyView = (TextView)mContentView.findViewById(com.android.internal.R.id.empty); //emptyView.setText("No Permissions!"); ListView lv = (ListView) mContentView.findViewById(android.R.id.list); //if (emptyView != null) { // lv.setEmptyView(emptyView); //} lv.setOnItemClickListener(this); lv.setSaveEnabled(true); lv.setItemsCanFocus(true); lv.setTextFilterEnabled(true); mListView = lv; return mContentView; } //just for parent activity to refresh this fragment public void onRefreshUi() { //load(); this.getLoaderManager().getLoader(0).onContentChanged(); } @Override public void onResume() { super.onResume(); //load(); onRefreshUi(); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mActivity = getActivity(); mPm = mActivity.getPackageManager(); mAppOps = (AppOpsManager)getActivity().getSystemService(Context.APP_OPS_SERVICE); mState = new AppOpsState(getActivity()); for(int index = 0; index < AppOpsState2.ALL_TEMPLATES.length; index ++){ AppOpsState2 state = new AppOpsState2(getActivity()); mStates.add(state); } mListView.setFastScrollEnabled(true); mAdapter = new PermListAdapter(getActivity()); mListView.setAdapter(mAdapter); // We have a menu item to show in action bar. setHasOptionsMenu(true); setListShown(false); // Prepare the loader. getLoaderManager().initLoader(0, null, this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ListView l = (ListView) parent; PermInfo info = (PermInfo) l.getAdapter().getItem(position); String permName = info.getLabel(); Intent intent = new Intent(); intent.putExtra("tplIndex", position); intent.setClass(getActivity(), PermToAppsActivity.class); startActivity(intent); } @Override public Loader<List<PermInfo>> onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader with no arguments, so it is simple. return new PermListLoader(getActivity()); } @Override public void onLoadFinished(Loader<List<PermInfo>> loader, List<PermInfo> data) { // Set the new data in the adapter. mAdapter.setDataAndNotify(data); // The list should now be shown. setListShown(true); } @Override public void onLoaderReset(Loader<List<PermInfo>> loader) { // Clear the data in the adapter. mAdapter.setDataAndNotify(null); //setApdaterData(null); //mAdapter.setDataAndNotify(list) } // View Holder used when displaying views static class AppViewHolder { ImageView mPermIcon; TextView mPermLabel; TextView mAppCount; } }