Add development setting for compatibility mode.

Also some cleanup here and there.

Change-Id: Iebf563cf6ec2d0b1671a54bd534336e8fef4b9c0
diff --git a/apps/Development/res/layout/development_settings.xml b/apps/Development/res/layout/development_settings.xml
index 4f185aa..7bad3bb 100644
--- a/apps/Development/res/layout/development_settings.xml
+++ b/apps/Development/res/layout/development_settings.xml
@@ -68,10 +68,17 @@
             android:layout_alignParentLeft="true"
             android:text="@string/development_settings_show_updates_text" />
 
+        <CheckBox android:id="@+id/compatibility_mode"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/show_updates"
+            android:layout_alignParentLeft="true"
+            android:text="@string/development_settings_compatibility_mode_text" />
+
         <Spinner android:id="@+id/max_procs"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/show_updates"
+            android:layout_below="@id/compatibility_mode"
             android:layout_alignParentLeft="true" />
 
         <View android:id="@+id/separator2"
diff --git a/apps/Development/res/layout/package_list_item.xml b/apps/Development/res/layout/package_list_item.xml
new file mode 100644
index 0000000..6a0faee
--- /dev/null
+++ b/apps/Development/res/layout/package_list_item.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="vertical"
+    android:gravity="fill" >
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="horizontal"
+        android:paddingRight="6dip"
+        android:paddingLeft="6dip"
+        android:gravity="center_vertical" >
+    
+        <ImageView android:id="@+id/icon"
+            android:layout_width="@android:dimen/app_icon_size"
+            android:layout_height="@android:dimen/app_icon_size"
+            android:layout_marginLeft="5dip"
+            android:layout_marginRight="11dip"
+            android:layout_gravity="center_vertical"
+            android:scaleType="fitCenter"/>
+    
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" >
+            <TextView android:id="@+id/name"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textStyle="bold"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:layout_marginBottom="2dip" />
+            <TextView android:id="@+id/description"
+                android:layout_marginTop="-4dip"
+                android:layout_gravity="center_vertical|left"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="4dip"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index 21f15f6..ad70fbe 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -77,6 +77,9 @@
     <string name="development_settings_always_finish_text">Immediately destroy activities</string>
     <string name="development_settings_show_load_text">Show running processes</string>
     <string name="development_settings_show_updates_text">Show screen updates</string>
+    <string name="development_settings_compatibility_mode_text">Disable compatibility mode</string>
+    <string name="development_settings_compatibility_mode_toast">Reboot required for
+            change to take effect.</string>
     <string name="development_settings_enable_gl_text">Enable OpenGL ES (reboot needed)</string>
     <string name="development_settings_allow_mock_location_text">Allow mock locations for testing</string>
     <string name="development_settings_wait_for_debugger_text">Wait for debugger</string>
diff --git a/apps/Development/src/com/android/development/AppPicker.java b/apps/Development/src/com/android/development/AppPicker.java
index 693defb..28040c2 100644
--- a/apps/Development/src/com/android/development/AppPicker.java
+++ b/apps/Development/src/com/android/development/AppPicker.java
@@ -17,11 +17,14 @@
 
 package com.android.development;
 
+import com.android.development.PackageBrowser.MyPackageInfo;
+
 import android.app.ActivityManagerNative;
 import android.app.ListActivity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.provider.Settings;
@@ -29,10 +32,12 @@
 import android.view.ViewGroup;
 import android.view.LayoutInflater;
 import android.widget.BaseAdapter;
+import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
 import java.text.Collator;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -67,96 +72,67 @@
     @Override
     protected void onListItemClick(ListView l, View v, int position, long id)
     {
-        ApplicationInfo app = mAdapter.appForPosition(position);
+        MyApplicationInfo app = mAdapter.itemForPosition(position);
         Intent intent = new Intent();
-        if (app != null) intent.setAction(app.packageName);
+        if (app.info != null) intent.setAction(app.info.packageName);
         setResult(RESULT_OK, intent);
         
-        /* This is a temporary fix for 824637 while it is blocked by 805226.  When 805226 is resolved, please remove this. */
         try {
             boolean waitForDebugger = Settings.System.getInt(
                     getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
             ActivityManagerNative.getDefault().setDebugApp(
-                    app != null ? app.packageName : null, waitForDebugger, true);
+                    app.info != null ? app.info.packageName : null, waitForDebugger, true);
         } catch (RemoteException ex) {
         }
         
         finish();
     }
 
