OSDN Git Service

Start fragmentizing Manage Applications.
authorDianne Hackborn <hackbod@google.com>
Fri, 29 Oct 2010 23:53:04 +0000 (16:53 -0700)
committerDianne Hackborn <hackbod@google.com>
Sat, 30 Oct 2010 00:48:26 +0000 (17:48 -0700)
Change-Id: I0c3d6a358d0236893aba7257537ec32bfad4170d

AndroidManifest.xml
proguard.flags
res/xml/application_settings.xml
src/com/android/settings/Settings.java
src/com/android/settings/applications/InstalledAppDetails.java
src/com/android/settings/applications/InstalledAppDetailsTop.java [new file with mode: 0644]
src/com/android/settings/applications/ManageApplications.java
src/com/android/settings/applications/RunningProcessesView.java

index 5b9af25..5b30ba5 100644 (file)
             </intent-filter>
         </activity-alias>
 
+        <activity-alias android:name=".applications.ManageApplications"
+                  android:label="@string/manageapplications_settings_title"
+                  android:clearTaskOnLaunch="true"
+                  android:targetActivity="Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.MANAGE_PACKAGE_STORAGE" />
+                <action android:name="android.settings.MANAGE_APPLICATIONS_SETTINGS" />
+                <action android:name="android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+                <category android:name="com.android.settings.SHORTCUT" />
+            </intent-filter>
+        </activity-alias>
+
+        <!-- Keep compatibility with old shortcuts. -->
+        <activity-alias android:name=".ManageApplications"
+                  android:label="@string/manageapplications_settings_title"
+                  android:clearTaskOnLaunch="true"
+                  android:exported="true"
+                  android:targetActivity="Settings">
+        </activity-alias>
+
+        <!-- Still need a top-level activity for showing app details.  Aliasing
+             trick is so the code that is now a fragment can still be called
+             InstalledAppDetails. -->
+        <activity android:name=".applications.InstalledAppDetailsTop"
+                  android:label="@string/application_info_label"
+                  android:exported="true">
+        </activity>
+        <activity-alias android:name=".applications.InstalledAppDetails"
+                  android:label="@string/application_info_label"
+                  android:targetActivity=".applications.InstalledAppDetailsTop">
+            <intent-filter>
+                <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="package" />
+            </intent-filter>
+        </activity-alias>
+
+        <!--
         <activity android:name=".applications.ManageApplications"
                   android:label="@string/manageapplications_settings_title"
                   android:clearTaskOnLaunch="true"
             </intent-filter>
         </activity>
 
-        <!-- Keep compatibility with old shortcuts. -->
         <activity-alias android:name=".ManageApplications"
             android:targetActivity=".applications.ManageApplications"
             android:exported="true" />
                 <data android:scheme="package" />
             </intent-filter>
         </activity>
+        -->
 
         <!-- Provide direct entry into manage apps showing running services. -->
         <activity-alias android:name=".RunningServices"
index 88da024..acda9aa 100644 (file)
@@ -5,4 +5,4 @@
 -keep class com.android.settings.wifi.*Settings
 -keep class com.android.settings.deviceinfo.*
 -keep class com.android.settings.bluetooth.*
-
+-keep class com.android.settings.applications.*
index 27a0411..6cd0b62 100644 (file)
     </PreferenceScreen>
         
     <PreferenceScreen
-            android:title="@string/manageapplications_settings_title"
-            android:summary="@string/manageapplications_settings_summary">
-        <intent android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.settings"
-                android:targetClass="com.android.settings.ManageApplications" />
+        android:fragment="com.android.settings.applications.ManageApplications"
+        android:title="@string/manageapplications_settings_title"
+        android:summary="@string/manageapplications_settings_summary">
     </PreferenceScreen>
 
     <PreferenceScreen
index 6cc641e..b428928 100644 (file)
@@ -17,6 +17,7 @@
 package com.android.settings;
 
 import android.content.Intent;
+import android.os.Bundle;
 import android.preference.PreferenceActivity;
 
 import java.util.List;
@@ -34,6 +35,13 @@ public class Settings extends PreferenceActivity {
         if (startingFragment != null && !onIsMultiPane()) {
             Intent modIntent = new Intent(super.getIntent());
             modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
+            Bundle args = super.getIntent().getExtras();
+            if (args != null) {
+                args = new Bundle(args);
+            } else {
+                args = new Bundle();
+            }
+            args.putParcelable("intent", super.getIntent());
             modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, super.getIntent().getExtras());
             return modIntent;
         }
