Enable move option for moving packages from internal to sdcard

This commit is contained in:
Suchi Amalapurapu
2010-02-19 14:30:01 -08:00
parent 03878a4a08
commit ad1482712d
3 changed files with 59 additions and 4 deletions

View File

@@ -39,6 +39,7 @@
<uses-permission android:name="android.permission.BATTERY_STATS"/> <uses-permission android:name="android.permission.BATTERY_STATS"/>
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.MOVE_PACKAGE" />
<application android:label="@string/settings_label" <application android:label="@string/settings_label"
android:icon="@drawable/ic_launcher_settings" android:icon="@drawable/ic_launcher_settings"

View File

@@ -1628,6 +1628,8 @@ found in the list of installed applications.</string>
<!-- Manage applications, text for Move button to move app to sdcard --> <!-- Manage applications, text for Move button to move app to sdcard -->
<string name="move_app_to_sdcard">Move to sdcard</string> <string name="move_app_to_sdcard">Move to sdcard</string>
<!-- Manage applications, title for dialog when killing persistent apps--> <!-- Manage applications, title for dialog when killing persistent apps-->
<!-- Manage applications, text for Move button when move is in progress -->
<string name="moving">Moving</string>
<string name="force_stop_dlg_title">Force Stop</string> <string name="force_stop_dlg_title">Force Stop</string>
<!-- Manage applications, text for dialog when killing persistent apps--> <!-- Manage applications, text for dialog when killing persistent apps-->
<string name="force_stop_dlg_text">This application will be restarted right way. Are you sure you want to force stop?</string> <string name="force_stop_dlg_text">This application will be restarted right way. Are you sure you want to force stop?</string>

View File