-    private final class AppListAdapter extends BaseAdapter
-    {
-        public AppListAdapter(Context context)
-        {
-            mContext = context;
-            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    class MyApplicationInfo {
+        ApplicationInfo info;
+        String label;
+    }
+    
+    public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
+        private List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
 
-            mList = context.getPackageManager().getInstalledApplications(0);
-            if (mList != null) {
-                Collections.sort(mList, sDisplayNameComparator);
-                mList.add(0, null);
+        public AppListAdapter(Context context) {
+            super(context, R.layout.package_list_item);
+            List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0);
+            for (int i=0; i<pkgs.size(); i++) {
+                MyApplicationInfo info = new MyApplicationInfo();
+                info.info = pkgs.get(i);
+                info.label = info.info.loadLabel(getPackageManager()).toString();
+                mPackageInfoList.add(info);
             }
+            Collections.sort(mPackageInfoList, sDisplayNameComparator);
+            MyApplicationInfo info = new MyApplicationInfo();
+            info.label = "(none)";
+            mPackageInfoList.add(0, info);
+            setSource(mPackageInfoList);
         }
     
-        public ApplicationInfo appForPosition(int position)
-        {
-            if (mList == null) {
-                return null;
-            }
-
-            return mList.get(position);
-        }
-
-        public int getCount()
-        {
-            return mList != null ? mList.size() : 0;
-        }
-
-        public Object getItem(int position)
-        {
-            return position;
-        }
-    
-        public long getItemId(int position)
-        {
-            return position;
-        }
-    
-        public View getView(int position, View convertView, ViewGroup parent)
-        {
-            View view;
-            if (convertView == null) {
-                view = mInflater.inflate(
-                        android.R.layout.simple_list_item_1, parent, false);
+        @Override
+        public void bindView(View view, MyApplicationInfo info) {
+            ImageView icon = (ImageView)view.findViewById(R.id.icon);
+            TextView name = (TextView)view.findViewById(R.id.name);
+            TextView description = (TextView)view.findViewById(R.id.description);
+            name.setText(info.label);
+            if (info.info != null) {
+                icon.setImageDrawable(info.info.loadIcon(getPackageManager()));
+                description.setText(info.info.packageName);
             } else {
-                view = convertView;
+                icon.setImageDrawable(null);
+                description.setText("");
             }
-            bindView(view, mList.get(position));
-            return view;
         }
-    
-        private final void bindView(View view, ApplicationInfo info)
-        {
-            TextView text = (TextView)view.findViewById(android.R.id.text1);
-    
-            text.setText(info != null ? info.packageName : "(none)");
-        }
-    
-        protected final Context mContext;
-        protected final LayoutInflater mInflater;
-    
-        protected List<ApplicationInfo> mList;
-        
     }
 
-    private final static Comparator sDisplayNameComparator = new Comparator() {
+    private final static Comparator<MyApplicationInfo> sDisplayNameComparator
+            = new Comparator<MyApplicationInfo>() {
         public final int
-        compare(Object a, Object b)
-        {
-            CharSequence  sa = ((ApplicationInfo) a).packageName;
-            CharSequence  sb = ((ApplicationInfo) b).packageName;
-
-            return collator.compare(sa, sb);
+        compare(MyApplicationInfo a, MyApplicationInfo b) {
+            return collator.compare(a.label, b.label);
         }
 
         private final Collator   collator = Collator.getInstance();
diff --git a/apps/Development/src/com/android/development/DevelopmentSettings.java b/apps/Development/src/com/android/development/DevelopmentSettings.java
index 3b4848a..9cb6fc6 100644
--- a/apps/Development/src/com/android/development/DevelopmentSettings.java
+++ b/apps/Development/src/com/android/development/DevelopmentSettings.java
@@ -38,6 +38,7 @@
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.Spinner;
+import android.widget.Toast;
 import android.widget.AdapterView.OnItemSelectedListener;
 
 import java.io.FileInputStream;
@@ -58,6 +59,7 @@
     private CheckBox mShowBackgroundCB;
     private CheckBox mShowSleepCB;
     private CheckBox mShowXmppCB;
+    private CheckBox mCompatibilityModeCB;
     private Spinner mMaxProcsSpinner;
     private Spinner mWindowAnimationScaleSpinner;
     private Spinner mTransitionAnimationScaleSpinner;
@@ -69,6 +71,7 @@
     private int mProcessLimit;
     private boolean mShowSleep;
     private boolean mShowXmpp;
+    private boolean mCompatibilityMode;
     private AnimationScaleSelectedListener mWindowAnimationScale
             = new AnimationScaleSelectedListener(0);
     private AnimationScaleSelectedListener mTransitionAnimationScale
@@ -106,6 +109,8 @@
         mShowSleepCB.setOnClickListener(mShowSleepClicked);
         mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
         mShowXmppCB.setOnClickListener(mShowXmppClicked);
+        mCompatibilityModeCB = (CheckBox)findViewById(R.id.compatibility_mode);
+        mCompatibilityModeCB.setOnClickListener(mCompatibilityModeClicked);
         mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
         mMaxProcsSpinner.setOnItemSelectedListener(mMaxProcsChanged);
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(
@@ -168,7 +173,8 @@
         updateSharedOptions();
         updateFlingerOptions();
         updateSleepOptions();
-        updateXmppOptions();        
+        updateXmppOptions();
+        updateCompatibilityOptions();
 
         try {
             FileInputStream  in = new FileInputStream( FONT_HINTING_FILE );
@@ -235,6 +241,17 @@
                 Settings.System.SHOW_PROCESSES, 0) != 0);
     }
 
+    private void writeCompatibilityOptions() {
+        Settings.System.putInt(getContentResolver(),
+                Settings.System.COMPATIBILITY_MODE, mCompatibilityMode ? 0 : 1);
+    }
+
+    private void updateCompatibilityOptions() {
+        mCompatibilityMode = Settings.System.getInt(
+            getContentResolver(), Settings.System.COMPATIBILITY_MODE, 1) == 0;
+        mCompatibilityModeCB.setChecked(mCompatibilityMode);
+    }
+
     private void updateFlingerOptions() {
         // magic communication with surface flinger.
         try {
@@ -332,6 +349,19 @@
         }
     };
 
+    private View.OnClickListener mCompatibilityModeClicked =
+        new View.OnClickListener() {
+    public void onClick(View v) {
+        mCompatibilityMode = ((CheckBox)v).isChecked();
+        writeCompatibilityOptions();
+        updateCompatibilityOptions();
+        Toast toast = Toast.makeText(DevelopmentSettings.this,
+                R.string.development_settings_compatibility_mode_toast,
+                Toast.LENGTH_LONG);
+        toast.show();
+    }
+};
+
     private View.OnClickListener mShowLoadClicked = new View.OnClickListener() {
         public void onClick(View v) {
             boolean value = ((CheckBox)v).isChecked();
diff --git a/apps/Development/src/com/android/development/PackageBrowser.java b/apps/Development/src/com/android/development/PackageBrowser.java
index e4c233f..689183d 100644
--- a/apps/Development/src/com/android/development/PackageBrowser.java
+++ b/apps/Development/src/com/android/development/PackageBrowser.java
@@ -31,27 +31,38 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
 import java.text.Collator;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-public class PackageBrowser extends ListActivity
-{
+public class PackageBrowser extends ListActivity {
+    static class MyPackageInfo {
+        PackageInfo info;
+        String label;
+    }
+    
     private PackageListAdapter mAdapter;
-    private List<PackageInfo> mPackageInfoList = null;
+    private List<MyPackageInfo> mPackageInfoList = new ArrayList<MyPackageInfo>();
     private Handler mHandler;
+    private BroadcastReceiver mRegisteredReceiver;
 
-    public class PackageListAdapter extends ArrayAdapter<PackageInfo>
-    {
+    public class PackageListAdapter extends ArrayAdapter<MyPackageInfo> {
 
-        public PackageListAdapter(Context context)
-        {
-            super(context, android.R.layout.simple_list_item_1);
-            mPackageInfoList = context.getPackageManager().getInstalledPackages(0);
+        public PackageListAdapter(Context context) {
+            super(context, R.layout.package_list_item);
+            List<PackageInfo> pkgs = context.getPackageManager().getInstalledPackages(0);
+            for (int i=0; i<pkgs.size(); i++) {
+                MyPackageInfo info = new MyPackageInfo();
+                info.info = pkgs.get(i);
+                info.label = info.info.applicationInfo.loadLabel(getPackageManager()).toString();
+                mPackageInfoList.add(info);
+            }
             if (mPackageInfoList != null) {
                 Collections.sort(mPackageInfoList, sDisplayNameComparator);
             }
@@ -59,10 +70,13 @@
         }
     
         @Override
-        public void bindView(View view, PackageInfo info)
-        {
-            TextView text = (TextView)view.findViewById(android.R.id.text1);
-            text.setText(info.packageName);
+        public void bindView(View view, MyPackageInfo info) {
+            ImageView icon = (ImageView)view.findViewById(R.id.icon);
+            TextView name = (TextView)view.findViewById(R.id.name);
+            TextView description = (TextView)view.findViewById(R.id.description);
+            icon.setImageDrawable(info.info.applicationInfo.loadIcon(getPackageManager()));
+            name.setText(info.label);
+            description.setText(info.info.packageName);
         }
     }
 
@@ -78,13 +92,11 @@
         }
     }
 
-    private final static Comparator sDisplayNameComparator = new Comparator() {
+    private final static Comparator<MyPackageInfo> sDisplayNameComparator
+            = new Comparator<MyPackageInfo>() {
         public final int
-        compare(Object a, Object b)
-        {
-            CharSequence  sa = ((PackageInfo) a).packageName;
-            CharSequence  sb = ((PackageInfo) b).packageName;
-            return collator.compare(sa, sb);
+        compare(MyPackageInfo a, MyPackageInfo b) {
+            return collator.compare(a.label, b.label);
         }
 
         private final Collator   collator = Collator.getInstance();
@@ -98,6 +110,14 @@
         registerIntentReceivers();
     }
 
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mRegisteredReceiver != null) {
+            unregisterReceiver(mRegisteredReceiver);
+        }
+    }
+
     private void setupAdapter() {
         mAdapter = new PackageListAdapter(this);
         setListAdapter(mAdapter);
@@ -119,9 +139,9 @@
         final int curSelection = getSelectedItemPosition();
         if (curSelection >= 0) {
             // todo: verification dialog for package deletion
-            final PackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
+            final MyPackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
             if (packageInfo != null) {
-                getPackageManager().deletePackage(packageInfo.packageName,
+                getPackageManager().deletePackage(packageInfo.info.packageName,
                                                   new IPackageDeleteObserver.Stub() {
                     public void packageDeleted(boolean succeeded) throws RemoteException {
                         if (succeeded) {
@@ -133,7 +153,7 @@
                                 });
 
                             // todo: verification dialog for data directory
-                            final String dataPath = packageInfo.applicationInfo.dataDir;
+                            final String dataPath = packageInfo.info.applicationInfo.dataDir;
                             // todo: delete the data directory
                         } else {
                             mHandler.post(new Runnable() {
@@ -159,17 +179,17 @@
         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         filter.addDataScheme("package");
-        registerReceiver(new ApplicationsIntentReceiver(), filter);
+        mRegisteredReceiver = new ApplicationsIntentReceiver();
+        registerReceiver(mRegisteredReceiver, filter);
     }
 
     @Override
-    protected void onListItemClick(ListView l, View v, int position, long id)
-    {
-        PackageInfo info =
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        MyPackageInfo info =
             mAdapter.itemForPosition(position);
         if (info != null) {
             Intent intent = new Intent(
-                null, Uri.fromParts("package", info.packageName, null));
+                null, Uri.fromParts("package", info.info.packageName, null));
             intent.setClass(this, PackageSummary.class);
             startActivity(intent);
         }
diff --git a/apps/Development/src/com/android/development/PackageSummary.java b/apps/Development/src/com/android/development/PackageSummary.java
index a6bbbb2..5610559 100644
--- a/apps/Development/src/com/android/development/PackageSummary.java
+++ b/apps/Development/src/com/android/development/PackageSummary.java
@@ -31,6 +31,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
@@ -90,7 +91,8 @@
             info = pm.getPackageInfo(mPackageName,
                 PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS
-                | PackageManager.GET_INSTRUMENTATION);
+                | PackageManager.GET_INSTRUMENTATION
+                | PackageManager.GET_DISABLED_COMPONENTS);
         } catch (PackageManager.NameNotFoundException e) {
         }
 
@@ -192,6 +194,7 @@
                     ActivityInfo ai = info.receivers[i];
                     Button view = (Button)inflate.inflate(
                         R.layout.package_item, null, false);
+                    Log.i("foo", "Receiver #" + i + " of " + N + ": " + ai);
                     setItemText(view, info, ai.name);
                     receivers.addView(view, lp);
                 }