@@ -45,9 +53,14 @@ public class Settings extends PreferenceActivity {
      * returns the class name to load as a fragment.
      */
     private String getStartingFragmentClass(Intent intent) {
-        final String intentClass = intent.getComponent().getClassName();
+        String intentClass = intent.getComponent().getClassName();
         if (intentClass.equals(getClass().getName())) return null;
 
+        if ("com.android.settings.ManageApplications".equals(intentClass)) {
+            // Old name of manage apps.
+            intentClass = com.android.settings.applications.ManageApplications.class.getName();
+        }
+
         return intentClass;
     }
 
index 912cc3e..cb5fbed 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.settings.applications;
 
-import com.android.internal.content.PackageHelper;
 import com.android.settings.R;
 import com.android.settings.applications.ApplicationsState.AppEntry;
 
@@ -24,6 +23,8 @@ import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -31,7 +32,6 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageManager;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -43,7 +43,6 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.text.format.Formatter;
 import android.util.Log;
 
@@ -51,7 +50,9 @@ import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
 import android.content.ComponentName;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.AppSecurityPermissions;
 import android.widget.Button;
 import android.widget.ImageView;
@@ -67,17 +68,20 @@ import android.widget.TextView;
  * For non-system applications, there is no option to clear data. Instead there is an option to
  * uninstall the application.
  */
-public class InstalledAppDetails extends Activity
+public class InstalledAppDetails extends Fragment
         implements View.OnClickListener, ApplicationsState.Callbacks {
     private static final String TAG="InstalledAppDetails";
     static final boolean SUPPORT_DISABLE_APPS = false;
     private static final boolean localLOGV = false;
     
+    public static final String ARG_PACKAGE_NAME = "package";
+
     private PackageManager mPm;
     private ApplicationsState mState;
     private ApplicationsState.AppEntry mAppEntry;
     private PackageInfo mPackageInfo;
     private CanBeOnSdCardChecker mCanBeOnSdCardChecker;
+    private View mRootView;
     private Button mUninstallButton;
     private boolean mMoveInProgress = false;
     private boolean mUpdatedSysApp = false;
@@ -95,7 +99,6 @@ public class InstalledAppDetails extends Activity
     private Button mForceStopButton;
     private Button mClearDataButton;
     private Button mMoveAppButton;
-    private int mMoveErrorCode;
     
     private PackageMoveObserver mPackageMoveObserver;
     
@@ -131,8 +134,8 @@ public class InstalledAppDetails extends Activity
     
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
-            // If the activity is gone, don't process any more messages.
-            if (isFinishing()) {
+            // If the fragment is gone, don't process any more messages.
+            if (getView() == null) {
                 return;
             }
             switch (msg.what) {
@@ -180,7 +183,7 @@ public class InstalledAppDetails extends Activity
         if (size == SIZE_INVALID) {
             return mInvalidSizeStr.toString();
         }
-        return Formatter.formatFileSize(this, size);
+        return Formatter.formatFileSize(getActivity(), size);
     }
     
     private void initDataButtons() {
@@ -203,15 +206,15 @@ public class InstalledAppDetails extends Activity
     private CharSequence getMoveErrMsg(int errCode) {
         switch (errCode) {
             case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE:
-                return getString(R.string.insufficient_storage);
+                return getActivity().getString(R.string.insufficient_storage);
             case PackageManager.MOVE_FAILED_DOESNT_EXIST:
-                return getString(R.string.does_not_exist);
+                return getActivity().getString(R.string.does_not_exist);
             case PackageManager.MOVE_FAILED_FORWARD_LOCKED:
-                return getString(R.string.app_forward_locked);
+                return getActivity().getString(R.string.app_forward_locked);
             case PackageManager.MOVE_FAILED_INVALID_LOCATION:
-                return getString(R.string.invalid_location);
+                return getActivity().getString(R.string.invalid_location);
             case PackageManager.MOVE_FAILED_SYSTEM_PACKAGE:
-                return getString(R.string.system_package);
+                return getActivity().getString(R.string.system_package);
             case PackageManager.MOVE_FAILED_INTERNAL_ERROR:
                 return "";
         }
@@ -289,45 +292,50 @@ public class InstalledAppDetails extends Activity
 
     /** Called when the activity is first created. */
     @Override
-    protected void onCreate(Bundle icicle) {
+    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         
-        mState = ApplicationsState.getInstance(getApplication());
-        mPm = getPackageManager();
+        mState = ApplicationsState.getInstance(getActivity().getApplication());
+        mPm = getActivity().getPackageManager();
         
         mCanBeOnSdCardChecker = new CanBeOnSdCardChecker();
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View view = mRootView = inflater.inflate(R.layout.installed_app_details, null);
         
-        setContentView(R.layout.installed_app_details);
-        
-        mComputingStr = getText(R.string.computing_size);
+        mComputingStr = getActivity().getText(R.string.computing_size);
         
         // Set default values on sizes
-        mTotalSize = (TextView)findViewById(R.id.total_size_text);
-        mAppSize = (TextView)findViewById(R.id.application_size_text);
-        mDataSize = (TextView)findViewById(R.id.data_size_text);
+        mTotalSize = (TextView)view.findViewById(R.id.total_size_text);
+        mAppSize = (TextView)view.findViewById(R.id.application_size_text);
+        mDataSize = (TextView)view.findViewById(R.id.data_size_text);
         
         // Get Control button panel
-        View btnPanel = findViewById(R.id.control_buttons_panel);
+        View btnPanel = view.findViewById(R.id.control_buttons_panel);
         mForceStopButton = (Button) btnPanel.findViewById(R.id.left_button);
         mForceStopButton.setText(R.string.force_stop);
         mUninstallButton = (Button)btnPanel.findViewById(R.id.right_button);
         mForceStopButton.setEnabled(false);
         
         // Initialize clear data and move install location buttons
-        View data_buttons_panel = findViewById(R.id.data_buttons_panel);
+        View data_buttons_panel = view.findViewById(R.id.data_buttons_panel);
         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);
-        mClearCacheButton = (Button) findViewById(R.id.clear_cache_button);
+        mCacheSize = (TextView) view.findViewById(R.id.cache_size_text);
+        mClearCacheButton = (Button) view.findViewById(R.id.clear_cache_button);
+
+        mActivitiesButton = (Button)view.findViewById(R.id.clear_activities_button);
         
-        mActivitiesButton = (Button)findViewById(R.id.clear_activities_button);
+        return view;
     }
 
     // Utility method to set applicaiton label and icon.
     private void setAppLabelAndIcon(PackageInfo pkgInfo) {
-        View appSnippet = findViewById(R.id.app_snippet);
+        View appSnippet = mRootView.findViewById(R.id.app_snippet);
         ImageView icon = (ImageView) appSnippet.findViewById(R.id.app_icon);
         mState.ensureIcon(mAppEntry);
         icon.setImageDrawable(mAppEntry.icon);
@@ -339,7 +347,7 @@ public class InstalledAppDetails extends Activity
 
         if (pkgInfo != null && pkgInfo.versionName != null) {
             mAppVersion.setVisibility(View.VISIBLE);
-            mAppVersion.setText(getString(R.string.version_text,
+            mAppVersion.setText(getActivity().getString(R.string.version_text,
                     String.valueOf(pkgInfo.versionName)));
         } else {
             mAppVersion.setVisibility(View.INVISIBLE);
@@ -395,8 +403,13 @@ public class InstalledAppDetails extends Activity
             return true;
         }
         
-        Intent intent = getIntent();
-        final String packageName = intent.getData().getSchemeSpecificPart();
+        String packageName = getArguments().getString(ARG_PACKAGE_NAME);
+        if (packageName == null) {
+            Intent intent = (Intent)getArguments().getParcelable("intent");
+            if (intent != null) {
+                packageName = intent.getData().getSchemeSpecificPart();
+            }
+        }
         mAppEntry = mState.getEntry(packageName);
         
         if (mAppEntry == null) {
@@ -421,7 +434,7 @@ public class InstalledAppDetails extends Activity
         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);
+        TextView autoLaunchView = (TextView)mRootView.findViewById(R.id.auto_launch);
         if (prefActList.size() <= 0) {
             // Disable clear activities button
             autoLaunchView.setText(R.string.auto_launch_disable_text);
@@ -433,8 +446,8 @@ public class InstalledAppDetails extends Activity
         }
          
         // Security permissions section
-        LinearLayout permsView = (LinearLayout) findViewById(R.id.permissions_section);
-        AppSecurityPermissions asp = new AppSecurityPermissions(this, packageName);
+        LinearLayout permsView = (LinearLayout) mRootView.findViewById(R.id.permissions_section);
+        AppSecurityPermissions asp = new AppSecurityPermissions(getActivity(), packageName);
         if (asp.getPermissionCount() > 0) {
             permsView.setVisibility(View.VISIBLE);
             // Make the security sections header visible
@@ -457,9 +470,12 @@ public class InstalledAppDetails extends Activity
         if(localLOGV) Log.i(TAG, "appChanged="+appChanged);
         Intent intent = new Intent();
         intent.putExtra(ManageApplications.APP_CHG, appChanged);
-        setResult(ManageApplications.RESULT_OK, intent);
-        if(finish) {
-            finish();
+        Fragment target = getTargetFragment();
+        if (target != null) {
+            target.onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
+        }
+        if (finish) {
+            getActivity().onBackPressed();
         }
     }
     
@@ -549,8 +565,7 @@ public class InstalledAppDetails extends Activity
             // Refresh size information again.
             mState.requestSize(mAppEntry.info.packageName);
         } else {
-            mMoveErrorCode = result;
-            showDialogInner(DLG_MOVE_FAILED);
+            showDialogInner(DLG_MOVE_FAILED, result);
         }
         refreshUi();
     }
@@ -567,105 +582,125 @@ public class InstalledAppDetails extends Activity
         if (mClearDataObserver == null) {
             mClearDataObserver = new ClearUserDataObserver();
         }
-        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        ActivityManager am = (ActivityManager)
+                getActivity().getSystemService(Context.ACTIVITY_SERVICE);
         boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
         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);
+            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
         } else {
             mClearDataButton.setText(R.string.recompute_size);
         }
     }
     
-    private void showDialogInner(int id) {
-        //removeDialog(id);
-        showDialog(id);
+    private void showDialogInner(int id, int moveErrorCode) {
+        DialogFragment newFragment = MyAlertDialogFragment.newInstance(id, moveErrorCode);
+        newFragment.setTargetFragment(this, 0);
+        newFragment.show(getFragmentManager(), "dialog " + id);
     }
     
-    @Override
-    public Dialog onCreateDialog(int id, Bundle args) {
-        switch (id) {
-        case DLG_CLEAR_DATA:
-            return 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,
-                    new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    // Clear user data here
-                    initiateClearUserData();
-                }
-            })
-            .setNegativeButton(R.string.dlg_cancel, null)
-            .create();
-        case DLG_FACTORY_RESET:
-            return new AlertDialog.Builder(this)
-            .setTitle(getString(R.string.app_factory_reset_dlg_title))
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(getString(R.string.app_factory_reset_dlg_text))
-            .setPositiveButton(R.string.dlg_ok,
-                    new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    // Clear user data here
-                    uninstallPkg(mAppEntry.info.packageName);
-                }
-            })
-            .setNegativeButton(R.string.dlg_cancel, null)
-            .create();
-        case DLG_APP_NOT_FOUND:
-            return new AlertDialog.Builder(this)
-            .setTitle(getString(R.string.app_not_found_dlg_title))
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(getString(R.string.app_not_found_dlg_title))
-            .setNeutralButton(getString(R.string.dlg_ok),
-                    new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    //force to recompute changed value
-                    setIntentAndFinish(true, true);
-                }
-            })
-            .create();
-        case DLG_CANNOT_CLEAR_DATA:
-            return new AlertDialog.Builder(this)
-            .setTitle(getString(R.string.clear_failed_dlg_title))
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(getString(R.string.clear_failed_dlg_text))
-            .setNeutralButton(R.string.dlg_ok,
-                    new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    mClearDataButton.setEnabled(false);
-                    //force to recompute changed value
-                    setIntentAndFinish(false, false);
-                }
-            })
-            .create();
-        case DLG_FORCE_STOP:
-            return new AlertDialog.Builder(this)
-            .setTitle(getString(R.string.force_stop_dlg_title))
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(getString(R.string.force_stop_dlg_text))
-            .setPositiveButton(R.string.dlg_ok,
-                new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    // Force stop
-                    forceStopPackage(mAppEntry.info.packageName);
-                }
-            })
-            .setNegativeButton(R.string.dlg_cancel, null)
-            .create();
-        case DLG_MOVE_FAILED:
-            CharSequence msg = getString(R.string.move_app_failed_dlg_text,
-                    getMoveErrMsg(mMoveErrorCode));
-            return new AlertDialog.Builder(this)
-            .setTitle(getString(R.string.move_app_failed_dlg_title))
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(msg)
-            .setNeutralButton(R.string.dlg_ok, null)
-            .create();
-        }
-        return null;
+    public static class MyAlertDialogFragment extends DialogFragment {
+
+        public static MyAlertDialogFragment newInstance(int id, int moveErrorCode) {
+            MyAlertDialogFragment frag = new MyAlertDialogFragment();
+            Bundle args = new Bundle();
+            args.putInt("id", id);
+            args.putInt("moveError", moveErrorCode);
+            frag.setArguments(args);
+            return frag;
+        }
+
+        InstalledAppDetails getOwner() {
+            return (InstalledAppDetails)getTargetFragment();
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            int id = getArguments().getInt("id");
+            int moveErrorCode = getArguments().getInt("moveError");
+            switch (id) {
+                case DLG_CLEAR_DATA:
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.clear_data_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(getActivity().getText(R.string.clear_data_dlg_text))
+                    .setPositiveButton(R.string.dlg_ok,
+                            new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            // Clear user data here
+                            getOwner().initiateClearUserData();
+                        }
+                    })
+                    .setNegativeButton(R.string.dlg_cancel, null)
+                    .create();
+                case DLG_FACTORY_RESET:
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.app_factory_reset_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(getActivity().getText(R.string.app_factory_reset_dlg_text))
+                    .setPositiveButton(R.string.dlg_ok,
+                            new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            // Clear user data here
+                            getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName);
+                        }
+                    })
+                    .setNegativeButton(R.string.dlg_cancel, null)
+                    .create();
+                case DLG_APP_NOT_FOUND:
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.app_not_found_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(getActivity().getText(R.string.app_not_found_dlg_title))
+                    .setNeutralButton(getActivity().getText(R.string.dlg_ok),
+                            new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            //force to recompute changed value
+                            getOwner().setIntentAndFinish(true, true);
+                        }
+                    })
+                    .create();
+                case DLG_CANNOT_CLEAR_DATA:
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.clear_failed_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(getActivity().getText(R.string.clear_failed_dlg_text))
+                    .setNeutralButton(R.string.dlg_ok,
+                            new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            getOwner().mClearDataButton.setEnabled(false);
+                            //force to recompute changed value
+                            getOwner().setIntentAndFinish(false, false);
+                        }
+                    })
+                    .create();
+                case DLG_FORCE_STOP:
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.force_stop_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(getActivity().getText(R.string.force_stop_dlg_text))
+                    .setPositiveButton(R.string.dlg_ok,
+                        new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            // Force stop
+                            getOwner().forceStopPackage(getOwner().mAppEntry.info.packageName);
+                        }
+                    })
+                    .setNegativeButton(R.string.dlg_cancel, null)
+                    .create();
+                case DLG_MOVE_FAILED:
+                    CharSequence msg = getActivity().getString(R.string.move_app_failed_dlg_text,
+                            getOwner().getMoveErrMsg(moveErrorCode));
+                    return new AlertDialog.Builder(getActivity())
+                    .setTitle(getActivity().getText(R.string.move_app_failed_dlg_title))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(msg)
+                    .setNeutralButton(R.string.dlg_ok, null)
+                    .create();
+            }
+            throw new IllegalArgumentException("unknown id " + id);
+        }
     }
 
     private void uninstallPkg(String packageName) {
@@ -677,7 +712,7 @@ public class InstalledAppDetails extends Activity
     }
 
     private void forceStopPackage(String pkgName) {
-        ActivityManager am = (ActivityManager)getSystemService(
+        ActivityManager am = (ActivityManager)getActivity().getSystemService(
                 Context.ACTIVITY_SERVICE);
         am.forceStopPackage(pkgName);
         checkForceStop();
@@ -686,7 +721,7 @@ public class InstalledAppDetails extends Activity
     private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            mForceStopButton.setEnabled(getResultCode() != RESULT_CANCELED);
+            mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
             mForceStopButton.setOnClickListener(InstalledAppDetails.this);
         }
     };
