FileDocCategorySizeDatePackage
InstalledAppDetails.javaAPI DocAndroid 1.5 API19610Wed May 06 22:42:48 BST 2009com.android.settings

InstalledAppDetails

public class InstalledAppDetails extends android.app.Activity implements DialogInterface.OnClickListener, View.OnClickListener
Activity to display application information from Settings. This activity presents extended information associated with a package like code, data, total size, permissions used by the application and also the set of default launchable activities. For system applications, an option to clear user data is displayed only if data size is > 0. System applications that do not want clear user data do not have this option. For non-system applications, there is no option to clear data. Instead there is an option to uninstall the application.

Fields Summary
private static final String
TAG
private static final int
_UNKNOWN_APP
private android.content.pm.ApplicationInfo
mAppInfo
private android.widget.Button
mAppButton
private android.widget.Button
mActivitiesButton
private boolean
mCanUninstall
private boolean
localLOGV
private android.widget.TextView
mAppSnippetSize
private android.widget.TextView
mTotalSize
private android.widget.TextView
mAppSize
private android.widget.TextView
mDataSize
private PkgSizeObserver
mSizeObserver
private ClearUserDataObserver
mClearDataObserver
private android.view.View
mCachePanel
private android.widget.TextView
mCacheSize
private android.widget.Button
mClearCacheButton
private ClearCacheObserver
mClearCacheObserver
private android.widget.Button
mForceStopButton
android.content.pm.PackageStats
mSizeInfo
private android.widget.Button
mManageSpaceButton
private android.content.pm.PackageManager
mPm
private static final int
OP_SUCCESSFUL
private static final int
OP_FAILED
private static final int
CLEAR_USER_DATA
private static final int
GET_PKG_SIZE
private static final int
CLEAR_CACHE
private static final String
ATTR_PACKAGE_STATS
private static final int
SIZE_INVALID
private CharSequence
mInvalidSizeStr
private CharSequence
mComputingStr
private CharSequence
mAppButtonText
private AppButtonStates
mAppButtonState
private android.os.Handler
mHandler
Constructors Summary
Methods Summary
private voiddisplayErrorDialog(int msgId, boolean finish, boolean changed)

        //display confirmation dialog
        new AlertDialog.Builder(this)
        .setTitle(getString(R.string.app_not_found_dlg_title))
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setMessage(getString(msgId))
        .setNeutralButton(getString(R.string.dlg_ok), 
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        //force to recompute changed value
                        setIntentAndFinish(finish, changed);
                    }
                }
        )
        .show();
    
private java.lang.StringgetSizeStr(long size)

        if (size == SIZE_INVALID) {
            return mInvalidSizeStr.toString();
        }
        return Formatter.formatFileSize(this, size);
    
private voidinitiateClearUserDataForSysPkg()

        mAppButton.setEnabled(false);
        //invoke uninstall or clear user data based on sysPackage
        String packageName = mAppInfo.packageName;
        Log.i(TAG, "Clearing user data for system package");
        if(mClearDataObserver == null) {
            mClearDataObserver = new ClearUserDataObserver();
        }
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
        if(!res) {
            //doesnt initiate clear. some error. should not happen but just log error for now
            Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
            displayErrorDialog(R.string.clear_data_failed, false, false);
        } else {
                mAppButton.setText(R.string.recompute_size);
        }
    
private booleanisUninstallable()

    
       
        if (((mAppInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) && 
                ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0)) {
            return false;
        }
        return true;
    
public voidonClick(android.view.View v)

        String packageName = mAppInfo.packageName;
        if(v == mAppButton) {
            if(mCanUninstall) {
                //display confirmation dialog
                new AlertDialog.Builder(this)
                .setTitle(getString(R.string.clear_data_dlg_title))
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setMessage(getString(R.string.clear_data_dlg_text))
                .setPositiveButton(R.string.dlg_ok, this)
                .setNegativeButton(R.string.dlg_cancel, this)
                .show();
            } else {
                //create new intent to launch Uninstaller activity
                Uri packageURI = Uri.parse("package:"+packageName);
                Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
                startActivity(uninstallIntent);
                setIntentAndFinish(true, true);
            }
        } else if(v == mActivitiesButton) {
            mPm.clearPackagePreferredActivities(packageName);
            mActivitiesButton.setEnabled(false);
        } else if(v == mManageSpaceButton) {
            Intent intent = new Intent(Intent.ACTION_DEFAULT);
            intent.setClassName(mAppInfo.packageName, mAppInfo.manageSpaceActivityName);
            startActivityForResult(intent, -1);
        } else if (v == mClearCacheButton) {
            // Lazy initialization of observer
            if (mClearCacheObserver == null) {
                mClearCacheObserver = new ClearCacheObserver();
            }
            mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver);
        } else if (v == mForceStopButton) {
            ActivityManager am = (ActivityManager)getSystemService(
                    Context.ACTIVITY_SERVICE);
            am.restartPackage(packageName);
        }
    
