From 0f9daab75f1557722b6e687a68eebfd5d28cbc51 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 30 Jul 2010 14:26:37 -0700 Subject: [PATCH] Manage apps "third party" and "on sd card" filters were swapped. Also change the app details screen to make use of the common ApplicationsState object for its UI, improving launch performance. Change-Id: I387ed72a06d44aab47a85692c10247ce488c605c --- .../applications/ApplicationsState.java | 41 +- .../applications/InstalledAppDetails.java | 436 ++++++++---------- 2 files changed, 233 insertions(+), 244 deletions(-) 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); } } }