@@ -696,7 +731,7 @@ public class InstalledAppDetails extends Activity
                 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,
+        getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
                 Activity.RESULT_CANCELED, null, null);
     }
     
@@ -728,7 +763,7 @@ public class InstalledAppDetails extends Activity
         String packageName = mAppEntry.info.packageName;
         if(v == mUninstallButton) {
             if (mUpdatedSysApp) {
-                showDialogInner(DLG_FACTORY_RESET);
+                showDialogInner(DLG_FACTORY_RESET, 0);
             } else {
                 if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                     new DisableChanger(this, mAppEntry.info, mAppEntry.info.enabled ?
@@ -748,7 +783,7 @@ public class InstalledAppDetails extends Activity
                         mAppEntry.info.manageSpaceActivityName);
                 startActivityForResult(intent, -1);
             } else {
-                showDialogInner(DLG_CLEAR_DATA);
+                showDialogInner(DLG_CLEAR_DATA, 0);
             }
         } else if (v == mClearCacheButton) {
             // Lazy initialization of observer
@@ -757,7 +792,7 @@ public class InstalledAppDetails extends Activity
             }
             mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver);
         } else if (v == mForceStopButton) {
-            showDialogInner(DLG_FORCE_STOP);
+            showDialogInner(DLG_FORCE_STOP, 0);
             //forceStopPackage(mAppInfo.packageName);
         } else if (v == mMoveAppButton) {
             if (mPackageMoveObserver == null) {
diff --git a/src/com/android/settings/applications/InstalledAppDetailsTop.java b/src/com/android/settings/applications/InstalledAppDetailsTop.java
new file mode 100644 (file)
index 0000000..5ad2182
--- /dev/null
@@ -0,0 +1,13 @@
+package com.android.settings.applications;
+
+import android.content.Intent;
+import android.preference.PreferenceActivity;
+
+public class InstalledAppDetailsTop extends PreferenceActivity {
+    @Override
+    public Intent getIntent() {
+        Intent modIntent = new Intent(super.getIntent());
+        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, InstalledAppDetails.class.getName());
+        return modIntent;
+    }
+}
index 9ec65c1..217e333 100644 (file)
@@ -20,6 +20,7 @@ import com.android.internal.content.PackageHelper;
 import com.android.settings.R;
 import com.android.settings.applications.ApplicationsState.AppEntry;
 
+import android.app.Fragment;
 import android.app.TabActivity;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -33,12 +34,14 @@ import android.os.Environment;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StatFs;
+import android.preference.PreferenceActivity;
 import android.provider.Settings;
 import android.text.format.Formatter;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
@@ -54,6 +57,7 @@ import android.widget.Filterable;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TabHost;
+import android.widget.TabWidget;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
 
@@ -108,8 +112,8 @@ final class CanBeOnSdCardChecker {
  * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
  * intent.
  */
-public class ManageApplications extends TabActivity implements
-        OnItemClickListener, DialogInterface.OnCancelListener,
+public class ManageApplications extends Fragment implements
+        OnItemClickListener,
         TabHost.TabContentFactory, TabHost.OnTabChangeListener {
     static final String TAG = "ManageApplications";
     static final boolean DEBUG = false;
@@ -169,13 +173,25 @@ public class ManageApplications extends TabActivity implements
 
     private boolean mResumedRunning;
     private boolean mActivityResumed;
-    private Object mNonConfigInstance;
     
     private StatFs mDataFileStats;
     private StatFs mSDCardFileStats;
     private boolean mLastShowedInternalStorage = true;
     private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;
 
+    static final String TAB_DOWNLOADED = "Downloaded";
+    static final String TAB_RUNNING = "Running";
+    static final String TAB_ALL = "All";
+    static final String TAB_SDCARD = "OnSdCard";
+    private View mRootView;
+
+    // -------------- Copied from TabActivity --------------
+
+    private TabHost mTabHost;
+    private String mDefaultTab = null;
+
+    // -------------- Copied from TabActivity --------------
+
     final Runnable mRunningProcessesAvail = new Runnable() {
         public void run() {
             handleRunningProcessesAvail();
@@ -345,16 +361,16 @@ public class ManageApplications extends TabActivity implements
 
         @Override
         public void onRunningStateChanged(boolean running) {
-            setProgressBarIndeterminateVisibility(running);
+            getActivity().setProgressBarIndeterminateVisibility(running);
         }
 
         @Override
         public void onRebuildComplete(ArrayList<AppEntry> apps) {
             if (mLoadingContainer.getVisibility() == View.VISIBLE) {
                 mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
-                        ManageApplications.this, android.R.anim.fade_out));
+                        getActivity(), android.R.anim.fade_out));
                 mListContainer.startAnimation(AnimationUtils.loadAnimation(
-                        ManageApplications.this, android.R.anim.fade_in));
+                        getActivity(), android.R.anim.fade_in));
             }
             mListContainer.setVisibility(View.VISIBLE);
             mLoadingContainer.setVisibility(View.GONE);