@@ -31,6 +31,7 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver; import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver; import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -87,6 +88,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
PackageStats mSizeInfo; PackageStats mSizeInfo;
private PackageManager mPm; private PackageManager mPm;
private PackageMoveObserver mPackageMoveObserver;
//internal constants used in Handler //internal constants used in Handler
private static final int OP_SUCCESSFUL = 1; private static final int OP_SUCCESSFUL = 1;
@@ -94,6 +96,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
private static final int CLEAR_USER_DATA = 1; private static final int CLEAR_USER_DATA = 1;
private static final int GET_PKG_SIZE = 2; private static final int GET_PKG_SIZE = 2;
private static final int CLEAR_CACHE = 3; private static final int CLEAR_CACHE = 3;
private static final int PACKAGE_MOVE = 4;
private static final String ATTR_PACKAGE_STATS="PackageStats"; private static final String ATTR_PACKAGE_STATS="PackageStats";
// invalid size value used initially and also when size retrieval through PackageManager // invalid size value used initially and also when size retrieval through PackageManager
@@ -125,6 +128,9 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
// Refresh size info // Refresh size info
mPm.getPackageSizeInfo(mAppInfo.packageName, mSizeObserver); mPm.getPackageSizeInfo(mAppInfo.packageName, mSizeObserver);
break; break;
case PACKAGE_MOVE:
processMoveMsg(msg);
break;
default: default:
break; break;
} }
@@ -153,10 +159,18 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
class ClearCacheObserver extends IPackageDataObserver.Stub { class ClearCacheObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(final String packageName, final boolean succeeded) { public void onRemoveCompleted(final String packageName, final boolean succeeded) {
final Message msg = mHandler.obtainMessage(CLEAR_CACHE); final Message msg = mHandler.obtainMessage(CLEAR_CACHE);
msg.arg1 = succeeded?OP_SUCCESSFUL:OP_FAILED; msg.arg1 = succeeded ? OP_SUCCESSFUL:OP_FAILED;
mHandler.sendMessage(msg); mHandler.sendMessage(msg);
} }
} }
class PackageMoveObserver extends IPackageMoveObserver.Stub {
public void packageMoved(String packageName, int returnCode) throws RemoteException {
final Message msg = mHandler.obtainMessage(PACKAGE_MOVE);
msg.arg1 = returnCode;
mHandler.sendMessage(msg);
}
}
private String getSizeStr(long size) { private String getSizeStr(long size) {
if (size == SIZE_INVALID) { if (size == SIZE_INVALID) {
@@ -172,23 +186,36 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
mClearDataButton.setText(R.string.clear_user_data_text); mClearDataButton.setText(R.string.clear_user_data_text);
} }
mClearDataButton.setOnClickListener(this); mClearDataButton.setOnClickListener(this);
initMoveButton();
}
private void initMoveButton() {
String pkgName = mAppInfo.packageName; String pkgName = mAppInfo.packageName;
boolean dataOnly = false; boolean dataOnly = false;
ApplicationInfo info1 = null; ApplicationInfo info1 = null;
ApplicationInfo info2 = null;
try { try {
info1 = mPm.getApplicationInfo(pkgName, 0); info1 = mPm.getApplicationInfo(pkgName, 0);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
} }
dataOnly = (info1 == null) && (mAppInfo != null); dataOnly = (info1 == null) && (mAppInfo != null);
boolean moveDisable = true;
if (dataOnly) { if (dataOnly) {
mMoveAppButton.setText(R.string.move_app); mMoveAppButton.setText(R.string.move_app);
} else if ((mAppInfo.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0) { } else if ((mAppInfo.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0) {
mMoveAppButton.setText(R.string.move_app_to_internal); mMoveAppButton.setText(R.string.move_app_to_internal);
moveDisable = false;
} else { } else {
moveDisable = (mAppInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0 ||
(mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
mMoveAppButton.setText(R.string.move_app_to_sdcard); mMoveAppButton.setText(R.string.move_app_to_sdcard);
} }
if (moveDisable) {
mMoveAppButton.setEnabled(false);
} else {
mMoveAppButton.setOnClickListener(this);
mMoveAppButton.setEnabled(true);
}
} }
private void initControlButtons() { private void initControlButtons() {
@@ -270,8 +297,6 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
View data_buttons_panel = findViewById(R.id.data_buttons_panel); View data_buttons_panel = findViewById(R.id.data_buttons_panel);
mClearDataButton = (Button) data_buttons_panel.findViewById(R.id.left_button); mClearDataButton = (Button) data_buttons_panel.findViewById(R.id.left_button);
mMoveAppButton = (Button) data_buttons_panel.findViewById(R.id.right_button); mMoveAppButton = (Button) data_buttons_panel.findViewById(R.id.right_button);
// Disable move for now
mMoveAppButton.setEnabled(false);
// Cache section // Cache section
mCacheSize = (TextView) findViewById(R.id.cache_size_text); mCacheSize = (TextView) findViewById(R.id.cache_size_text);
mCacheSize.setText(mComputingStr); mCacheSize.setText(mComputingStr);
@@ -444,6 +469,24 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
mClearDataButton.setEnabled(true); mClearDataButton.setEnabled(true);
} }
} }
private void processMoveMsg(Message msg) {
int result = msg.arg1;
String packageName = mAppInfo.packageName;
if(result == PackageManager.MOVE_SUCCEEDED) {
Log.i(TAG, "Moved resources for " + packageName);
try {
// Reset flags
mAppInfo = mPm.getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
initMoveButton();
} catch (NameNotFoundException e) {
// TODO error handling
}
} else {
// TODO Present a dialog indicating failure.
}
}
/* /*
* Private method to initiate clearing user data when the user clicks the clear data * Private method to initiate clearing user data when the user clicks the clear data
@@ -601,6 +644,15 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene
// that the button cannot be enabled or disabled since // that the button cannot be enabled or disabled since
// we do not have this info for now. // we do not have this info for now.
forceStopPackage(mAppInfo.packageName); forceStopPackage(mAppInfo.packageName);
} else if (v == mMoveAppButton) {
if (mPackageMoveObserver == null) {
mPackageMoveObserver = new PackageMoveObserver();
}
int moveFlags = (mAppInfo.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0 ?
PackageManager.MOVE_INTERNAL : PackageManager.MOVE_EXTERNAL_MEDIA;
mMoveAppButton.setText(R.string.moving);
mMoveAppButton.setEnabled(false);
mPm.movePackage(mAppInfo.packageName, mPackageMoveObserver, moveFlags);
} }
} }
} }