public voidonClick(android.content.DialogInterface dialog, int which)

        if(which == AlertDialog.BUTTON_POSITIVE) {
            //invoke uninstall or clear user data based on sysPackage
            initiateClearUserDataForSysPkg();
        } else {
            //cancel do nothing just retain existing screen
        }
    
protected voidonCreate(android.os.Bundle icicle)
Called when the activity is first created.

        super.onCreate(icicle);
        //get package manager
        mPm = getPackageManager();
        //get application's name from intent
        Intent intent = getIntent();
        final String packageName = intent.getStringExtra(ManageApplications.APP_PKG_NAME);
        mComputingStr = getText(R.string.computing_size);
        // Try retrieving package stats again
        CharSequence totalSizeStr, appSizeStr, dataSizeStr;
        totalSizeStr = appSizeStr = dataSizeStr = mComputingStr;
        if(localLOGV) Log.i(TAG, "Have to compute package sizes");
        mSizeObserver = new PkgSizeObserver();
        mPm.getPackageSizeInfo(packageName, mSizeObserver);

        try {
            mAppInfo = mPm.getApplicationInfo(packageName, 
                    PackageManager.GET_UNINSTALLED_PACKAGES);
        } catch (NameNotFoundException e) {
            Log.e(TAG, "Exception when retrieving package:"+packageName, e);
            displayErrorDialog(R.string.app_not_found_dlg_text, true, true);
        }
        setContentView(R.layout.installed_app_details);       
        ((ImageView)findViewById(R.id.app_icon)).setImageDrawable(mAppInfo.loadIcon(mPm));
        //set application name TODO version
        CharSequence appName = mAppInfo.loadLabel(mPm);
        if(appName == null) {
            appName = getString(_UNKNOWN_APP);
        }
        ((TextView)findViewById(R.id.app_name)).setText(appName);
        mAppSnippetSize = ((TextView)findViewById(R.id.app_size));
        mAppSnippetSize.setText(totalSizeStr);
        //TODO download str and download url
        //set values on views
        mTotalSize = (TextView)findViewById(R.id.total_size_text);
        mTotalSize.setText(totalSizeStr);
        mAppSize = (TextView)findViewById(R.id.application_size_text);
        mAppSize.setText(appSizeStr);
        mDataSize = (TextView)findViewById(R.id.data_size_text);
        mDataSize.setText(dataSizeStr);
         
         mAppButton = ((Button)findViewById(R.id.uninstall_button));
        //determine if app is a system app
         mCanUninstall = !isUninstallable();
         if(localLOGV) Log.i(TAG, "Is systemPackage "+mCanUninstall);
         setAppBtnState();
         mManageSpaceButton = (Button)findViewById(R.id.manage_space_button);
         if(mAppInfo.manageSpaceActivityName != null) {
             mManageSpaceButton.setVisibility(View.VISIBLE);
             mManageSpaceButton.setOnClickListener(this);
         }
         
         // Cache section
         mCachePanel = findViewById(R.id.cache_panel);
         mCacheSize = (TextView) findViewById(R.id.cache_size_text);
         mCacheSize.setText(mComputingStr);
         mClearCacheButton = (Button) findViewById(R.id.clear_cache_button);
         mForceStopButton = (Button) findViewById(R.id.force_stop_button);
         mForceStopButton.setOnClickListener(this);
         
         //clear activities
         mActivitiesButton = (Button)findViewById(R.id.clear_activities_button);
         List<ComponentName> prefActList = new ArrayList<ComponentName>();
         //intent list cannot be null. so pass empty list
         List<IntentFilter> intentList = new ArrayList<IntentFilter>();
         mPm.getPreferredActivities(intentList,  prefActList, packageName);
         if(localLOGV) Log.i(TAG, "Have "+prefActList.size()+" number of activities in prefered list");
         TextView autoLaunchView = (TextView)findViewById(R.id.auto_launch);
         if(prefActList.size() <= 0) {
             //disable clear activities button
             autoLaunchView.setText(R.string.auto_launch_disable_text);
             mActivitiesButton.setEnabled(false);
         } else {
             autoLaunchView.setText(R.string.auto_launch_enable_text);
             mActivitiesButton.setOnClickListener(this);
         }
         
         // security permissions section
         LinearLayout permsView = (LinearLayout) findViewById(R.id.permissions_section);
         AppSecurityPermissions asp = new AppSecurityPermissions(this, packageName);
         if(asp.getPermissionCount() > 0) {
             permsView.setVisibility(View.VISIBLE);
             // Make the security sections header visible
             LinearLayout securityList = (LinearLayout) permsView.findViewById(
                     R.id.security_settings_list);
             securityList.addView(asp.getPermissionsView());
         } else {
             permsView.setVisibility(View.GONE);
         }
    