@@ -453,7 +469,7 @@ public class ManageApplications extends TabActivity implements
                 holder.entry = entry;
                 if (entry.label != null) {
                     holder.appName.setText(entry.label);
-                    holder.appName.setTextColor(getResources().getColorStateList(
+                    holder.appName.setTextColor(getActivity().getResources().getColorStateList(
                             entry.info.enabled ? android.R.color.primary_text_dark
                                     : android.R.color.secondary_text_dark));
                 }
@@ -491,18 +507,15 @@ public class ManageApplications extends TabActivity implements
         }
     }
     
-    static final String TAB_DOWNLOADED = "Downloaded";
-    static final String TAB_RUNNING = "Running";
-    static final String TAB_ALL = "All";
-    static final String TAB_SDCARD = "OnSdCard";
-    private View mRootView;
-    
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
+    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mApplicationsState = ApplicationsState.getInstance(getApplication());
+
+        setHasOptionsMenu(true);
+
+        mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
         mApplicationsAdapter = new ApplicationsAdapter(mApplicationsState);
-        Intent intent = getIntent();
+        Intent intent = getActivity().getIntent();
         String action = intent.getAction();
         String defaultTabTag = TAB_DOWNLOADED;
         if (intent.getComponent().getClassName().equals(
@@ -526,19 +539,21 @@ public class ManageApplications extends TabActivity implements
             if (tmp != null) defaultTabTag = tmp;
         }
         
-        mNonConfigInstance = getLastNonConfigurationInstance();
+        mDefaultTab = defaultTabTag;
         
         mDataFileStats = new StatFs("/data");
         mSDCardFileStats = new StatFs(Environment.getExternalStorageDirectory().toString());
 
-        // initialize some window features
-        requestWindowFeature(Window.FEATURE_RIGHT_ICON);
-        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-        mInvalidSizeStr = getText(R.string.invalid_size_value);
-        mComputingSizeStr = getText(R.string.computing_size);
+        mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
+        mComputingSizeStr = getActivity().getText(R.string.computing_size);
+    }
+
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         // initialize the inflater
-        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        mRootView = mInflater.inflate(R.layout.manage_applications, null);
+        mInflater = inflater;
+        mRootView = inflater.inflate(R.layout.manage_applications, null);
         mLoadingContainer = mRootView.findViewById(R.id.loading_container);
         mListContainer = mRootView.findViewById(R.id.list_container);
         // Create adapter and list view here
