diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java index f01743a8bf9..1f94d0ae924 100644 --- a/src/com/android/settings/applications/ApplicationsState.java +++ b/src/com/android/settings/applications/ApplicationsState.java @@ -67,6 +67,10 @@ public class ApplicationsState { final String label; final long id; long size; + + long cacheSize; + long codeSize; + long dataSize; String getNormalizedLabel() { if (normalizedLabel != null) { @@ -116,7 +120,9 @@ public class ApplicationsState { public static final AppFilter THIRD_PARTY_FILTER = new AppFilter() { @Override public boolean filterApp(ApplicationInfo info) { - if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { + if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { + return true; + } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { return true; } return false; @@ -126,9 +132,7 @@ public class ApplicationsState { public static final AppFilter ON_SD_CARD_FILTER = new AppFilter() { @Override public boolean filterApp(ApplicationInfo info) { - if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { - return true; - } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { return true; } return false; @@ -195,9 +199,10 @@ public class ApplicationsState { // Ignore return; } + boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr); for (String pkgName : pkgList) { - removePackage(pkgName); - addPackage(pkgName); + if (avail) addPackage(pkgName); + else removePackage(pkgName); } } } @@ -316,6 +321,22 @@ public class ApplicationsState { return filteredApps; } + AppEntry getEntry(String packageName) { + synchronized (mEntriesMap) { + AppEntry entry = mEntriesMap.get(packageName); + if (entry == null) { + for (int i=0; i homes = mPm.queryIntentActivities(intent, 0); - if ((homes != null && homes.size() > 0) - || sys.signatures[0].equals(pi.signatures[0])) { + if ((homes != null && homes.size() > 0) || + (mPackageInfo != null && + sys.signatures[0].equals(mPackageInfo.signatures[0]))) { // Disable button for core system applications. mUninstallButton.setText(R.string.disable_text); - } else if (mAppInfo.enabled) { + } else if (mAppEntry.info.enabled) { mUninstallButton.setText(R.string.disable_text); enabled = true; } else { @@ -323,49 +295,22 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene } } - private boolean initAppInfo(String packageName) { - try { - mAppInfo = mPm.getApplicationInfo(packageName, - PackageManager.GET_UNINSTALLED_PACKAGES); - return true; - } catch (NameNotFoundException e) { - Log.e(TAG, "Exception when retrieving package: " + packageName, e); - showDialogInner(DLG_APP_NOT_FOUND); - return false; - } - } - /** Called when the activity is first created. */ @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); - // Get package manager + mState = ApplicationsState.getInstance(getApplication()); mPm = getPackageManager(); - // Get application's name from intent - Intent intent = getIntent(); - final String packageName = intent.getData().getSchemeSpecificPart(); - if (! initAppInfo(packageName)) { - return; // could not find package, finish called - } - - // Try retrieving package stats again - CharSequence totalSizeStr, appSizeStr, dataSizeStr; - mComputingStr = getText(R.string.computing_size); - totalSizeStr = appSizeStr = dataSizeStr = mComputingStr; - if(localLOGV) Log.i(TAG, "Have to compute package sizes"); - mSizeObserver = new PkgSizeObserver(); setContentView(R.layout.installed_app_details); - //TODO download str and download url + + mComputingStr = getText(R.string.computing_size); // Set default values on sizes 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); // Get Control button panel View btnPanel = findViewById(R.id.control_buttons_panel); @@ -379,51 +324,22 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene mClearDataButton = (Button) data_buttons_panel.findViewById(R.id.left_button); mMoveAppButton = (Button) data_buttons_panel.findViewById(R.id.right_button); - // Cache section - mCacheSize = (TextView) findViewById(R.id.cache_size_text); - mCacheSize.setText(mComputingStr); - mClearCacheButton = (Button) findViewById(R.id.clear_cache_button); - - // Get list of preferred activities - mActivitiesButton = (Button)findViewById(R.id.clear_activities_button); - List prefActList = new ArrayList(); - - // Intent list cannot be null. so pass empty list - List intentList = new ArrayList(); - 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); - } + // Cache section + mCacheSize = (TextView) findViewById(R.id.cache_size_text); + mClearCacheButton = (Button) findViewById(R.id.clear_cache_button); + + mActivitiesButton = (Button)findViewById(R.id.clear_activities_button); } // Utility method to set applicaiton label and icon. private void setAppLabelAndIcon(PackageInfo pkgInfo) { View appSnippet = findViewById(R.id.app_snippet); ImageView icon = (ImageView) appSnippet.findViewById(R.id.app_icon); - icon.setImageDrawable(mAppInfo.loadIcon(mPm)); + mState.ensureIcon(mAppEntry); + icon.setImageDrawable(mAppEntry.icon); // Set application name. TextView label = (TextView) appSnippet.findViewById(R.id.app_name); - label.setText(mAppInfo.loadLabel(mPm)); + label.setText(mAppEntry.label); // Version number of application mAppVersion = (TextView) appSnippet.findViewById(R.id.app_size); @@ -440,35 +356,105 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene public void onResume() { super.onResume(); - if (mAppInfo == null) { + mState.resume(this); + if (!refreshUi()) { setIntentAndFinish(true, true); - return; // onCreate must have failed, make sure to exit - } - if (! initAppInfo(mAppInfo.packageName)) { - return; // could not find package, finish called - } - - PackageInfo pkgInfo = null; - // Get application info again to refresh changed properties of application - try { - pkgInfo = mPm.getPackageInfo(mAppInfo.packageName, - PackageManager.GET_UNINSTALLED_PACKAGES); - } catch (NameNotFoundException e) { - Log.e(TAG, "Exception when retrieving package:" + mAppInfo.packageName, e); - showDialogInner(DLG_APP_NOT_FOUND); - return; // could not find package, finish called - } - - checkForceStop(); - setAppLabelAndIcon(pkgInfo); - refreshButtons(); - - // Refresh size info - if (mAppInfo != null && mAppInfo.packageName != null) { - mPm.getPackageSizeInfo(mAppInfo.packageName, mSizeObserver); } } + @Override + public void onPause() { + super.onPause(); + mState.pause(); + } + + @Override + public void onAllSizesComputed() { + } + + @Override + public void onPackageIconChanged() { + } + + @Override + public void onPackageListChanged() { + refreshUi(); + } + + @Override + public void onPackageSizeChanged(String packageName) { + if (packageName.equals(mAppEntry.info.packageName)) { + refreshSizeInfo(); + } + } + + @Override + public void onRunningStateChanged(boolean running) { + } + + private boolean refreshUi() { + if (mMoveInProgress) { + return true; + } + + Intent intent = getIntent(); + final String packageName = intent.getData().getSchemeSpecificPart(); + mAppEntry = mState.getEntry(packageName); + + if (mAppEntry == null) { + return false; // onCreate must have failed, make sure to exit + } + + // Get application info again to refresh changed properties of application + try { + mPackageInfo = mPm.getPackageInfo(mAppEntry.info.packageName, + PackageManager.GET_DISABLED_COMPONENTS | + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_SIGNATURES); + } catch (NameNotFoundException e) { + Log.e(TAG, "Exception when retrieving package:" + mAppEntry.info.packageName, e); + return false; // onCreate must have failed, make sure to exit + } + + // Get list of preferred activities + List prefActList = new ArrayList(); + + // Intent list cannot be null. so pass empty list + List intentList = new ArrayList(); + 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.setEnabled(true); + 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.removeAllViews(); + securityList.addView(asp.getPermissionsView()); + } else { + permsView.setVisibility(View.GONE); + } + + checkForceStop(); + setAppLabelAndIcon(mPackageInfo); + refreshButtons(); + refreshSizeInfo(); + return true; + } + private void setIntentAndFinish(boolean finish, boolean appChanged) { if(localLOGV) Log.i(TAG, "appChanged="+appChanged); Intent intent = new Intent(); @@ -479,60 +465,50 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene } } - /* - * Private method to handle get size info notification from observer when - * the async operation from PackageManager is complete. The current user data - * info has to be refreshed in the manage applications screen as well as the current screen. - */ - private void refreshSizeInfo(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); - 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); - changed = true; + private void refreshSizeInfo() { + if (mAppEntry.size == ApplicationsState.SIZE_INVALID + || mAppEntry.size == ApplicationsState.SIZE_UNKNOWN) { + mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1; + if (!mHaveSizes) { + mAppSize.setText(mComputingStr); + mDataSize.setText(mComputingStr); + mCacheSize.setText(mComputingStr); + mTotalSize.setText(mComputingStr); } - 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; - } - } - // If data size is zero disable clear data button - if (newPs.dataSize == 0) { mClearDataButton.setEnabled(false); - } - long data = mSizeInfo.dataSize; - refreshCacheInfo(newPs.cacheSize); - } - - private void refreshCacheInfo(long cacheSize) { - // Set cache info - mCacheSize.setText(getSizeStr(cacheSize)); - if (cacheSize <= 0) { mClearCacheButton.setEnabled(false); + } else { - mClearCacheButton.setOnClickListener(this); + mHaveSizes = true; + if (mLastCodeSize != mAppEntry.codeSize) { + mLastCodeSize = mAppEntry.codeSize; + mAppSize.setText(getSizeStr(mAppEntry.codeSize)); + } + if (mLastDataSize != mAppEntry.dataSize) { + mLastDataSize = mAppEntry.dataSize; + mDataSize.setText(getSizeStr(mAppEntry.dataSize)); + } + if (mLastCacheSize != mAppEntry.cacheSize) { + mLastCacheSize = mAppEntry.cacheSize; + mCacheSize.setText(getSizeStr(mAppEntry.cacheSize)); + } + if (mLastTotalSize != mAppEntry.size) { + mLastTotalSize = mAppEntry.size; + mTotalSize.setText(getSizeStr(mAppEntry.size)); + } + + if (mAppEntry.dataSize <= 0) { + mClearDataButton.setEnabled(false); + } else { + mClearDataButton.setEnabled(true); + mClearDataButton.setOnClickListener(this); + } + if (mAppEntry.cacheSize <= 0) { + mClearCacheButton.setEnabled(false); + } else { + mClearCacheButton.setEnabled(true); + mClearCacheButton.setOnClickListener(this); + } } } @@ -542,11 +518,11 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene */ private void processClearMsg(Message msg) { int result = msg.arg1; - String packageName = mAppInfo.packageName; + String packageName = mAppEntry.info.packageName; mClearDataButton.setText(R.string.clear_user_data_text); if(result == OP_SUCCESSFUL) { Log.i(TAG, "Cleared user data for package : "+packageName); - mPm.getPackageSizeInfo(packageName, mSizeObserver); + mState.requestSize(mAppEntry.info.packageName); } else { mClearDataButton.setEnabled(true); } @@ -567,23 +543,18 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene private void processMoveMsg(Message msg) { int result = msg.arg1; - String packageName = mAppInfo.packageName; + String packageName = mAppEntry.info.packageName; // Refresh the button attributes. mMoveInProgress = false; - if(result == PackageManager.MOVE_SUCCEEDED) { + if (result == PackageManager.MOVE_SUCCEEDED) { Log.i(TAG, "Moved resources for " + packageName); // Refresh size information again. - mPm.getPackageSizeInfo(packageName, mSizeObserver); + mState.requestSize(mAppEntry.info.packageName); } else { mMoveErrorCode = result; showDialogInner(DLG_MOVE_FAILED); } - - if (! initAppInfo(packageName)) { - return; // could not find package, finish called - } - - refreshButtons(); + refreshUi(); } /* @@ -593,14 +564,14 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene private void initiateClearUserData() { mClearDataButton.setEnabled(false); // Invoke uninstall or clear user data based on sysPackage - String packageName = mAppInfo.packageName; + String packageName = mAppEntry.info.packageName; Log.i(TAG, "Clearing user data for package : " + packageName); - if(mClearDataObserver == null) { + if (mClearDataObserver == null) { mClearDataObserver = new ClearUserDataObserver(); } ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); boolean res = am.clearApplicationUserData(packageName, mClearDataObserver); - if(!res) { + if (!res) { // Clearing data failed for some obscure reason. Just log error for now Log.i(TAG, "Couldnt clear application user data for package:"+packageName); showDialogInner(DLG_CANNOT_CLEAR_DATA); @@ -640,7 +611,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // Clear user data here - uninstallPkg(mAppInfo.packageName); + uninstallPkg(mAppEntry.info.packageName); } }) .setNegativeButton(R.string.dlg_cancel, null) @@ -681,7 +652,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // Force stop - forceStopPackage(mAppInfo.packageName); + forceStopPackage(mAppEntry.info.packageName); } }) .setNegativeButton(R.string.dlg_cancel, null) @@ -724,9 +695,9 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene private void checkForceStop() { Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, - Uri.fromParts("package", mAppInfo.packageName, null)); - intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppInfo.packageName }); - intent.putExtra(Intent.EXTRA_UID, mAppInfo.uid); + Uri.fromParts("package", mAppEntry.info.packageName, null)); + intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName }); + intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid); sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); } @@ -749,16 +720,6 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0); return null; } - - @Override - protected void onPostExecute(Object result) { - InstalledAppDetails activity = mActivity.get(); - if (activity != null) { - activity.initAppInfo(mInfo.packageName); - activity.checkForceStop(); - activity.refreshButtons(); - } - } } /* @@ -766,13 +727,13 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene * @see android.view.View.OnClickListener#onClick(android.view.View) */ public void onClick(View v) { - String packageName = mAppInfo.packageName; + String packageName = mAppEntry.info.packageName; if(v == mUninstallButton) { if (mUpdatedSysApp) { showDialogInner(DLG_FACTORY_RESET); } else { - if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - new DisableChanger(this, mAppInfo, mAppInfo.enabled ? + if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + new DisableChanger(this, mAppEntry.info, mAppEntry.info.enabled ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).execute((Object)null); } else { @@ -783,9 +744,10 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene mPm.clearPackagePreferredActivities(packageName); mActivitiesButton.setEnabled(false); } else if(v == mClearDataButton) { - if (mAppInfo.manageSpaceActivityName != null) { + if (mAppEntry.info.manageSpaceActivityName != null) { Intent intent = new Intent(Intent.ACTION_DEFAULT); - intent.setClassName(mAppInfo.packageName, mAppInfo.manageSpaceActivityName); + intent.setClassName(mAppEntry.info.packageName, + mAppEntry.info.manageSpaceActivityName); startActivityForResult(intent, -1); } else { showDialogInner(DLG_CLEAR_DATA); @@ -803,11 +765,11 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene if (mPackageMoveObserver == null) { mPackageMoveObserver = new PackageMoveObserver(); } - int moveFlags = (mAppInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ? + int moveFlags = (mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ? PackageManager.MOVE_INTERNAL : PackageManager.MOVE_EXTERNAL_MEDIA; mMoveInProgress = true; refreshButtons(); - mPm.movePackage(mAppInfo.packageName, mPackageMoveObserver, moveFlags); + mPm.movePackage(mAppEntry.info.packageName, mPackageMoveObserver, moveFlags); } } }