Initial Contribution
This commit is contained in:
167
apps/Development/src/com/android/development/AppPicker.java
Normal file
167
apps/Development/src/com/android/development/AppPicker.java
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
31
apps/Development/src/com/android/development/ColumnData.java
Normal file
31
apps/Development/src/com/android/development/ColumnData.java
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
134
apps/Development/src/com/android/development/DataList.java
Normal file
134
apps/Development/src/com/android/development/DataList.java
Normal file
@@ -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;
|
||||
}
|
||||
157
apps/Development/src/com/android/development/Details.java
Normal file
157
apps/Development/src/com/android/development/Details.java
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
310
apps/Development/src/com/android/development/EnterURL.java
Normal file
310
apps/Development/src/com/android/development/EnterURL.java
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
167
apps/Development/src/com/android/development/GLSTester.java
Normal file
167
apps/Development/src/com/android/development/GLSTester.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
72
apps/Development/src/com/android/development/LogTextBox.java
Normal file
72
apps/Development/src/com/android/development/LogTextBox.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
169
apps/Development/src/com/android/development/LogViewer.java
Normal file
169
apps/Development/src/com/android/development/LogViewer.java
Normal file
@@ -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);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
177
apps/Development/src/com/android/development/PackageBrowser.java
Normal file
177
apps/Development/src/com/android/development/PackageBrowser.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
269
apps/Development/src/com/android/development/PackageSummary.java
Normal file
269
apps/Development/src/com/android/development/PackageSummary.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
122
apps/Development/src/com/android/development/ShowActivity.java
Normal file
122
apps/Development/src/com/android/development/ShowActivity.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user