@@ -562,54 +577,56 @@ public class ManageApplications extends TabActivity implements
         mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
                 R.id.running_processes);
 
-        final TabHost tabHost = getTabHost();
+        View tabRoot = mInflater.inflate(com.android.internal.R.layout.tab_content, null);
+        mTabHost = (TabHost)tabRoot.findViewById(com.android.internal.R.id.tabhost);
+        mTabHost.setup();
+        final TabHost tabHost = mTabHost;
         tabHost.addTab(tabHost.newTabSpec(TAB_DOWNLOADED)
-                .setIndicator(getString(R.string.filter_apps_third_party),
-                        getResources().getDrawable(R.drawable.ic_tab_download))
+                .setIndicator(getActivity().getString(R.string.filter_apps_third_party),
+                        getActivity().getResources().getDrawable(R.drawable.ic_tab_download))
                 .setContent(this));
         tabHost.addTab(tabHost.newTabSpec(TAB_ALL)
-                .setIndicator(getString(R.string.filter_apps_all),
-                        getResources().getDrawable(R.drawable.ic_tab_all))
+                .setIndicator(getActivity().getString(R.string.filter_apps_all),
+                        getActivity().getResources().getDrawable(R.drawable.ic_tab_all))
                 .setContent(this));
         tabHost.addTab(tabHost.newTabSpec(TAB_SDCARD)
-                .setIndicator(getString(R.string.filter_apps_onsdcard),
-                        getResources().getDrawable(R.drawable.ic_tab_sdcard))
+                .setIndicator(getActivity().getString(R.string.filter_apps_onsdcard),
+                        getActivity().getResources().getDrawable(R.drawable.ic_tab_sdcard))
                 .setContent(this));
         tabHost.addTab(tabHost.newTabSpec(TAB_RUNNING)
-                .setIndicator(getString(R.string.filter_apps_running),
-                        getResources().getDrawable(R.drawable.ic_tab_running))
+                .setIndicator(getActivity().getString(R.string.filter_apps_running),
+                        getActivity().getResources().getDrawable(R.drawable.ic_tab_running))
                 .setContent(this));