private voidprocessClearMsg(android.os.Message msg)

        int result = msg.arg1;
        String packageName = mAppInfo.packageName;
        if(result == OP_SUCCESSFUL) {
            Log.i(TAG, "Cleared user data for system package:"+packageName);
            mPm.getPackageSizeInfo(packageName, mSizeObserver);
        } else {
            mAppButton.setText(R.string.clear_user_data_text);
            mAppButton.setEnabled(true);
        }
    
private voidrefreshCacheInfo(long cacheSize)

        // Set cache info
        mCacheSize.setText(getSizeStr(cacheSize));
        if (cacheSize <= 0) {
            mClearCacheButton.setEnabled(false);
        } else {
            mClearCacheButton.setOnClickListener(this);
        }
    
private voidrefreshSizeInfo(android.os.Message msg)

        boolean changed = false;
        PackageStats newPs = msg.getData().getParcelable(ATTR_PACKAGE_STATS);
        long newTot = newPs.cacheSize+newPs.codeSize+newPs.dataSize;
        if(mSizeInfo == null) {
            mSizeInfo = newPs;
            String str = getSizeStr(newTot);
            mTotalSize.setText(str);
            mAppSnippetSize.setText(str);
            mAppSize.setText(getSizeStr(newPs.codeSize));
            mDataSize.setText(getSizeStr(newPs.dataSize));
            mCacheSize.setText(getSizeStr(newPs.cacheSize));
        } else {
            long oldTot = mSizeInfo.cacheSize+mSizeInfo.codeSize+mSizeInfo.dataSize;
            if(newTot != oldTot) {
                String str = getSizeStr(newTot);
                mTotalSize.setText(str);
                mAppSnippetSize.setText(str);
                changed = true;
            }
            if(newPs.codeSize != mSizeInfo.codeSize) {
                mAppSize.setText(getSizeStr(newPs.codeSize));
                changed = true;
            }
            if(newPs.dataSize != mSizeInfo.dataSize) {
                mDataSize.setText(getSizeStr(newPs.dataSize));
                changed = true;
            }
            if(newPs.cacheSize != mSizeInfo.cacheSize) {
                mCacheSize.setText(getSizeStr(newPs.cacheSize));
                changed = true;
            }
            if(changed) {
                mSizeInfo = newPs;
            }
        }
        
        long data = mSizeInfo.dataSize;
        // Disable button if data is 0
        if(mAppButtonState != AppButtonStates.NONE){
            mAppButton.setText(mAppButtonText);
            if((mAppButtonState == AppButtonStates.CLEAR_DATA) && (data == 0)) {
                mAppButton.setEnabled(false);
            } else {
                mAppButton.setEnabled(true);
                mAppButton.setOnClickListener(this);
            }            
        }
        refreshCacheInfo(newPs.cacheSize);
    
private voidsetAppBtnState()

        boolean visible = false;
        if(mCanUninstall) {
            //app can clear user data
            if((mAppInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 
                    == ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) {
                mAppButtonText = getText(R.string.clear_user_data_text);
               mAppButtonState = AppButtonStates.CLEAR_DATA;
               visible = true;
            } else {
                //hide button if diableClearUserData is set
                visible = false;
                mAppButtonState = AppButtonStates.NONE;
            }
        } else {
            visible = true;
            mAppButtonState = AppButtonStates.UNINSTALL;
            mAppButtonText = getText(R.string.uninstall_text);
        }
        if(visible) {
            mAppButton.setText(mAppButtonText);
            mAppButton.setVisibility(View.VISIBLE);
        } else {
            mAppButton.setVisibility(View.GONE);
        }
    
private voidsetIntentAndFinish(boolean finish, boolean appChanged)

        if(localLOGV) Log.i(TAG, "appChanged="+appChanged);
        Intent intent = new Intent();
        intent.putExtra(ManageApplications.APP_CHG, appChanged);
        setResult(ManageApplications.RESULT_OK, intent);
        mAppButton.setEnabled(false);
        if(finish) {
            finish();
        }