summaryrefslogtreecommitdiffstats
path: root/apps/Development/src/com/android/development
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit5c11852110eeb03dc5a69111354b383f98d15336 (patch)
tree7b26fde6effb80c241f28fc3e620016e7f86418e /apps/Development/src/com/android/development
downloadandroid_development-5c11852110eeb03dc5a69111354b383f98d15336.tar.gz
android_development-5c11852110eeb03dc5a69111354b383f98d15336.tar.bz2
android_development-5c11852110eeb03dc5a69111354b383f98d15336.zip
Initial Contribution
Diffstat (limited to 'apps/Development/src/com/android/development')
-rw-r--r--apps/Development/src/com/android/development/AppPicker.java167
-rw-r--r--apps/Development/src/com/android/development/ArrayAdapter.java78
-rw-r--r--apps/Development/src/com/android/development/ColumnData.java31
-rw-r--r--apps/Development/src/com/android/development/DataList.java134
-rw-r--r--apps/Development/src/com/android/development/Details.java157
-rw-r--r--apps/Development/src/com/android/development/Development.java31
-rw-r--r--apps/Development/src/com/android/development/DevelopmentSettings.java549
-rw-r--r--apps/Development/src/com/android/development/EnterURL.java310
-rw-r--r--apps/Development/src/com/android/development/ExceptionBrowser.java171
-rw-r--r--apps/Development/src/com/android/development/GLSTester.java167
-rw-r--r--apps/Development/src/com/android/development/IRemoteService.aidl24
-rw-r--r--apps/Development/src/com/android/development/InstrumentationList.java197
-rw-r--r--apps/Development/src/com/android/development/LogTextBox.java72
-rw-r--r--apps/Development/src/com/android/development/LogViewer.java169
-rw-r--r--apps/Development/src/com/android/development/MediaScannerActivity.java72
-rw-r--r--apps/Development/src/com/android/development/PackageBrowser.java177
-rw-r--r--apps/Development/src/com/android/development/PackageSummary.java269
-rw-r--r--apps/Development/src/com/android/development/PointerLocation.java192
-rw-r--r--apps/Development/src/com/android/development/PreferredPackages.java189
-rw-r--r--apps/Development/src/com/android/development/RadioIssueReport.java191
-rw-r--r--apps/Development/src/com/android/development/ShowActivity.java122
-rw-r--r--apps/Development/src/com/android/development/StacktraceViewer.java50
-rw-r--r--apps/Development/src/com/android/development/UnderdevelopedSettings.java31
23 files changed, 3550 insertions, 0 deletions
diff --git a/apps/Development/src/com/android/development/AppPicker.java b/apps/Development/src/com/android/development/AppPicker.java
new file mode 100644
index 000000000..693defbf9
--- /dev/null
+++ b/apps/Development/src/com/android/development/AppPicker.java
@@ -0,0 +1,167 @@
+/* //device/java/android/android/app/ResolveListActivity.java
+**
+** Copyright 2006, 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.
+*/
+
+package com.android.development;
+
+import android.app.ActivityManagerNative;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.text.Collator;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class AppPicker extends ListActivity
+{
+ @Override
+ protected void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+
+ mAdapter = new AppListAdapter(this);
+ if (mAdapter.getCount() <= 0) {
+ finish();
+ } else {
+ setListAdapter(mAdapter);
+ }
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ }
+
+ @Override
+ protected void onStop()
+ {
+ super.onStop();
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ ApplicationInfo app = mAdapter.appForPosition(position);
+ Intent intent = new Intent();
+ if (app != null) intent.setAction(app.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);
+ } catch (RemoteException ex) {
+ }
+
+ finish();
+ }
+
+ private final class AppListAdapter extends BaseAdapter
+ {
+ public AppListAdapter(Context context)
+ {
+ mContext = context;
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ mList = context.getPackageManager().getInstalledApplications(0);
+ if (mList != null) {
+ Collections.sort(mList, sDisplayNameComparator);
+ mList.add(0, null);
+ }
+ }
+
+ 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);
+ } else {
+ view = convertView;
+ }
+ 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() {
+ public final int
+ compare(Object a, Object b)
+ {
+ CharSequence sa = ((ApplicationInfo) a).packageName;
+ CharSequence sb = ((ApplicationInfo) b).packageName;
+
+ return collator.compare(sa, sb);
+ }
+
+ private final Collator collator = Collator.getInstance();
+ };
+
+ private AppListAdapter mAdapter;
+}
+
diff --git a/apps/Development/src/com/android/development/ArrayAdapter.java b/apps/Development/src/com/android/development/ArrayAdapter.java
new file mode 100644
index 000000000..378e98f24
--- /dev/null
+++ b/apps/Development/src/com/android/development/ArrayAdapter.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+
+import java.util.List;
+
+public abstract class ArrayAdapter<E> extends BaseAdapter
+{
+ public ArrayAdapter(Context context, int layoutRes) {
+ mContext = context;
+ mInflater = (LayoutInflater)context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ mLayoutRes = layoutRes;
+ }
+
+ public void setSource(List<E> list) {
+ mList = list;
+ }
+
+ public abstract void bindView(View view, E item);
+
+ public E itemForPosition(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(mLayoutRes, parent, false);
+ } else {
+ view = convertView;
+ }
+ bindView(view, mList.get(position));
+ return view;
+ }
+
+ private final Context mContext;
+ private final LayoutInflater mInflater;
+ private final int mLayoutRes;
+ private List<E> mList;
+}
+
diff --git a/apps/Development/src/com/android/development/ColumnData.java b/apps/Development/src/com/android/development/ColumnData.java
new file mode 100644
index 000000000..28781c2d7
--- /dev/null
+++ b/apps/Development/src/com/android/development/ColumnData.java
@@ -0,0 +1,31 @@
+/* //device/apps/Notes/NotesList.java
+**
+** Copyright 2006, 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.
+*/
+package com.android.development;
+
+import java.util.ArrayList;
+
+class ColumnData
+{
+ ColumnData(String k, String v)
+ {
+ key = k;
+ value = v;
+ }
+ public String key;
+ public String value;
+}
+
diff --git a/apps/Development/src/com/android/development/DataList.java b/apps/Development/src/com/android/development/DataList.java
new file mode 100644
index 000000000..5dee2fe9c
--- /dev/null
+++ b/apps/Development/src/com/android/development/DataList.java
@@ -0,0 +1,134 @@
+/* //device/apps/Notes/NotesList.java
+**
+** Copyright 2006, 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.
+*/
+package com.android.development;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+import java.util.ArrayList;
+
+public class DataList extends ListActivity
+{
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+
+ mCursor = getContentResolver().query(intent.getData(), null, null, null, null);
+ mDisplay = intent.getStringExtra("display");
+ if (mDisplay == null) {
+ mDisplay = "_id";
+ }
+
+ if (mCursor != null) {
+ setListAdapter(new SimpleCursorAdapter(
+ this,
+ R.layout.url_list,
+ mCursor,
+ new String[] {mDisplay},
+ new int[] {android.R.id.text1}));
+ }
+ }
+
+ public void onStop()
+ {
+ super.onStop();
+
+ if (mCursor != null) {
+ mCursor.deactivate();
+ }
+ }
+
+ public void onResume()
+ {
+ super.onResume();
+
+ if (mCursor != null) {
+ mCursor.requery();
+ }
+
+ setTitle("Showing " + mDisplay);
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ super.onCreateOptionsMenu(menu);
+ menu.add(0, 0, 0, "Requery").setOnMenuItemClickListener(mRequery);
+ return true;
+ }
+
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ mCursor.moveToPosition(position);
+
+ ArrayList<ColumnData> data = new ArrayList<ColumnData>();
+
+ String[] columnNames = mCursor.getColumnNames();
+ for (int i=0; i<columnNames.length; i++) {
+ String str = mCursor.getString(i);
+ ColumnData cd = new ColumnData(columnNames[i], str);
+ data.add(cd);
+ }
+
+
+ Uri uri = null;
+ int idCol = mCursor.getColumnIndex("_id");
+ if (idCol >= 0) {
+ uri = Uri.withAppendedPath(getIntent().getData(), mCursor.getString(idCol));
+ }
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.setClass(this, Details.class);
+
+ intent.putExtra("data", data);
+ int displayColumn = mCursor.getColumnIndex(mDisplay);
+ if (displayColumn >= 0) {
+ intent.putExtra("title",
+ ((ColumnData)data.get(displayColumn)).value);
+ }
+
+ startActivity(intent);
+ }
+
+ MenuItem.OnMenuItemClickListener mRequery = new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ // Should just do requery on cursor, but
+ // doesn't work right now. So do this instead.
+ mCursor.requery();
+ if (mCursor != null) {
+ setListAdapter(new SimpleCursorAdapter(
+ DataList.this,
+ R.layout.url_list,
+ mCursor,
+ new String[] {mDisplay},
+ new int[] {android.R.id.text1}));
+ }
+ return true;
+ }
+ };
+
+ private String mDisplay;
+ private Cursor mCursor;
+}
diff --git a/apps/Development/src/com/android/development/Details.java b/apps/Development/src/com/android/development/Details.java
new file mode 100644
index 000000000..16722a3ab
--- /dev/null
+++ b/apps/Development/src/com/android/development/Details.java
@@ -0,0 +1,157 @@
+/* //device/apps/Notes/NotesList.java
+**
+** Copyright 2006, 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.
+*/
+package com.android.development;
+
+import java.util.ArrayList;
+
+import android.content.Intent;
+import android.app.Activity;
+import android.database.Cursor;
+import android.graphics.Typeface;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class Details extends Activity
+{
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+
+ String title = intent.getStringExtra("title");
+ if (title == null) {
+ title = "Details";
+ }
+ setTitle(title);
+
+ mScrollView = new ScrollView(this);
+ setContentView(mScrollView);
+ mScrollView.setFocusable(true);
+
+ mData = (ArrayList<ColumnData>)getIntent().getExtra("data");
+ addDataViews();
+ }
+
+ public void onResume()
+ {
+ super.onResume();
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ super.onCreateOptionsMenu(menu);
+ menu.add(0, 0, 0, "Requery").setOnMenuItemClickListener(mRequery);
+ menu.add(0, 0, 0, "Print to stdout").setOnMenuItemClickListener(mPrintToStdout);
+ return true;
+ }
+
+ void addDataViews()
+ {
+ int oldScroll = 0;
+
+ if (mLinearLayout != null) {
+ mScrollView.removeView(mLinearLayout);
+ }
+ mLinearLayout = new LinearLayout(this);
+ mScrollView.addView(mLinearLayout, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+
+ // Here in onStart, we're given data. We use that because some
+ // data that we show is transient and can't be retrieved from a url.
+ // We'll try to use that in requery
+ int count = mData.size();
+ for (int i=0; i<count; i++) {
+ ColumnData cd = mData.get(i);
+ TextView label = makeView(cd.key, true, 12);
+ TextView contents = makeView(cd.value, false, 12);
+ contents.setPadding(3, 0, 0, i==count-1?0:3);
+ mLinearLayout.addView(label, lazy());
+ mLinearLayout.addView(contents, lazy());
+ }
+ }
+
+ TextView makeView(String str, boolean bold, int fontSize)
+ {
+ if (str == null) {
+ str = "(null)";
+ }
+ TextView v = new TextView(this);
+ v.setText(str);
+ v.setTextSize(fontSize);
+ if (bold) {
+ v.setTypeface(Typeface.DEFAULT_BOLD);
+ }
+ return v;
+ }
+
+ LinearLayout.LayoutParams lazy()
+ {
+ return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ }
+
+ MenuItem.OnMenuItemClickListener mRequery = new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = getIntent();
+ Cursor c = getContentResolver().query(intent.getData(), null, null, null, null);
+ if (c != null && c.moveToNext()) {
+ mData.clear();
+ String[] columnNames = c.getColumnNames();
+ for (int i=0; i<columnNames.length; i++) {
+ String str = c.getString(i);
+ ColumnData cd = new ColumnData(columnNames[i], str);
+ mData.add(cd);
+ }
+ addDataViews();
+ } else {
+ TextView error = new TextView(Details.this);
+ error.setText("Showing old data.\nURL couldn't be requeried:\n"
+ + intent.getData());
+ error.setTextColor(0xffff0000);
+ error.setTextSize(11);
+ mLinearLayout.addView(error, 0, lazy());
+ }
+ return true;
+ }
+ };
+
+ MenuItem.OnMenuItemClickListener mPrintToStdout = new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ System.out.println("=== begin data ===");
+ int count = mData.size();
+ for (int i=0; i<count; i++) {
+ ColumnData cd = mData.get(i);
+ System.out.println(" " + cd.key + ": " + cd.value);
+ }
+ System.out.println("=== end data ===");
+ return true;
+ }
+ };
+
+ LinearLayout mLinearLayout;
+ ScrollView mScrollView;
+ ArrayList<ColumnData> mData;
+}
diff --git a/apps/Development/src/com/android/development/Development.java b/apps/Development/src/com/android/development/Development.java
new file mode 100644
index 000000000..a3979f219
--- /dev/null
+++ b/apps/Development/src/com/android/development/Development.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.LauncherActivity;
+import android.content.Intent;
+
+public class Development extends LauncherActivity
+{
+ @Override
+ protected Intent getTargetIntent() {
+ Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
+ targetIntent.addCategory(Intent.CATEGORY_TEST);
+ targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return targetIntent;
+ }
+}
diff --git a/apps/Development/src/com/android/development/DevelopmentSettings.java b/apps/Development/src/com/android/development/DevelopmentSettings.java
new file mode 100644
index 000000000..03536bbe7
--- /dev/null
+++ b/apps/Development/src/com/android/development/DevelopmentSettings.java
@@ -0,0 +1,549 @@
+/* //device/apps/Settings/src/com/android/settings/Keyguard.java
+**
+** Copyright 2006, 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.
+*/
+
+package com.android.development;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.ServiceManager;
+import android.os.ServiceManagerNative;
+import android.provider.Settings;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.IWindowManager;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.Spinner;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Map;
+
+public class DevelopmentSettings extends Activity {
+ private static final String TAG = "DevelopmentSettings";
+ private static final int DEBUG_APP_REQUEST = 1;
+
+ private Button mDebugAppButton;
+ private CheckBox mEnableAdbCB;
+ private CheckBox mWaitForDebuggerCB;
+ private CheckBox mAlwaysFinishCB;
+ private CheckBox mShowLoadCB;
+ private CheckBox mShowCpuCB;
+ private CheckBox mEnableGLCB;
+ private CheckBox mShowUpdatesCB;
+ private CheckBox mShowBackgroundCB;
+ private CheckBox mShowSleepCB;
+ private CheckBox mShowMapsCompassCB;
+ private CheckBox mKeepScreenOnCB;
+ private CheckBox mShowXmppCB;
+ private Spinner mMaxProcsSpinner;
+ private Spinner mWindowAnimationScaleSpinner;
+ private Spinner mTransitionAnimationScaleSpinner;
+ private Spinner mFontHintingSpinner;
+
+ private String mDebugApp;
+ private boolean mEnableAdb;
+ private boolean mWaitForDebugger;
+ private boolean mAlwaysFinish;
+ private int mProcessLimit;
+ private boolean mShowSleep;
+ private boolean mShowMapsCompass;
+ private boolean mKeepScreenOn;
+ private boolean mShowXmpp;
+ private AnimationScaleSelectedListener mWindowAnimationScale
+ = new AnimationScaleSelectedListener(0);
+ private AnimationScaleSelectedListener mTransitionAnimationScale
+ = new AnimationScaleSelectedListener(1);
+ private SharedPreferences mSharedPrefs;
+ private IWindowManager mWindowManager;
+
+ private static final boolean FONT_HINTING_ENABLED = true;
+ private static final String FONT_HINTING_FILE = "/data/misc/font-hack";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.development_settings);
+
+ mDebugAppButton = (Button)findViewById(R.id.debug_app);
+ mDebugAppButton.setOnClickListener(mDebugAppClicked);
+ mEnableAdbCB = (CheckBox)findViewById(R.id.enable_adb);
+ mEnableAdbCB.setOnClickListener(mEnableAdbClicked);
+ mWaitForDebuggerCB = (CheckBox)findViewById(R.id.wait_for_debugger);
+ mWaitForDebuggerCB.setOnClickListener(mWaitForDebuggerClicked);
+ mAlwaysFinishCB = (CheckBox)findViewById(R.id.always_finish);
+ mAlwaysFinishCB.setOnClickListener(mAlwaysFinishClicked);
+ mShowLoadCB = (CheckBox)findViewById(R.id.show_load);
+ mShowLoadCB.setOnClickListener(mShowLoadClicked);
+ mShowCpuCB = (CheckBox)findViewById(R.id.show_cpu);
+ mShowCpuCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1000));
+ mEnableGLCB = (CheckBox)findViewById(R.id.enable_gl);
+ mEnableGLCB.getLayoutParams().height = 0; // doesn't do anything
+ mEnableGLCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1004));
+ mShowUpdatesCB = (CheckBox)findViewById(R.id.show_updates);
+ mShowUpdatesCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1002));
+ mShowBackgroundCB = (CheckBox)findViewById(R.id.show_background);
+ mShowBackgroundCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1003));
+ mShowSleepCB = (CheckBox)findViewById(R.id.show_sleep);
+ mShowSleepCB.setOnClickListener(mShowSleepClicked);
+ mShowMapsCompassCB = (CheckBox)findViewById(R.id.show_maps_compass);
+ mShowMapsCompassCB.setOnClickListener(mShowMapsCompassClicked);
+ mKeepScreenOnCB = (CheckBox)findViewById(R.id.keep_screen_on);
+ mKeepScreenOnCB.setOnClickListener(mKeepScreenOnClicked);
+ mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
+ mShowXmppCB.setOnClickListener(mShowXmppClicked);
+ mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
+ mMaxProcsSpinner.setOnItemSelectedListener(mMaxProcsChanged);
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(
+ this,
+ android.R.layout.simple_spinner_item,
+ new String[] {
+ "No App Process Limit",
+ "Max 1 App Process",
+ "Max 2 App Processes",
+ "Max 3 App Processes",
+ "Max 4 App Processes" });
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mMaxProcsSpinner.setAdapter(adapter);
+ mWindowAnimationScaleSpinner = setupAnimationSpinner(
+ R.id.window_animation_scale, mWindowAnimationScale, "Window");
+ mTransitionAnimationScaleSpinner = setupAnimationSpinner(
+ R.id.transition_animation_scale, mTransitionAnimationScale, "Transition");
+
+ if (FONT_HINTING_ENABLED) {
+ mFontHintingSpinner = (Spinner)findViewById(R.id.font_hinting);
+ mFontHintingSpinner.setOnItemSelectedListener(mFontHintingChanged);
+ adapter = new ArrayAdapter<String>(
+ this,
+ android.R.layout.simple_spinner_item,
+ new String[] {
+ "Light Hinting",
+ "Medium Hinting" });
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mFontHintingSpinner.setAdapter(adapter);
+ }
+ mSharedPrefs = getSharedPreferences("global", 0);
+ mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+ }
+
+ Spinner setupAnimationSpinner(int resid,
+ AnimationScaleSelectedListener listener, String name) {
+ Spinner spinner = (Spinner)findViewById(resid);
+ spinner.setOnItemSelectedListener(listener);
+ ArrayAdapter adapter = new ArrayAdapter<String>(
+ this,
+ android.R.layout.simple_spinner_item,
+ new String[] {
+ name + " Animation Scale 1x",
+ name + " Animation Scale 2x",
+ name + " Animation Scale 5x",
+ name + " Animation Scale 10x",
+ name + " Animation Off" });
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ listener.spinner = spinner;
+ return spinner;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateDebugOptions();
+ updateFinishOptions();
+ updateProcessLimitOptions();
+ updateSharedOptions();
+ updateFlingerOptions();
+ updateSleepOptions();
+ updateMapsCompassOptions();
+ updateKeepScreenOnOptions();
+ updateXmppOptions();
+
+ try {
+ FileInputStream in = new FileInputStream( FONT_HINTING_FILE );
+ int mode = in.read() - 48;
+ if (mode >= 0 && mode < 3)
+ mFontHintingSpinner.setSelection(mode);
+ in.close();
+ } catch (Exception e) {
+ }
+
+ mWindowAnimationScale.load();
+ mTransitionAnimationScale.load();
+ }
+
+ private void writeDebugOptions() {
+ try {
+ ActivityManagerNative.getDefault().setDebugApp(
+ mDebugApp, mWaitForDebugger, true);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ private void updateDebugOptions() {
+ mDebugApp = Settings.System.getString(
+ getContentResolver(), Settings.System.DEBUG_APP);
+ mWaitForDebugger = Settings.System.getInt(
+ getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
+ mEnableAdb = Settings.System.getInt(
+ getContentResolver(), Settings.System.ADB_ENABLED, 0) != 0;
+
+ mDebugAppButton.setText(
+ mDebugApp == null || mDebugApp.length() == 0 ? "(none)" : mDebugApp);
+ mWaitForDebuggerCB.setChecked(mWaitForDebugger);
+ mEnableAdbCB.setChecked(mEnableAdb);
+ }
+
+ private void writeFinishOptions() {
+ try {
+ ActivityManagerNative.getDefault().setAlwaysFinish(mAlwaysFinish);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ private void updateFinishOptions() {
+ mAlwaysFinish = Settings.System.getInt(
+ getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
+ mAlwaysFinishCB.setChecked(mAlwaysFinish);
+ }
+
+ private void writeProcessLimitOptions() {
+ try {
+ ActivityManagerNative.getDefault().setProcessLimit(mProcessLimit);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ private void updateProcessLimitOptions() {
+ try {
+ mProcessLimit = ActivityManagerNative.getDefault().getProcessLimit();
+ mMaxProcsSpinner.setSelection(mProcessLimit);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ private void updateSharedOptions() {
+ mShowLoadCB.setChecked(Settings.System.getInt(getContentResolver(),
+ Settings.System.SHOW_PROCESSES, 0) != 0);
+ }
+
+ private void updateFlingerOptions() {
+ // magic communication with surface flinger.
+ try {
+ IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+ if (flinger != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ flinger.transact(1010, data, reply, 0);
+ int v;
+ v = reply.readInt();
+ mShowCpuCB.setChecked(v != 0);
+ v = reply.readInt();
+ mEnableGLCB.setChecked(v != 0);
+ v = reply.readInt();
+ mShowUpdatesCB.setChecked(v != 0);
+ v = reply.readInt();
+ mShowBackgroundCB.setChecked(v != 0);
+ reply.recycle();
+ data.recycle();
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ private void writeSleepOptions() {
+ try {
+ FileOutputStream os = new FileOutputStream(
+ "/sys/devices/platform/gpio_sleep_debug/enable", true);
+ if(mShowSleep)
+ os.write(new byte[] { (byte)'1' });
+ else
+ os.write(new byte[] { (byte)'0' });
+ os.close();
+ } catch (Exception e) {
+ Log.w(TAG, "Failed setting gpio_sleep_debug");
+ }
+ }
+
+ private void updateSleepOptions() {
+ try {
+ FileInputStream is = new FileInputStream(
+ "/sys/devices/platform/gpio_sleep_debug/enable");
+ int character = is.read();
+ mShowSleep = character == '1';
+ is.close();
+ } catch (Exception e) {
+ Log.w(TAG, "Failed reading gpio_sleep_debug");
+ mShowSleep = false;
+ }
+ mShowSleepCB.setChecked(mShowSleep);
+ }
+
+ private void writeMapsCompassOptions() {
+ try {
+ Context c = createPackageContext("com.google.android.apps.maps", 0);
+ c.getSharedPreferences("extra-features", MODE_WORLD_WRITEABLE)
+ .edit()
+ .putBoolean("compass", mShowMapsCompass)
+ .commit();
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Failed setting maps compass");
+ e.printStackTrace();
+ }
+ }
+
+ private void updateMapsCompassOptions() {
+ try {
+ Context c = createPackageContext("com.google.android.apps.maps", 0);
+ mShowMapsCompass = c.getSharedPreferences("extra-features", MODE_WORLD_READABLE)
+ .getBoolean("compass", false);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Failed reading maps compass");
+ e.printStackTrace();
+ }
+ mShowMapsCompassCB.setChecked(mShowMapsCompass);
+ }
+
+ private void writeKeepScreenOnOptions() {
+ Settings.System.putInt(getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+ mKeepScreenOn ? 1 : 0);
+ }
+
+ private void updateKeepScreenOnOptions() {
+ mKeepScreenOn = Settings.System.getInt(getContentResolver(),
+ Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0;
+ mKeepScreenOnCB.setChecked(mKeepScreenOn);
+ }
+
+ private void writeXmppOptions() {
+ Settings.System.setShowGTalkServiceStatus(getContentResolver(), mShowXmpp);
+ }
+
+ private void updateXmppOptions() {
+ mShowXmpp = Settings.System.getShowGTalkServiceStatus(getContentResolver());
+ mShowXmppCB.setChecked(mShowXmpp);
+ }
+
+ private View.OnClickListener mDebugAppClicked = new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClass(DevelopmentSettings.this, AppPicker.class);
+ startActivityForResult(intent, DEBUG_APP_REQUEST);
+ }
+ };
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (requestCode == DEBUG_APP_REQUEST && resultCode == RESULT_OK) {
+ mDebugApp = intent.getAction();
+ writeDebugOptions();
+ updateDebugOptions();
+ }
+ }
+
+ private View.OnClickListener mEnableAdbClicked = new View.OnClickListener() {
+ public void onClick(View v) {
+ Settings.System.putInt(getContentResolver(), Settings.System.ADB_ENABLED,
+ ((CheckBox)v).isChecked() ? 1 : 0);
+ }
+ };
+
+ private View.OnClickListener mWaitForDebuggerClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mWaitForDebugger = ((CheckBox)v).isChecked();
+ writeDebugOptions();
+ updateDebugOptions();
+ }
+ };
+
+ private View.OnClickListener mAlwaysFinishClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mAlwaysFinish = ((CheckBox)v).isChecked();
+ writeFinishOptions();
+ updateFinishOptions();
+ }
+ };
+
+ private View.OnClickListener mShowLoadClicked = new View.OnClickListener() {
+ public void onClick(View v) {
+ boolean value = ((CheckBox)v).isChecked();
+ Settings.System.putInt(getContentResolver(),
+ Settings.System.SHOW_PROCESSES, value ? 1 : 0);
+ Intent service = (new Intent())
+ .setClassName("android", "com.android.server.LoadAverageService");
+ if (value) {
+ startService(service);
+ } else {
+ stopService(service);
+ }
+ }
+ };
+
+ private class SurfaceFlingerClicker implements CheckBox.OnCheckedChangeListener {
+ SurfaceFlingerClicker(int code) {
+ mCode = code;
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ try {
+ IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+ if (flinger != null) {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeInt(isChecked ? 1 : 0);
+ flinger.transact(mCode, data, null, 0);
+ data.recycle();
+
+ updateFlingerOptions();
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ final int mCode;
+ }
+
+ private View.OnClickListener mShowSleepClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mShowSleep = ((CheckBox)v).isChecked();
+ writeSleepOptions();
+ updateSleepOptions();
+ }
+ };
+
+ private View.OnClickListener mShowMapsCompassClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mShowMapsCompass = ((CheckBox)v).isChecked();
+ writeMapsCompassOptions();
+ updateMapsCompassOptions();
+ }
+ };
+
+
+ private View.OnClickListener mKeepScreenOnClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mKeepScreenOn = ((CheckBox)v).isChecked();
+ writeKeepScreenOnOptions();
+ updateKeepScreenOnOptions();
+ }
+ };
+
+ private View.OnClickListener mShowXmppClicked = new View.OnClickListener() {
+ public void onClick(View v) {
+ mShowXmpp = ((CheckBox)v).isChecked();
+ // can streamline these calls, but keeping consistent with the
+ // other development settings code.
+ writeXmppOptions();
+ updateXmppOptions();
+ }
+ };
+
+ private Spinner.OnItemSelectedListener mMaxProcsChanged
+ = new Spinner.OnItemSelectedListener() {
+ public void onItemSelected(android.widget.AdapterView av, View v,
+ int position, long id) {
+ mProcessLimit = position;
+ writeProcessLimitOptions();
+ }
+
+ public void onNothingSelected(android.widget.AdapterView av) {
+ }
+ };
+
+ private Spinner.OnItemSelectedListener mFontHintingChanged
+ = new Spinner.OnItemSelectedListener() {
+ public void onItemSelected(android.widget.AdapterView av, View v,
+ int position, long id) {
+ try {
+ FileOutputStream out = new FileOutputStream( FONT_HINTING_FILE );
+ out.write(position+48);
+ out.close();
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to write font hinting settings to /data/misc/font-hack");
+ }
+ }
+
+ public void onNothingSelected(android.widget.AdapterView av) {
+ }
+ };
+
+ class AnimationScaleSelectedListener implements OnItemSelectedListener {
+ final int which;
+ float scale;
+ Spinner spinner;
+
+ AnimationScaleSelectedListener(int _which) {
+ which = _which;
+ }
+
+ void load() {
+ try {
+ scale = mWindowManager.getAnimationScale(which);
+
+ if (scale > 0.1f && scale < 2.0f) {
+ spinner.setSelection(0);
+ } else if (scale >= 2.0f && scale < 3.0f) {
+ spinner.setSelection(1);
+ } else if (scale >= 4.9f && scale < 6.0f) {
+ spinner.setSelection(2);
+ } else if (scale >= 9.9f && scale < 11.0f) {
+ spinner.setSelection(3);
+ } else {
+ spinner.setSelection(4);
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ public void onItemSelected(android.widget.AdapterView av, View v,
+ int position, long id) {
+ switch (position) {
+ case 0: scale = 1.0f; break;
+ case 1: scale = 2.0f; break;
+ case 2: scale = 5.0f; break;
+ case 3: scale = 10.0f; break;
+ case 4: scale = 0.0f; break;
+ default: break;
+ }
+
+ try {
+ mWindowManager.setAnimationScale(which, scale);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public void onNothingSelected(android.widget.AdapterView av) {
+ }
+ }
+}
diff --git a/apps/Development/src/com/android/development/EnterURL.java b/apps/Development/src/com/android/development/EnterURL.java
new file mode 100644
index 000000000..72f58de82
--- /dev/null
+++ b/apps/Development/src/com/android/development/EnterURL.java
@@ -0,0 +1,310 @@
+/* //device/apps/Notes/NotesList.java
+**
+** Copyright 2006, 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.
+*/
+package com.android.development;
+
+import android.app.ListActivity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.pim.DateUtils;
+import android.text.Editable;
+import android.text.Selection;
+import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.graphics.Rect;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+
+public class EnterURL extends ListActivity
+{
+ private static final int DATABASE_VERSION = 1;
+ public static class UrlEditText extends EditText
+ {
+ public UrlEditText(Context context, AttributeSet attrs)
+ {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)
+ {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ if (focused) {
+ Editable text = getText();
+ String str = text.toString();
+ int highlightStart = 0;
+ if (str.startsWith("content://")) {
+ highlightStart = "content://".length();
+ }
+ Selection.setSelection(text, highlightStart, text.length());
+ }
+ }
+ }
+
+ public static class DisplayEditText extends EditText
+ {
+ public DisplayEditText(Context context, AttributeSet attrs)
+ {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)
+ {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ if (focused) {
+ Editable text = getText();
+ Selection.setSelection(text, 0, text.length());
+ }
+ }
+ }
+
+ @Override
+ public View onCreateView(String name, Context context, AttributeSet attrs)
+ {
+ if (name.equals("com.android.development.UrlEditText")) {
+ return new UrlEditText(this, attrs);
+ }
+ if (name.equals("com.android.development.DisplayEditText")) {
+ return new DisplayEditText(this, attrs);
+ }
+ return null;
+ }
+
+ View.OnClickListener mViewItemAction = new View.OnClickListener () {
+ public void onClick(View v)
+ {
+ String url = mUrlField.getText().toString();
+ String display = mDisplayField.getText().toString();
+ viewItem(url, display);
+ }
+ };
+
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ setContentView(R.layout.enter_url);
+
+ // display
+ mDisplayField = (DisplayEditText)findViewById(R.id.display_edit_text);
+ mDisplayField.setOnClickListener(mViewItemAction);
+ // url
+ mUrlField = (UrlEditText)findViewById(R.id.url_edit_text);
+ mUrlField.setOnClickListener(mViewItemAction);
+ }
+
+ public void onStop()
+ {
+ super.onStop();
+
+ if (mCursor != null) {
+ mCursor.deactivate();
+ }
+ }
+
+ public void onResume()
+ {
+ super.onResume();
+
+ // show the history
+ loadPrefs();
+ fillListView();
+ if (mHistory.size() > 0) {
+ ListView lv = this.getListView();
+ lv.setSelection(0);
+ lv.requestFocus();
+ }
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ super.onCreateOptionsMenu(menu);
+ menu.add(0, 0, 0, "Clear Bookmarks").setOnMenuItemClickListener(mClearBookmarks);
+ return true;
+ }
+
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ HistoryEntry he = mHistory.get(position);
+ viewItem(he.url, he.display);
+ }
+
+ private final void viewItem(String url, String display)
+ {
+ // -------------- save this in the history ----------------
+ // look in the history
+ int count = mHistory.size();
+ int i;
+ for (i=0; i<count; i++) {
+ HistoryEntry he = mHistory.get(i);
+ if (he.url.equals(url) && he.display.equals(display)) {
+ he.updateAccessTime();
+ mHistory.remove(i);
+ mHistory.add(0, he);
+ break;
+ }
+ }
+ if (i >= count) {
+ // didn't find it, add it first
+ HistoryEntry he = new HistoryEntry();
+ he.url = url;
+ he.display = display;
+ he.updateAccessTime();
+ mHistory.add(0, he);
+ }
+
+ savePrefs();
+
+ // -------------- view it ---------------------------------
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ intent.setClass(this, DataList.class);
+ intent.putExtra("display", display);
+ startActivity(intent);
+ }
+
+ MenuItem.OnMenuItemClickListener mClearBookmarks = new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ mHistory.clear();
+ savePrefs();
+ fillListView();
+ return true;
+ }
+ };
+
+ private void fillListView()
+ {
+ loadPrefs();
+ ArrayList<HashMap<String, String>> d = new ArrayList<HashMap<String, String>>();
+ int count = mHistory.size();
+ for (int i=0; i<count; i++) {
+ HashMap<String, String> m = new HashMap<String, String>();
+ HistoryEntry he = mHistory.get(i);
+ m.put("title", he.url + " (" + he.display + ")");
+ d.add(m);
+ }
+ setListAdapter(new SimpleAdapter(this, d, R.layout.url_list,
+ new String[] {"title"},
+ new int[] {android.R.id.text1}));
+ }
+
+ SQLiteDatabase openDB()
+ {
+ SQLiteDatabase db = null;
+ db = openOrCreateDatabase("inspector.db", 0, null);
+ int version = db.getVersion();
+ if (version != DATABASE_VERSION) {
+ db.execSQL("CREATE TABLE History ("
+ + " url TEXT,"
+ + " display TEXT,"
+ + " lastAccessTime TEXT"
+ + ");");
+ db.execSQL("CREATE TABLE FieldState ("
+ + " url TEXT,"
+ + " display TEXT"
+ + ");");
+ db.setVersion(DATABASE_VERSION);
+ }
+ return db;
+ }
+
+ private void loadPrefs()
+ {
+ SQLiteDatabase db = openDB();
+ Cursor c = db.query("History",
+ new String[] { "url", "display", "lastAccessTime" },
+ null, null, null, null, "lastAccessTime DESC");
+ int urlCol = c.getColumnIndex("url");
+ int accessCol = c.getColumnIndex("lastAccessTime");
+ int displayCol = c.getColumnIndex("display");
+ mHistory.clear();
+ while (c.moveToNext()) {
+ HistoryEntry he = new HistoryEntry();
+ he.url = c.getString(urlCol);
+ he.display = c.getString(displayCol);
+ he.lastAccessTime = c.getString(accessCol);
+ mHistory.add(he);
+ }
+
+ c = db.query("FieldState", null, null, null, null, null, null);
+ if (c.moveToNext()) {
+ urlCol = c.getColumnIndex("url");
+ displayCol = c.getColumnIndex("display");
+ mUrlField.setText(c.getString(urlCol));
+ mDisplayField.setText(c.getString(displayCol));
+ } else {
+ mDisplayField.setText("_id");
+ mUrlField.setText("content://");
+ }
+
+ db.close();
+ }
+
+ private void savePrefs()
+ {
+ ContentValues m;
+ HistoryEntry he;
+
+ SQLiteDatabase db = openDB();
+ db.execSQL("DELETE FROM History;");
+ int count = mHistory.size();
+ for (int i=0; i<count; i++) {
+ m = new ContentValues();
+ he = mHistory.get(i);
+ m.put("url", he.url);
+ m.put("display", he.display);
+ m.put("lastAccessTime", he.lastAccessTime);
+ db.insert("History", null, m);
+ }
+
+ db.execSQL("DELETE FROM FieldState");
+ m = new ContentValues();
+ m.put("url", mUrlField.getText().toString());
+ m.put("display", mDisplayField.getText().toString());
+ db.insert("FieldState", null, m);
+
+ db.close();
+ }
+
+ private class HistoryEntry
+ {
+ public String url;
+ public String display;
+ public String lastAccessTime;
+ public void updateAccessTime()
+ {
+ this.lastAccessTime = DateUtils.writeDateTime(
+ new GregorianCalendar());
+ }
+ }
+
+ private ArrayList<HistoryEntry> mHistory = new ArrayList<HistoryEntry>();
+ private UrlEditText mUrlField;
+ private DisplayEditText mDisplayField;
+ private Cursor mCursor;
+}
diff --git a/apps/Development/src/com/android/development/ExceptionBrowser.java b/apps/Development/src/com/android/development/ExceptionBrowser.java
new file mode 100644
index 000000000..63270aab5
--- /dev/null
+++ b/apps/Development/src/com/android/development/ExceptionBrowser.java
@@ -0,0 +1,171 @@
+/*
+** Copyright 2007, 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.
+*/
+
+package com.android.development;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.ContentObserver;
+import android.database.DataSetObserver;
+import android.graphics.Typeface;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Checkin;
+import android.server.data.CrashData;
+import android.server.data.ThrowableData;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.KeyEvent;
+import android.widget.*;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ *
+ *
+ */
+public class ExceptionBrowser extends ListActivity {
+ /** Logging identifier. */
+ private static final String TAG = "ExceptionBrowser";
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Cursor cursor = getContentResolver().query(
+ Checkin.Crashes.CONTENT_URI,
+ new String[] { Checkin.Crashes._ID, Checkin.Crashes.DATA },
+ null, null, null);
+
+ if (cursor != null) {
+ startManagingCursor(cursor);
+
+ setListAdapter(new CursorAdapter(this, cursor, true) {
+ public View newView(Context context, Cursor c, ViewGroup v) {
+ return new CrashListItem(context);
+ }
+
+ public void bindView(View view, Context c, Cursor cursor) {
+ CrashListItem item = (CrashListItem) view;
+ try {
+ String data = cursor.getString(1);
+ CrashData crash = new CrashData(
+ new DataInputStream(
+ new ByteArrayInputStream(
+ Base64.decodeBase64(data.getBytes()))));
+
+ ThrowableData exc = crash.getThrowableData();
+ item.setText(exc.getType() + ": " + exc.getMessage());
+ item.setCrashData(crash);
+ } catch (IOException e) {
+ item.setText("Invalid crash: " + e);
+ Log.e(TAG, "Invalid crash", e);
+ }
+ }
+ });
+ } else {
+ // No database, no exceptions, empty list.
+ setListAdapter(new BaseAdapter() {
+ public int getCount() {
+ return 0;
+ }
+
+ public Object getItem(int position) {
+ throw new AssertionError();
+ }
+
+ public long getItemId(int position) {
+ throw new AssertionError();
+ }
+
+ public View getView(int position, View convertView,
+ ViewGroup parent) {
+ throw new AssertionError();
+ }
+ });
+ }
+ }
+
+ private static final int UPLOAD_ID = Menu.FIRST;
+ private static final int CLEAR_ID = Menu.FIRST + 1;
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ menu.add(0, UPLOAD_ID, 0, R.string.menu_upload_exceptions);
+ menu.add(0, CLEAR_ID, 0, R.string.menu_clear_exceptions);
+
+ return true;
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle all of the possible menu actions.
+ switch (item.getItemId()) {
+ case UPLOAD_ID:
+ sendBroadcast(new Intent(Checkin.TriggerIntent.ACTION));
+ break;
+ case CLEAR_ID:
+ getContentResolver().delete(
+ Checkin.Crashes.CONTENT_URI, null, null);
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ static class CrashListItem extends TextView {
+ CrashData crashData = null;
+
+ public CrashListItem(Context context) {
+ super(context);
+ setTextSize(10);
+ setTypeface(Typeface.MONOSPACE);
+ }
+
+ public CrashData getCrashData() {
+ return crashData;
+ }
+
+ public void setCrashData(CrashData crashData) {
+ this.crashData = crashData;
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View view, int pos, long id) {
+ // TODO: Use a generic VIEW action on the crash's content URI.
+ CrashData crash = ((CrashListItem) view).getCrashData();
+ if (crash != null) {
+ Intent intent = new Intent();
+ intent.setClass(this, StacktraceViewer.class);
+ intent.putExtra(
+ CrashData.class.getName(),
+ crash.getThrowableData().toString());
+ startActivity(intent);
+ }
+ }
+}
diff --git a/apps/Development/src/com/android/development/GLSTester.java b/apps/Development/src/com/android/development/GLSTester.java
new file mode 100644
index 000000000..57b812083
--- /dev/null
+++ b/apps/Development/src/com/android/development/GLSTester.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import com.google.android.googleapps.GoogleLoginCredentialsResult;
+import com.google.android.googlelogin.GoogleLoginServiceConstants;
+import com.google.android.googleapps.IGoogleLoginService;
+import com.google.android.googleapps.LoginData;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.Spinner;
+
+/**
+ * Using a LogTextBox to display a scrollable text area
+ * to which text is appended.
+ *
+ */
+public class GLSTester extends Activity {
+
+ private static final String TAG = "GLSTester";
+
+ private LogTextBox mText;
+
+ private IGoogleLoginService mGls = null;
+ private ServiceConnection mConnection = null;
+
+ CheckBox mDoNotify = null;
+ CheckBox mRunIntent = null;
+ Spinner mService = null;
+
+ private class Listener implements View.OnClickListener {
+ private boolean mRequireGoogle;
+
+ public Listener(boolean requireGoogle) {
+ mRequireGoogle = requireGoogle;
+ }
+
+ public void onClick(View v) {
+ if (mGls == null) {
+ mText.append("mGls is null\n");
+ return;
+ }
+ try {
+ String service = (String) mService.getSelectedItem();
+ mText.append("service: " + service + "\n");
+
+ String account = mGls.getAccount(mRequireGoogle);
+ mText.append("account: " + account + "\n");
+ GoogleLoginCredentialsResult result =
+ mGls.blockingGetCredentials(account, service, mDoNotify.isChecked());
+ mText.append("result account: " + result.getAccount() + "\n");
+ mText.append("result string: " + result.getCredentialsString() + "\n");
+ Intent intent = result.getCredentialsIntent();
+ mText.append("result intent: " + intent + "\n");
+
+ if (intent != null && mRunIntent.isChecked()) {
+ startActivityForResult(intent, 0);
+ }
+ } catch (RemoteException e) {
+ mText.append("caught exception " + e + "\n");
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mText.append("resultCode: " + resultCode + "\n");
+ if (data != null) {
+ mText.append("account: " +
+ data.getStringExtra(GoogleLoginServiceConstants.AUTH_ACCOUNT_KEY) + "\n");
+ mText.append("authtoken: " +
+ data.getStringExtra(GoogleLoginServiceConstants.AUTHTOKEN_KEY) + "\n");
+ } else {
+ mText.append("intent is null");
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Open a connection to the Google Login Service. Return the account.
+ mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mGls = IGoogleLoginService.Stub.asInterface(service);
+ }
+ public void onServiceDisconnected(ComponentName className) {
+ mGls = null;
+ }
+ };
+
+ bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
+ mConnection, Context.BIND_AUTO_CREATE);
+
+ setContentView(R.layout.gls_tester);
+
+ mText = (LogTextBox) findViewById(R.id.text);
+
+ mDoNotify = (CheckBox) findViewById(R.id.do_notification);
+ mRunIntent = (CheckBox) findViewById(R.id.run_intent);
+ mRunIntent.setChecked(true);
+
+ mService = (Spinner) findViewById(R.id.service_spinner);
+
+ Button b;
+ b = (Button) findViewById(R.id.require_google);
+ b.setOnClickListener(new Listener(GoogleLoginServiceConstants.REQUIRE_GOOGLE));
+ b = (Button) findViewById(R.id.prefer_hosted);
+ b.setOnClickListener(new Listener(GoogleLoginServiceConstants.PREFER_HOSTED));
+
+ b = (Button) findViewById(R.id.clear);
+ b.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mText.setText("");
+ } });
+
+ b = (Button) findViewById(R.id.wipe_passwords);
+ b.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mText.setText("wiping passwords:\n");
+ try {
+ String[] accounts = mGls.getAccounts();
+ LoginData ld = new LoginData();
+ for (String username: accounts) {
+ ld.mUsername = username;
+ mGls.updatePassword(ld);
+ mText.append(" " + username + "\n");
+ }
+ mText.append("done.\n");
+ } catch (RemoteException e) {
+ mText.append("caught exception " + e + "\n");
+ }
+ } });
+
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unbindService(mConnection);
+ }
+}
diff --git a/apps/Development/src/com/android/development/IRemoteService.aidl b/apps/Development/src/com/android/development/IRemoteService.aidl
new file mode 100644
index 000000000..0a60d3409
--- /dev/null
+++ b/apps/Development/src/com/android/development/IRemoteService.aidl
@@ -0,0 +1,24 @@
+/* //device/samples/SampleCode/src/com/android/development/IRemoteService.aidl
+**
+** Copyright 2007, 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.
+*/
+
+package com.android.development;
+
+interface IRemoteService
+{
+ int getPid();
+}
+
diff --git a/apps/Development/src/com/android/development/InstrumentationList.java b/apps/Development/src/com/android/development/InstrumentationList.java
new file mode 100644
index 000000000..88f09f867
--- /dev/null
+++ b/apps/Development/src/com/android/development/InstrumentationList.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.ActivityManagerNative;
+import android.app.IInstrumentationWatcher;
+import android.app.ListActivity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.List;
+
+class InstrumentationAdapter extends BaseAdapter
+{
+ private PackageManager mPM;
+
+ public InstrumentationAdapter(Context context, String targetPackage)
+ {
+ mContext = context;
+ mTargetPackage = targetPackage;
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mPM = context.getPackageManager();
+
+ mList = context.getPackageManager().queryInstrumentation(mTargetPackage, 0);
+ if (mList != null) {
+ Collections.sort(mList, new InstrumentationInfo.DisplayNameComparator(mPM));
+ }
+ }
+
+ public ComponentName instrumentationForPosition(int position)
+ {
+ if (mList == null) {
+ return null;
+ }
+ InstrumentationInfo ii = mList.get(position);
+ return new ComponentName(ii.packageName, ii.name);
+ }
+
+ 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);
+ } else {
+ view = convertView;
+ }
+ bindView(view, mList.get(position));
+ return view;
+ }
+
+ private final void bindView(View view, InstrumentationInfo info)
+ {
+ TextView text = (TextView)view.findViewById(android.R.id.text1);
+ CharSequence label = info.loadLabel(mPM);
+ text.setText(label != null ? label : info.name);
+ }
+
+ protected final Context mContext;
+ protected final String mTargetPackage;
+ protected final LayoutInflater mInflater;
+
+ protected List<InstrumentationInfo> mList;
+}
+
+public class InstrumentationList extends ListActivity
+{
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mProfilingMode = icicle != null && icicle.containsKey("profiling");
+ setListAdapter(new InstrumentationAdapter(this, null));
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ super.onCreateOptionsMenu(menu);
+ mProfilingItem = menu.add(0, 0, 0, "Profiling Mode")
+ .setOnMenuItemClickListener(mProfilingCallback);
+ mProfilingItem.setCheckable(true);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu)
+ {
+ super.onPrepareOptionsMenu(menu);
+ mProfilingItem.setChecked(mProfilingMode);
+ return true;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState)
+ {
+ if (mProfilingMode) {
+ outState.putBoolean("profiling", true);
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ ComponentName className = ((InstrumentationAdapter)getListAdapter()).
+ instrumentationForPosition(position);
+ if (className != null) {
+ String profilingFile = null;
+ if (mProfilingMode) {
+ profilingFile = "/tmp/trace/" + className + ".dmtrace";
+ }
+ try {
+ ActivityManagerNative.getDefault().
+ startInstrumentation(className, profilingFile, 0, null, mWatcher);
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ private MenuItem.OnMenuItemClickListener mProfilingCallback =
+ new MenuItem.OnMenuItemClickListener()
+ {
+ public boolean onMenuItemClick(MenuItem item) {
+ mProfilingMode = !mProfilingMode;
+ return true;
+ }
+ };
+
+ private IInstrumentationWatcher mWatcher = new IInstrumentationWatcher.Stub() {
+
+ public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+ if (results != null) {
+ for (String key : results.keySet()) {
+ Log.i("instrumentation",
+ "INSTRUMENTATION_STATUS_RESULT: " + key + "=" + results.get(key));
+ }
+ }
+ Log.i("instrumentation", "INSTRUMENTATION_STATUS_CODE: " + resultCode);
+ }
+ public void instrumentationFinished(ComponentName name,
+ int resultCode, Bundle results) {
+ if (results != null) {
+ for (String key : results.keySet()) {
+ Log.i("instrumentation",
+ "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
+ }
+ }
+ Log.i("instrumentation", "INSTRUMENTATION_CODE: " + resultCode);
+ }
+ };
+
+ private MenuItem mProfilingItem;
+ private boolean mProfilingMode;
+}
diff --git a/apps/Development/src/com/android/development/LogTextBox.java b/apps/Development/src/com/android/development/LogTextBox.java
new file mode 100644
index 000000000..2f99ab280
--- /dev/null
+++ b/apps/Development/src/com/android/development/LogTextBox.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.widget.TextView;
+import android.content.Context;
+import android.text.method.ScrollingMovementMethod;
+import android.text.method.MovementMethod;
+import android.text.method.KeyListener;
+import android.text.method.TransformationMethod;
+import android.text.Editable;
+import android.util.AttributeSet;
+
+
+/**
+ * This is a TextView that is Editable and by default scrollable,
+ * like EditText without a cursor.
+ *
+ * <p>
+ * <b>XML attributes</b>
+ * <p>
+ * See
+ * {@link android.R.styleable#TextView TextView Attributes},
+ * {@link android.R.styleable#View View Attributes}
+ */
+public class LogTextBox extends TextView {
+ public LogTextBox(Context context) {
+ this(context, null);
+ }
+
+ public LogTextBox(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.textViewStyle);
+ }
+
+ public LogTextBox(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected boolean getDefaultEditable() {
+ return true;
+ }
+
+ @Override
+ protected MovementMethod getDefaultMovementMethod() {
+ return ScrollingMovementMethod.getInstance();
+ }
+
+ @Override
+ public Editable getText() {
+ return (Editable) super.getText();
+ }
+
+ @Override
+ public void setText(CharSequence text, BufferType type) {
+ super.setText(text, BufferType.EDITABLE);
+ }
+}
diff --git a/apps/Development/src/com/android/development/LogViewer.java b/apps/Development/src/com/android/development/LogViewer.java
new file mode 100644
index 000000000..aadc0d423
--- /dev/null
+++ b/apps/Development/src/com/android/development/LogViewer.java
@@ -0,0 +1,169 @@
+/*
+** Copyright 2007, 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.
+*/
+
+package com.android.development;
+
+import static com.android.internal.util.CharSequences.forAsciiBytes;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.net.Socket;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Bundle;
+import android.util.Log;
+import android.graphics.Typeface;
+import android.view.Gravity;
+
+/**
+ * Views the device log.
+ */
+public class LogViewer extends Activity {
+
+ static final String TAG = LogViewer.class.getSimpleName();
+
+ FileOutputStream logger;
+
+ volatile boolean active = true;
+ Handler handler;
+ LogTextBox text;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.log_viewer);
+ this.handler = new Handler();
+
+ text = (LogTextBox) findViewById(R.id.text);
+
+ text.setTextSize(10);
+ text.setHorizontallyScrolling(true);
+ text.setTypeface(Typeface.MONOSPACE);
+ text.setGravity(Gravity.BOTTOM | Gravity.LEFT);
+
+ this.active = true;
+ try {
+ logger = new FileOutputStream("/tmp/logviewer.txt");
+ new Thread(new LogReader()).start();
+ } catch (IOException e) {
+ appendThrowable(e);
+ }
+ }
+
+ private void appendThrowable(Throwable t) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Error reading log: ");
+ builder.append(Log.getStackTraceString(t));
+ text.getText().append(builder);
+ }
+
+ private class LogReader implements Runnable {
+
+ final Socket socket;
+ final DataInputStream in;
+ StringBuilder builder = new StringBuilder();
+ long lastTime = System.currentTimeMillis();
+
+ private static final int HEADER_SIZE = 24;
+
+ public LogReader() throws IOException {
+ this.socket = new Socket("127.0.0.1", 5040);
+ this.in = new DataInputStream(this.socket.getInputStream());
+ // Write two newlines to indicate "no reader args"
+ this.socket.getOutputStream().write('\n');
+ this.socket.getOutputStream().write('\n');
+ }
+
+ public void run() {
+ while (active) {
+ try {
+ while (in.available() > 0) {
+ logger.write("Reading message.\n".getBytes());
+
+ int length = in.readInt();
+ byte[] bytes = new byte[length];
+ in.readFully(bytes);
+
+ int tagEnd = next0(bytes, HEADER_SIZE);
+ int fileEnd = next0(bytes, tagEnd + 1);
+ int messageEnd = next0(bytes, fileEnd + 1);
+
+ CharSequence tag
+ = forAsciiBytes(bytes, HEADER_SIZE, tagEnd);
+ CharSequence message
+ = forAsciiBytes(bytes, fileEnd + 1, messageEnd);
+
+ builder.append(tag)
+ .append(": ")
+ .append(message)
+ .append("\n");
+ }
+
+ logger.write("Updating UI.\n".getBytes());
+ handler.post(new AppendCharacters(builder));
+ builder = new StringBuilder();
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {}
+ } catch (final IOException e) {
+ handler.post(new AppendThrowable(e));
+ }
+ }
+ }
+ }
+
+ static int next0(byte[] bytes, int start) {
+ for (int current = start; current < bytes.length; current++) {
+ if (bytes[current] == 0)
+ return current;
+ }
+ return bytes.length;
+ }
+
+ private class AppendThrowable implements Runnable {
+
+ private final Throwable t;
+
+ public AppendThrowable(Throwable t) {
+ this.t = t;
+ }
+
+ public void run() {
+ appendThrowable(t);
+ }
+ }
+
+ private class AppendCharacters implements Runnable {
+
+ private final CharSequence message;
+
+ public AppendCharacters(CharSequence message) {
+ this.message = message;
+ }
+
+ public void run() {
+ text.getText().append(message);
+// try {
+// logger.write(builder.toString().getBytes());
+// } catch (IOException e) {
+// appendThrowable(e);
+// }
+ }
+ }
+}
diff --git a/apps/Development/src/com/android/development/MediaScannerActivity.java b/apps/Development/src/com/android/development/MediaScannerActivity.java
new file mode 100644
index 000000000..f78910ac4
--- /dev/null
+++ b/apps/Development/src/com/android/development/MediaScannerActivity.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.net.Uri;
+import android.os.Environment;
+import android.widget.TextView;
+
+public class MediaScannerActivity extends Activity
+{
+ public MediaScannerActivity() {
+ }
+
+ /** Called when the activity is first created or resumed. */
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ setContentView(R.layout.media_scanner_activity);
+
+ IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
+ intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
+ intentFilter.addDataScheme("file");
+ registerReceiver(mReceiver, intentFilter);
+
+ sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ + Environment.getExternalStorageDirectory())));
+
+ mTitle = (TextView) findViewById(R.id.title);
+ mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner.");
+ }
+
+ /** Called when the activity going into the background or being destroyed. */
+ @Override
+ public void onPause() {
+ super.onPause();
+ unregisterReceiver(mReceiver);
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
+ mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());
+ }
+ else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
+ mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());
+ }
+ }
+ };
+
+ private TextView mTitle;
+}
diff --git a/apps/Development/src/com/android/development/PackageBrowser.java b/apps/Development/src/com/android/development/PackageBrowser.java
new file mode 100644
index 000000000..e4c233f7d
--- /dev/null
+++ b/apps/Development/src/com/android/development/PackageBrowser.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.text.Collator;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class PackageBrowser extends ListActivity
+{
+ private PackageListAdapter mAdapter;
+ private List<PackageInfo> mPackageInfoList = null;
+ private Handler mHandler;
+
+ public class PackageListAdapter extends ArrayAdapter<PackageInfo>
+ {
+
+ public PackageListAdapter(Context context)
+ {
+ super(context, android.R.layout.simple_list_item_1);
+ mPackageInfoList = context.getPackageManager().getInstalledPackages(0);
+ if (mPackageInfoList != null) {
+ Collections.sort(mPackageInfoList, sDisplayNameComparator);
+ }
+ setSource(mPackageInfoList);
+ }
+
+ @Override
+ public void bindView(View view, PackageInfo info)
+ {
+ TextView text = (TextView)view.findViewById(android.R.id.text1);
+ text.setText(info.packageName);
+ }
+ }
+
+ /**
+ * Receives notifications when applications are added/removed.
+ */
+ private class ApplicationsIntentReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // todo: this is a bit brute force. We should probably get the action and package name
+ // from the intent and just add to or delete from the mPackageInfoList
+ setupAdapter();
+ }
+ }
+
+ private final static Comparator sDisplayNameComparator = new Comparator() {
+ public final int
+ compare(Object a, Object b)
+ {
+ CharSequence sa = ((PackageInfo) a).packageName;
+ CharSequence sb = ((PackageInfo) b).packageName;
+ return collator.compare(sa, sb);
+ }
+
+ private final Collator collator = Collator.getInstance();
+ };
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setupAdapter();
+ mHandler= new Handler();
+ registerIntentReceivers();
+ }
+
+ private void setupAdapter() {
+ mAdapter = new PackageListAdapter(this);
+ setListAdapter(mAdapter);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add(0, 0, 0, "Delete package").setOnMenuItemClickListener(
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ deletePackage();
+ return true;
+ }
+ });
+ return true;
+ }
+
+ private void deletePackage() {
+ final int curSelection = getSelectedItemPosition();
+ if (curSelection >= 0) {
+ // todo: verification dialog for package deletion
+ final PackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
+ if (packageInfo != null) {
+ getPackageManager().deletePackage(packageInfo.packageName,
+ new IPackageDeleteObserver.Stub() {
+ public void packageDeleted(boolean succeeded) throws RemoteException {
+ if (succeeded) {
+ mPackageInfoList.remove(curSelection);
+ mHandler.post(new Runnable() {
+ public void run() {
+ mAdapter.notifyDataSetChanged();
+ }
+ });
+
+ // todo: verification dialog for data directory
+ final String dataPath = packageInfo.applicationInfo.dataDir;
+ // todo: delete the data directory
+ } else {
+ mHandler.post(new Runnable() {
+ public void run() {
+ new AlertDialog.Builder(PackageBrowser.this)
+ .setTitle("Oops")
+ .setMessage("Could not delete package." +
+ " Maybe it is in /system/app rather than /data/app?")
+ .show();
+ }
+ });
+
+ }
+ }
+ },
+ 0);
+ }
+ }
+ }
+
+ private void registerIntentReceivers() {
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addDataScheme("package");
+ registerReceiver(new ApplicationsIntentReceiver(), filter);
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id)
+ {
+ PackageInfo info =
+ mAdapter.itemForPosition(position);
+ if (info != null) {
+ Intent intent = new Intent(
+ null, Uri.fromParts("package", 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
new file mode 100644
index 000000000..a6bbbb227
--- /dev/null
+++ b/apps/Development/src/com/android/development/PackageSummary.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ServiceInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+public class PackageSummary extends Activity {
+
+ String mPackageName;
+ private TextView mPackage;
+ private ImageView mIconImage;
+ private TextView mClass;
+ private TextView mLabel;
+ private View mDisabled;
+ private View mSystem;
+ private View mDebuggable;
+ private View mNoCode;
+ private View mPersistent;
+ private Button mRestart;
+ private TextView mTask;
+ private TextView mVersion;
+ private TextView mProcess;
+ private TextView mUid;
+ private TextView mSource;
+ private TextView mData;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.package_summary);
+
+ final PackageManager pm = getPackageManager();
+
+ mPackage = (TextView)findViewById(R.id.packageView);
+ mIconImage = (ImageView)findViewById(R.id.icon);
+ mClass = (TextView)findViewById(R.id.classView);
+ mLabel = (TextView)findViewById(R.id.label);
+ mDisabled = findViewById(R.id.disabled);
+ mSystem = findViewById(R.id.system);
+ mDebuggable = findViewById(R.id.debuggable);
+ mNoCode = findViewById(R.id.nocode);
+ mPersistent = findViewById(R.id.persistent);
+ mRestart = (Button)findViewById(R.id.restart);
+ mTask = (TextView)findViewById(R.id.task);
+ mVersion = (TextView)findViewById(R.id.version);
+ mUid = (TextView)findViewById(R.id.uid);
+ mProcess = (TextView)findViewById(R.id.process);
+ mSource = (TextView)findViewById(R.id.source);
+ mData = (TextView)findViewById(R.id.data);
+
+ mPackageName = getIntent().getData().getSchemeSpecificPart();
+ PackageInfo info = null;
+ try {
+ info = pm.getPackageInfo(mPackageName,
+ PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
+ | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS
+ | PackageManager.GET_INSTRUMENTATION);
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+
+ if (info != null) {
+ mPackage.setText(info.packageName);
+ CharSequence label = null;
+ String appClass = null;
+ if (info.applicationInfo != null) {
+ mIconImage.setImageDrawable(
+ pm.getApplicationIcon(info.applicationInfo));
+ label = info.applicationInfo.nonLocalizedLabel;
+ appClass = info.applicationInfo.className;
+ if (info.applicationInfo.enabled) {
+ mDisabled.setVisibility(View.GONE);
+ }
+ if ((info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
+ mSystem.setVisibility(View.GONE);
+ }
+ if ((info.applicationInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+ mDebuggable.setVisibility(View.GONE);
+ }
+ if ((info.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
+ mNoCode.setVisibility(View.GONE);
+ }
+ if ((info.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
+ mPersistent.setVisibility(View.GONE);
+ }
+ mUid.setText(Integer.toString(info.applicationInfo.uid));
+ mProcess.setText(info.applicationInfo.processName);
+ if (info.versionName != null) {
+ mVersion.setText(info.versionName + " (#" + info.versionCode + ")");
+ } else {
+ mVersion.setText("(#" + info.versionCode + ")");
+ }
+ mSource.setText(info.applicationInfo.sourceDir);
+ mData.setText(info.applicationInfo.dataDir);
+ if (info.applicationInfo.taskAffinity != null) {
+ mTask.setText("\"" + info.applicationInfo.taskAffinity + "\"");
+ } else {
+ mTask.setText("(No Task Affinity)");
+ }
+ }
+ if (appClass != null) {
+ if (appClass.startsWith(info.packageName + "."))
+ mClass.setText(appClass.substring(info.packageName.length()));
+ else
+ mClass.setText(appClass);
+ } else {
+ mClass.setText("(No Application Class)");
+ }
+ if (label != null) {
+ mLabel.setText("\"" + label + "\"");
+ } else {
+ mLabel.setText("(No Label)");
+ }
+
+ mRestart.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ try {
+ ActivityManagerNative.getDefault().restartPackage(mPackageName);
+ } catch (RemoteException e) {
+ }
+ }
+ });
+
+ final LayoutInflater inflate =
+ (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
+ LinearLayout activities = (LinearLayout)findViewById(R.id.activities);
+ LinearLayout receivers = (LinearLayout)findViewById(R.id.receivers);
+ LinearLayout services = (LinearLayout)findViewById(R.id.services);
+ LinearLayout providers = (LinearLayout)findViewById(R.id.providers);
+ LinearLayout instrumentation = (LinearLayout)findViewById(R.id.instrumentation);
+
+ if (info.activities != null) {
+ final int N = info.activities.length;
+ for (int i=0; i<N; i++) {
+ ActivityInfo ai = info.activities[i];
+ // If an activity is disabled then the ActivityInfo will be null
+ if (ai != null) {
+ Button view = (Button)inflate.inflate(
+ R.layout.package_item, null, false);
+ view.setOnClickListener(new ActivityOnClick(
+ new ComponentName(ai.applicationInfo.packageName,
+ ai.name)));
+ setItemText(view, info, ai.name);
+ activities.addView(view, lp);
+ }
+ }
+ } else {
+ activities.setVisibility(View.GONE);
+ }
+
+ if (info.receivers != null) {
+ final int N = info.receivers.length;
+ for (int i=0; i<N; i++) {
+ ActivityInfo ai = info.receivers[i];
+ Button view = (Button)inflate.inflate(
+ R.layout.package_item, null, false);
+ setItemText(view, info, ai.name);
+ receivers.addView(view, lp);
+ }
+ } else {
+ receivers.setVisibility(View.GONE);
+ }
+
+ if (info.services != null) {
+ final int N = info.services.length;
+ for (int i=0; i<N; i++) {
+ ServiceInfo si = info.services[i];
+ Button view = (Button)inflate.inflate(
+ R.layout.package_item, null, false);
+ setItemText(view, info, si.name);
+ services.addView(view, lp);
+ }
+ } else {
+ services.setVisibility(View.GONE);
+ }
+
+ if (info.providers != null) {
+ final int N = info.providers.length;
+ for (int i=0; i<N; i++) {
+ ProviderInfo pi = info.providers[i];
+ Button view = (Button)inflate.inflate(
+ R.layout.package_item, null, false);
+ setItemText(view, info, pi.name);
+ providers.addView(view, lp);
+ }
+ } else {
+ providers.setVisibility(View.GONE);
+ }
+
+ if (info.instrumentation != null) {
+ final int N = info.instrumentation.length;
+ for (int i=0; i<N; i++) {
+ InstrumentationInfo ii = info.instrumentation[i];
+ Button view = (Button)inflate.inflate(
+ R.layout.package_item, null, false);
+ setItemText(view, info, ii.name);
+ instrumentation.addView(view, lp);
+ }
+ } else {
+ instrumentation.setVisibility(View.GONE);
+ }
+
+ }
+
+ // Put focus here, so a button doesn't get focus and cause the
+ // scroll view to move to it.
+ mPackage.requestFocus();
+ }
+
+ private final static void setItemText(Button item, PackageInfo pi,
+ String className)
+ {
+ item.setText(className.substring(pi.packageName.length()+1));
+ }
+
+ private final class ActivityOnClick implements View.OnClickListener
+ {
+ private final ComponentName mClassName;
+ ActivityOnClick(ComponentName className) {
+ mClassName = className;
+ }
+
+ public void onClick(View v) {
+ Intent intent = new Intent(
+ null, Uri.fromParts("component",
+ mClassName.flattenToString(), null));
+ intent.setClass(PackageSummary.this, ShowActivity.class);
+ startActivity(intent);
+ }
+ }
+}
diff --git a/apps/Development/src/com/android/development/PointerLocation.java b/apps/Development/src/com/android/development/PointerLocation.java
new file mode 100644
index 000000000..64533069c
--- /dev/null
+++ b/apps/Development/src/com/android/development/PointerLocation.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Paint.FontMetricsInt;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.VelocityTracker;
+import android.view.View;
+
+import java.util.ArrayList;
+
+/**
+ * Demonstrates wrapping a layout in a ScrollView.
+ *
+ */
+public class PointerLocation extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(new MyView(this));
+ }
+
+ public class MyView extends View {
+ private final Paint mTextPaint;
+ private final Paint mTextBackgroundPaint;
+ private final Paint mTextLevelPaint;
+ private final Paint mPaint;
+ private final Paint mTargetPaint;
+ private final FontMetricsInt mTextMetrics = new FontMetricsInt();
+ private final ArrayList<Float> mXs = new ArrayList<Float>();
+ private final ArrayList<Float> mYs = new ArrayList<Float>();
+ private int mHeaderBottom;
+ private boolean mCurDown;
+ private int mCurX;
+ private int mCurY;
+ private float mCurPressure;
+ private float mCurSize;
+ private int mCurWidth;
+ private VelocityTracker mVelocity;
+
+ public MyView(Context c) {
+ super(c);
+ mTextPaint = new Paint();
+ mTextPaint.setAntiAlias(true);
+ mTextPaint.setTextSize(10);
+ mTextPaint.setARGB(255, 0, 0, 0);
+ mTextBackgroundPaint = new Paint();
+ mTextBackgroundPaint.setAntiAlias(false);
+ mTextBackgroundPaint.setARGB(128, 255, 255, 255);
+ mTextLevelPaint = new Paint();
+ mTextLevelPaint.setAntiAlias(false);
+ mTextLevelPaint.setARGB(192, 255, 0, 0);
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setARGB(255, 255, 255, 255);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(2);
+ mTargetPaint = new Paint();
+ mTargetPaint.setAntiAlias(false);
+ mTargetPaint.setARGB(192, 0, 0, 255);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(1);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mTextPaint.getFontMetricsInt(mTextMetrics);
+ mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;
+ Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
+ + " descent=" + mTextMetrics.descent
+ + " leading=" + mTextMetrics.leading
+ + " top=" + mTextMetrics.top
+ + " bottom=" + mTextMetrics.bottom);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int w = getWidth()/5;
+ int base = -mTextMetrics.ascent+1;
+ int bottom = mHeaderBottom;
+ canvas.drawRect(0, 0, w-1, bottom, mTextBackgroundPaint);
+ canvas.drawText("X: " + mCurX, 1, base, mTextPaint);
+ canvas.drawRect(w, 0, (w * 2) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawText("Y: " + mCurY, 1 + w, base, mTextPaint);
+ canvas.drawRect(w * 2, 0, (w * 3) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawRect(w * 2, 0, (w * 2) + (mCurPressure * w) - 1, bottom, mTextLevelPaint);
+ canvas.drawText("Pres: " + mCurPressure, 1 + w * 2, base, mTextPaint);
+ canvas.drawRect(w * 3, 0, (w * 4) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawRect(w * 3, 0, (w * 3) + (mCurSize * w) - 1, bottom, mTextLevelPaint);
+ canvas.drawText("Size: " + mCurSize, 1 + w * 3, base, mTextPaint);
+ canvas.drawRect(w * 4, 0, getWidth(), bottom, mTextBackgroundPaint);
+ int velocity = mVelocity == null ? 0 : (int) (mVelocity.getYVelocity() * 1000);
+ canvas.drawText("yVel: " + velocity, 1 + w * 4, base, mTextPaint);
+
+ final int N = mXs.size();
+ float lastX=0, lastY=0;
+ mPaint.setARGB(255, 0, 255, 255);
+ for (int i=0; i<N; i++) {
+ float x = mXs.get(i);
+ float y = mYs.get(i);
+ if (i > 0) {
+ canvas.drawLine(lastX, lastY, x, y, mTargetPaint);
+ canvas.drawPoint(lastX, lastY, mPaint);
+ }
+ lastX = x;
+ lastY = y;
+ }
+ if (mVelocity != null) {
+ mPaint.setARGB(255, 255, 0, 0);
+ float xVel = mVelocity.getXVelocity() * (1000/60);
+ float yVel = mVelocity.getYVelocity() * (1000/60);
+ canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
+ } else {
+ canvas.drawPoint(lastX, lastY, mPaint);
+ }
+
+ if (mCurDown) {
+ canvas.drawLine(0, (int)mCurY, getWidth(), (int)mCurY, mTargetPaint);
+ canvas.drawLine((int)mCurX, 0, (int)mCurX, getHeight(), mTargetPaint);
+ int pressureLevel = (int)(mCurPressure*255);
+ mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
+ canvas.drawPoint(mCurX, mCurY, mPaint);
+ canvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int action = event.getAction();
+ //mRect.set(0, 0, getWidth(), mHeaderBottom+1);
+ //invalidate(mRect);
+ //if (mCurDown) {
+ // mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+ // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+ //} else {
+ // mRect.setEmpty();
+ //}
+ if (action == MotionEvent.ACTION_DOWN) {
+ mXs.clear();
+ mYs.clear();
+ mVelocity = VelocityTracker.obtain();
+ }
+ mVelocity.addMovement(event);
+ mVelocity.computeCurrentVelocity(1);
+ final int N = event.getHistorySize();
+ for (int i=0; i<N; i++) {
+ mXs.add(event.getHistoricalX(i));
+ mYs.add(event.getHistoricalY(i));
+ }
+ mXs.add(event.getX());
+ mYs.add(event.getY());
+ mCurDown = action == MotionEvent.ACTION_DOWN
+ || action == MotionEvent.ACTION_MOVE;
+ mCurX = (int)event.getX();
+ mCurY = (int)event.getY();
+ mCurPressure = event.getPressure();
+ mCurSize = event.getSize();
+ mCurWidth = (int)(mCurSize*(getWidth()/3));
+ //if (mCurDown) {
+ // mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+ // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+ //}
+ //invalidate(mRect);
+ invalidate();
+ return true;
+ }
+
+ }
+}
diff --git a/apps/Development/src/com/android/development/PreferredPackages.java b/apps/Development/src/com/android/development/PreferredPackages.java
new file mode 100644
index 000000000..1c6f23c27
--- /dev/null
+++ b/apps/Development/src/com/android/development/PreferredPackages.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+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 PreferredPackages extends ListActivity {
+ private static final int ADD_APP_REQUEST = 1;
+
+ private PackageListAdapter mAdapter;
+ private Handler mHandler;
+
+ final static class Entry {
+ final PackageInfo info;
+ final CharSequence label;
+
+ Entry(PackageInfo _info, CharSequence _label) {
+ info = _info;
+ label = _label;
+ }
+ }
+ private final ArrayList<Entry> mPackageInfoList = new ArrayList<Entry>();
+
+ final class PackageListAdapter extends ArrayAdapter<Entry> {
+ public PackageListAdapter(Context context) {
+ super(context, android.R.layout.simple_list_item_1);
+ List<PackageInfo> pkgs =
+ context.getPackageManager().getPreferredPackages(0);
+ final int N = pkgs.size();
+ mPackageInfoList.clear();
+ for (int i=0; i<N; i++) {
+ PackageInfo pi = pkgs.get(i);
+ if (pi.applicationInfo == null) {
+ continue;
+ }
+ mPackageInfoList.add(new Entry(pi,
+ getPackageManager().getApplicationLabel(
+ pi.applicationInfo)));
+ }
+ Collections.sort(mPackageInfoList, sDisplayNameComparator);
+ setSource(mPackageInfoList);
+ }
+
+ public void bindView(View view, Entry info) {
+ TextView text = (TextView)view.findViewById(android.R.id.text1);
+ text.setText(info.label);
+ }
+ }
+
+ private final static Comparator<Entry> sDisplayNameComparator = new Comparator<Entry>() {
+ public final int
+ compare(Entry a, Entry b) {
+ return collator.compare(a.toString(), b.toString());
+ }
+
+ private final Collator collator = Collator.getInstance();
+ };
+
+ /**
+ * Receives notifications when applications are added/removed.
+ */
+ private final BroadcastReceiver mAppsReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ setupAdapter();
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setupAdapter();
+ mHandler = new Handler();
+ registerIntentReceivers();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterIntentReceivers();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add(0, 0, 0, "Add Package").setOnMenuItemClickListener(
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ addPackage();
+ return true;
+ }
+ });
+ menu.add(0, 0, 0, "Remove Package").setOnMenuItemClickListener(
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ removePackage();
+ return true;
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (requestCode == ADD_APP_REQUEST && resultCode == RESULT_OK) {
+ getPackageManager().addPackageToPreferred(intent.getAction());
+ setupAdapter();
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Entry info =
+ mAdapter.itemForPosition(position);
+ if (info != null) {
+ Intent intent = new Intent(
+ Intent.ACTION_VIEW,
+ Uri.fromParts("package", info.info.packageName, null));
+ intent.setClass(this, PackageSummary.class);
+ startActivity(intent);
+ }
+ }
+
+ private void setupAdapter() {
+ mAdapter = new PackageListAdapter(this);
+ setListAdapter(mAdapter);
+ }
+
+ private void removePackage() {
+ final int curSelection = this.getSelectedItemPosition();
+ if (curSelection >= 0) {
+ final Entry packageInfo = mAdapter.itemForPosition(curSelection);
+ if (packageInfo != null) {
+ getPackageManager().removePackageFromPreferred(
+ packageInfo.info.packageName);
+ }
+ setupAdapter();
+ }
+ }
+
+ private void addPackage() {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClass(this, AppPicker.class);
+ startActivityForResult(intent, ADD_APP_REQUEST);
+ }
+
+ private void registerIntentReceivers() {
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addDataScheme("package");
+ registerReceiver(mAppsReceiver, filter);
+ }
+
+ private void unregisterIntentReceivers() {
+ unregisterReceiver(mAppsReceiver);
+ }
+}
diff --git a/apps/Development/src/com/android/development/RadioIssueReport.java b/apps/Development/src/com/android/development/RadioIssueReport.java
new file mode 100644
index 000000000..e1d1ec880
--- /dev/null
+++ b/apps/Development/src/com/android/development/RadioIssueReport.java
@@ -0,0 +1,191 @@
+/*
+** Copyright 2006, 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.
+*/
+
+package com.android.development;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.pim.DateFormat;
+import android.provider.Checkin;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import android.telephony.ServiceState;
+import static com.android.internal.util.CharSequences.forAsciiBytes;
+import android.util.Log;
+import android.view.View.OnClickListener;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.google.android.collect.Maps;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Map;
+
+/**
+ * Report radio issues to the StatisticsService.
+ */
+public class RadioIssueReport extends Activity
+{
+ private static final String TAG = "RadioIssue";
+ private static final int HEADER_SIZE = 24;
+ private static final String RADIO_BUFFER_OPTIONS = "-b radio\n-d\n";
+
+ /** List of system properties to snapshot. */
+ private static String[] SYSTEM_PROPERTIES = {
+ "net.gsm.radio-reset",
+ "net.gsm.attempt-gprs",
+ "net.gsm.succeed-gprs",
+ "net.gsm.disconnect",
+ "net.ppp.sent",
+ "net.ppp.received",
+ "gsm.version.baseband",
+ "gsm.version.ril-impl",
+ };
+
+ private Button mSubmitButton;
+ private EditText mReportText;
+ private ServiceState mServiceState;
+ private Phone.State mPhoneState;
+ private int mSignalStrength;
+ private Phone.DataState mDataState;
+ private String mRadioLog;
+
+ /** Snapshot of interesting variables relevant to the radio. */
+ private Map<String, String> mRadioState;
+
+ @Override
+ public void
+ onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.radio_issue);
+
+ initSubmitButton();
+ initReportText();
+
+ mRadioState = snapState();
+ }
+
+ /**
+ * @return a snapshot of phone state variables to report.
+ */
+ private static Map<String, String> snapState() {
+ Map<String, String> state = Maps.newHashMap();
+
+ // Capture a bunch of system properties
+ for (String property: SYSTEM_PROPERTIES) {
+ String value = SystemProperties.get(property);
+ state.put(property, SystemProperties.get(property));
+ }
+
+ Phone phone = PhoneFactory.getDefaultPhone();
+ state.put("phone-data", phone.getDataConnectionState().toString());
+ state.put("phone-service", phone.getServiceState().toString());
+ state.put("phone-signal", String.valueOf(phone.getSignalStrengthASU()));
+ state.put("phone-state", phone.getState().toString());
+
+ try {
+ state.put("radio-log", getRadioLog());
+ } catch (IOException e) {
+ Log.e(TAG, "Error reading radio log", e);
+ }
+
+ return state;
+ }
+
+ private void initSubmitButton() {
+ mSubmitButton = (Button) findViewById(R.id.submit);
+ mSubmitButton.setOnClickListener(mSubmitButtonHandler);
+ }
+
+ private void initReportText() {
+ mReportText = (EditText) findViewById(R.id.report_text);
+ mReportText.requestFocus();
+ }
+
+ OnClickListener mSubmitButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ // Include the user-supplied report text.
+ mRadioState.put("user-report", mReportText.getText().toString());
+
+ // Dump the state variables directly into the report.
+ Checkin.logEvent(getContentResolver(),
+ Checkin.Events.Tag.RADIO_BUG_REPORT,
+ mRadioState.toString());
+
+ finish();
+ }
+ };
+
+ // Largely stolen from LogViewer.java
+ private static String getRadioLog() throws IOException {
+ Socket sock = new Socket("127.0.0.1", 5040);
+ DataInputStream in = new DataInputStream(sock.getInputStream());
+ StringBuilder log = new StringBuilder();
+
+ // Set options
+ sock.getOutputStream().write(RADIO_BUFFER_OPTIONS.getBytes());
+ sock.getOutputStream().write('\n');
+ sock.getOutputStream().write('\n');
+
+ // Read in the log
+ try {
+ Calendar cal = new GregorianCalendar();
+
+ while (true) {
+ int length = in.readInt();
+ long when = (long)in.readInt();
+ byte[] bytes = new byte[length-4];
+ in.readFully(bytes);
+
+ int tagEnd = next0(bytes, HEADER_SIZE-4);
+ int fileEnd = next0(bytes, tagEnd + 1);
+ int messageEnd = next0(bytes, fileEnd + 1);
+
+ CharSequence tag
+ = forAsciiBytes(bytes, HEADER_SIZE-4, tagEnd);
+ CharSequence message
+ = forAsciiBytes(bytes, fileEnd + 1, messageEnd);
+
+ cal.setTimeInMillis(when*1000);
+ log.append(DateFormat.format("MM-dd kk:mm:ss ", cal));
+ log.append(tag)
+ .append(": ")
+ .append(message)
+ .append("\n");
+ }
+ } catch (EOFException e) {
+ Log.d(TAG, "reached end of stream");
+ }
+
+ return log.toString();
+ }
+
+ private static int next0(byte[] bytes, int start) {
+ for (int current = start; current < bytes.length; current++) {
+ if (bytes[current] == 0)
+ return current;
+ }
+ return bytes.length;
+ }
+}
diff --git a/apps/Development/src/com/android/development/ShowActivity.java b/apps/Development/src/com/android/development/ShowActivity.java
new file mode 100644
index 000000000..1fc281640
--- /dev/null
+++ b/apps/Development/src/com/android/development/ShowActivity.java
@@ -0,0 +1,122 @@
+/* //device/apps/Settings/src/com/android/settings/Keyguard.java
+**
+** Copyright 2006, 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.
+*/
+
+package com.android.development;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+
+public class ShowActivity extends Activity {
+
+ private ActivityInfo mActivityInfo;
+
+ private TextView mPackage;
+ private ImageView mIconImage;
+ private TextView mClass;
+ private TextView mLabel;
+ private TextView mLaunch;
+ private TextView mProcess;
+ private TextView mTaskAffinity;
+ private TextView mPermission;
+ private TextView mMultiprocess;
+ private TextView mClearOnBackground;
+ private TextView mStateNotNeeded;
+
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.show_activity);
+
+ mPackage = (TextView)findViewById(R.id.packageView);
+ mIconImage = (ImageView)findViewById(R.id.icon);
+ mClass = (TextView)findViewById(R.id.classView);
+ mLabel = (TextView)findViewById(R.id.label);
+ mLaunch = (TextView)findViewById(R.id.launch);
+ mProcess = (TextView)findViewById(R.id.process);
+ mTaskAffinity = (TextView)findViewById(R.id.taskAffinity);
+ mPermission = (TextView)findViewById(R.id.permission);
+ mMultiprocess = (TextView)findViewById(R.id.multiprocess);
+ mClearOnBackground = (TextView)findViewById(R.id.clearOnBackground);
+ mStateNotNeeded = (TextView)findViewById(R.id.stateNotNeeded);
+
+ final PackageManager pm = getPackageManager();
+ try {
+ mActivityInfo = pm.getActivityInfo(ComponentName.unflattenFromString(
+ getIntent().getData().getSchemeSpecificPart()), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ if (mActivityInfo != null) {
+ mPackage.setText(mActivityInfo.applicationInfo.packageName);
+ mIconImage.setImageDrawable(mActivityInfo.loadIcon(pm));
+ if (mActivityInfo.name.startsWith(
+ mActivityInfo.applicationInfo.packageName + ".")) {
+ mClass.setText(mActivityInfo.name.substring(
+ mActivityInfo.applicationInfo.packageName.length()));
+ } else {
+ mClass.setText(mActivityInfo.name);
+ }
+ CharSequence label = mActivityInfo.loadLabel(pm);
+ mLabel.setText("\"" + (label != null ? label : "") + "\"");
+ switch (mActivityInfo.launchMode) {
+ case ActivityInfo.LAUNCH_MULTIPLE:
+ mLaunch.setText(getText(R.string.launch_multiple));
+ break;
+ case ActivityInfo.LAUNCH_SINGLE_TOP:
+ mLaunch.setText(getText(R.string.launch_singleTop));
+ break;
+ case ActivityInfo.LAUNCH_SINGLE_TASK:
+ mLaunch.setText(getText(R.string.launch_singleTask));
+ break;
+ case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
+ mLaunch.setText(getText(R.string.launch_singleInstance));
+ break;
+ default:
+ mLaunch.setText(getText(R.string.launch_unknown));
+ }
+ mProcess.setText(mActivityInfo.processName);
+ mTaskAffinity.setText(mActivityInfo.taskAffinity != null
+ ? mActivityInfo.taskAffinity : getText(R.string.none));
+ mPermission.setText(mActivityInfo.permission != null
+ ? mActivityInfo.permission : getText(R.string.none));
+ mMultiprocess.setText(
+ (mActivityInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
+ ? getText(R.string.yes) : getText(R.string.no));
+ mClearOnBackground.setText(
+ (mActivityInfo.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0
+ ? getText(R.string.yes) : getText(R.string.no));
+ mStateNotNeeded.setText(
+ (mActivityInfo.flags&ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0
+ ? getText(R.string.yes) : getText(R.string.no));
+ }
+ }
+
+ public void onResume() {
+ super.onResume();
+ }
+}
diff --git a/apps/Development/src/com/android/development/StacktraceViewer.java b/apps/Development/src/com/android/development/StacktraceViewer.java
new file mode 100644
index 000000000..96b052129
--- /dev/null
+++ b/apps/Development/src/com/android/development/StacktraceViewer.java
@@ -0,0 +1,50 @@
+/*
+** Copyright 2007, 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.
+*/
+
+package com.android.development;
+
+
+import android.app.Activity;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.text.method.ScrollingMovementMethod;
+import android.os.Bundle;
+import android.server.data.CrashData;
+import android.server.data.ThrowableData;
+import android.server.data.StackTraceElementData;
+import android.graphics.Typeface;
+
+/**
+ * Views a single stack trace.
+ */
+public class StacktraceViewer extends Activity {
+
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.log_viewer);
+
+ TextView text = (TextView) findViewById(R.id.text);
+ text.setTextSize(10);
+ text.setHorizontallyScrolling(true);
+ text.setTypeface(Typeface.MONOSPACE);
+ text.setMovementMethod(ScrollingMovementMethod.getInstance());
+
+ String stacktrace = getIntent().getExtras().getString(
+ CrashData.class.getName());
+
+ text.setText(stacktrace);
+ }
+}
diff --git a/apps/Development/src/com/android/development/UnderdevelopedSettings.java b/apps/Development/src/com/android/development/UnderdevelopedSettings.java
new file mode 100644
index 000000000..9cf1b9085
--- /dev/null
+++ b/apps/Development/src/com/android/development/UnderdevelopedSettings.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.development;
+
+import android.app.LauncherActivity;
+import android.content.Intent;
+
+public class UnderdevelopedSettings extends LauncherActivity {
+
+ @Override
+ protected Intent getTargetIntent() {
+ Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
+ targetIntent.addCategory(Intent.CATEGORY_DEVELOPMENT_PREFERENCE);
+ return targetIntent;
+ }
+
+}