-        tabHost.setCurrentTabByTag(defaultTabTag);
+        tabHost.setCurrentTabByTag(mDefaultTab);
         tabHost.setOnTabChangedListener(this);
+
+        return tabRoot;
     }
-    
+
     @Override
     public void onStart() {
         super.onStart();
     }
 
     @Override
-    protected void onResume() {
+    public void onResume() {
         super.onResume();
         mActivityResumed = true;
         showCurrentTab();
     }
 
     @Override
-    protected void onSaveInstanceState(Bundle outState) {
+    public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putInt("sortOrder", mSortOrder);
         outState.putInt("filterApps", mFilterApps);
-        outState.putString("defautTabTag", getTabHost().getCurrentTabTag());
+        if (mTabHost != null) {
+            outState.putString("defautTabTag", mTabHost.getCurrentTabTag());
+        }
     }
 
     @Override
-    public Object onRetainNonConfigurationInstance() {
-        return mRunningProcessesView.doRetainNonConfigurationInstance();
-    }
-    
-    @Override
-    protected void onPause() {
+    public void onPause() {
         super.onPause();
         mActivityResumed = false;
         mApplicationsAdapter.pause();
@@ -620,8 +637,7 @@ public class ManageApplications extends TabActivity implements
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode,
-            Intent data) {
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
             mApplicationsState.requestSize(mCurrentPkgName);
         }
@@ -632,23 +648,34 @@ public class ManageApplications extends TabActivity implements
         // Create intent to start new activity
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                 Uri.fromParts("package", mCurrentPkgName, null));
-        // start new activity to display extended information
-        startActivityForResult(intent, INSTALLED_APP_DETAILS);
+        // start new fragment to display extended information
+        Bundle args = new Bundle();
+        args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mCurrentPkgName);
+
+        PreferenceActivity pa = (PreferenceActivity)getActivity();
+        if (pa.isMultiPane()) {
+            Fragment frag = new InstalledAppDetails();
+            frag.setTargetFragment(this, INSTALLED_APP_DETAILS);
+            frag.setArguments(args);
+            frag.setTargetFragment(this, INSTALLED_APP_DETAILS);
+            pa.startPreferenceFragment(frag, true);
+        } else {
+            pa.startWithFragment(InstalledAppDetails.class.getName(), args);
+        }
     }
     
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
                 .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
         menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
                 .setIcon(android.R.drawable.ic_menu_sort_by_size); 
         menu.add(0, SHOW_RUNNING_SERVICES, 3, R.string.show_running_services);
         menu.add(0, SHOW_BACKGROUND_PROCESSES, 3, R.string.show_background_processes);
-        return true;
     }
     
     @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
+    public void onPrepareOptionsMenu(Menu menu) {
         /*
          * The running processes screen doesn't use the mApplicationsAdapter
          * so bringing up this menu in that case doesn't make any sense.
@@ -665,7 +692,6 @@ public class ManageApplications extends TabActivity implements
             menu.findItem(SHOW_RUNNING_SERVICES).setVisible(false);
             menu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(false);
         }
-        return true;
     }
 
     @Override
@@ -684,18 +710,6 @@ public class ManageApplications extends TabActivity implements
         return true;
     }
     
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_SEARCH && event.isTracking()) {
-            if (mCurView != VIEW_RUNNING) {
-                ((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
-                        .showSoftInputUnchecked(0, null);
-            }
-            return true;
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
     public void onItemClick(AdapterView<?> parent, View view, int position,
             long id) {
         ApplicationsState.AppEntry entry = mApplicationsAdapter.getAppEntry(position);
@@ -703,11 +717,6 @@ public class ManageApplications extends TabActivity implements
         startApplicationDetailsActivity();
     }
     
-    // Finish the activity if the user presses the back button to cancel the activity
-    public void onCancel(DialogInterface dialog) {
-        finish();
-    }
-
     public View createTabContent(String tag) {
         return mRootView;
     }
@@ -730,7 +739,7 @@ public class ManageApplications extends TabActivity implements
             if (mLastShowedInternalStorage) {
                 mLastShowedInternalStorage = false;
             }
-            newLabel = this.getText(R.string.sd_card_storage);
+            newLabel = getActivity().getText(R.string.sd_card_storage);
             mSDCardFileStats.restat(Environment.getExternalStorageDirectory().toString());
             try {
                 totalStorage = (long)mSDCardFileStats.getBlockCount() *
@@ -744,7 +753,7 @@ public class ManageApplications extends TabActivity implements
             if (!mLastShowedInternalStorage) {
                 mLastShowedInternalStorage = true;
             }
-            newLabel = this.getText(R.string.internal_storage);
+            newLabel = getActivity().getText(R.string.internal_storage);
             mDataFileStats.restat("/data");
             try {
                 totalStorage = (long)mDataFileStats.getBlockCount() *
@@ -769,14 +778,14 @@ public class ManageApplications extends TabActivity implements
             long usedStorage = totalStorage - freeStorage;
             if (mLastUsedStorage != usedStorage) {
                 mLastUsedStorage = usedStorage;
-                String sizeStr = Formatter.formatShortFileSize(this, usedStorage);
-                mUsedStorageText.setText(getResources().getString(
+                String sizeStr = Formatter.formatShortFileSize(getActivity(), usedStorage);
+                mUsedStorageText.setText(getActivity().getResources().getString(
                         R.string.service_foreground_processes, sizeStr));
             }
             if (mLastFreeStorage != freeStorage) {
                 mLastFreeStorage = freeStorage;
-                String sizeStr = Formatter.formatShortFileSize(this, freeStorage);
-                mFreeStorageText.setText(getResources().getString(
+                String sizeStr = Formatter.formatShortFileSize(getActivity(), freeStorage);
+                mFreeStorageText.setText(getActivity().getResources().getString(
                         R.string.service_background_processes, sizeStr));
             }
         } else {
@@ -808,7 +817,7 @@ public class ManageApplications extends TabActivity implements
             }
         } else if (which == VIEW_RUNNING) {
             if (!mCreatedRunning) {
-                mRunningProcessesView.doCreate(null, mNonConfigInstance);
+                mRunningProcessesView.doCreate(null);
                 mCreatedRunning = true;
             }
             boolean haveData = true;
@@ -832,16 +841,16 @@ public class ManageApplications extends TabActivity implements
     void handleRunningProcessesAvail() {
         if (mCurView == VIEW_RUNNING) {
             mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
-                    this, android.R.anim.fade_out));
+                    getActivity(), android.R.anim.fade_out));
             mRunningProcessesView.startAnimation(AnimationUtils.loadAnimation(
-                    this, android.R.anim.fade_in));
+                    getActivity(), android.R.anim.fade_in));
             mRunningProcessesView.setVisibility(View.VISIBLE);
             mLoadingContainer.setVisibility(View.GONE);
         }
     }
 
     public void showCurrentTab() {
-        String tabId = getTabHost().getCurrentTabTag();
+        String tabId = mTabHost.getCurrentTabTag();
         int newOption;
         if (TAB_DOWNLOADED.equalsIgnoreCase(tabId)) {
             newOption = FILTER_APPS_THIRD_PARTY;
@@ -850,8 +859,9 @@ public class ManageApplications extends TabActivity implements
         } else if (TAB_SDCARD.equalsIgnoreCase(tabId)) {
             newOption = FILTER_APPS_SDCARD;
         } else if (TAB_RUNNING.equalsIgnoreCase(tabId)) {
-            ((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
-                    .hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
+            ((InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
+                    .hideSoftInputFromWindow(
+                            getActivity().getWindow().getDecorView().getWindowToken(), 0);
             selectView(VIEW_RUNNING);
             return;
         } else {
index 86457bf..7794365 100644 (file)
@@ -433,7 +433,7 @@ public class RunningProcessesView extends FrameLayout
         super(context, attrs);
     }
     
-    public void doCreate(Bundle savedInstanceState, Object nonConfigurationInstace) {
+    public void doCreate(Bundle savedInstanceState) {
         mAm = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
         mState = RunningState.getInstance(getContext());
         LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
@@ -486,10 +486,6 @@ public class RunningProcessesView extends FrameLayout
         return false;
     }
 
-    public Object doRetainNonConfigurationInstance() {
-        return null;
-    }
-
     void updateTimes() {
         Iterator<ActiveItem> it = mActiveItems.values().iterator();
         while (it.hasNext()) {