Merge korg/donut into korg/master

Conflicts:

	tools/eclipse/plugins/README.txt
	tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
This commit is contained in:
Jean-Baptiste Queru
2009-07-25 17:25:52 -07:00
2132 changed files with 100935 additions and 9901 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
*~
*.bak
*.pyc
Thumbs.db

View File

@@ -36,7 +36,6 @@
android:icon="@drawable/ic_launcher_devtools">
<uses-library android:name="android.test.runner" />
<uses-library android:name="com.google.android.maps" />
<activity android:name="Development" android:label="Dev Tools"
android:icon="@drawable/ic_launcher_devtools">
@@ -132,5 +131,11 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="PermissionDetails" android:label="Permission Info">
<intent-filter>
<action android:name="com.android.development.VIEW_PERMISSION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -77,6 +77,14 @@
<TextView android:id="@+id/attr_five_way_nav"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/attr_gles_version_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/gles_version_label"
android:textStyle="bold" />
<TextView android:id="@+id/attr_gles_version"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>

View File

@@ -143,13 +143,6 @@
android:layout_alignParentLeft="true"
android:text="@string/development_settings_show_xmpp_text" />
<CheckBox android:id="@+id/show_maps_compass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/show_xmpp"
android:layout_alignParentLeft="true"
android:text="@string/development_settings_show_maps_compass_text" />
</RelativeLayout>
</ScrollView>

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="4dip" >
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/perm_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/perm_name_text"
android:textStyle="bold" />
<TextView android:id="@+id/perm_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/perm_desc_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/perm_desc_text"
android:textStyle="bold" />
<TextView android:id="@+id/perm_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/perm_group_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/perm_group_text"
android:textStyle="bold" />
<TextView android:id="@+id/perm_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/perm_protection_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/perm_protection_text"
android:textStyle="bold" />
<TextView android:id="@+id/perm_protection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/perm_source_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/perm_source_text"
android:textStyle="bold" />
<TextView android:id="@+id/perm_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/source_uid_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/source_uid_text"
android:textStyle="bold" />
<TextView android:id="@+id/source_uid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:id="@+id/shared_pkgs_panel"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4dip" >
<TextView android:id="@+id/shared_pkgs_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shared_pkgs_text"
android:textStyle="bold" />
<TextView android:id="@+id/shared_pkgs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView android:id="@+id/perm_list_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="3dip"
android:text="@string/perm_list_header_text"
android:textStyle="bold" />
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingRight="6dip"
android:paddingLeft="6dip"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:gravity="center_vertical" >
<TextView android:id="@+id/pkg_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginBottom="2dip" />
</LinearLayout>

View File

@@ -1,49 +0,0 @@
<!--
**
** 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/submit"
android:textSize="14sp"
android:layout_marginTop="8dip"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="@string/radio_issue_submit_text"
/>
<TextView android:id="@+id/instructions"
android:textSize="14sp"
android:layout_marginTop="10dip"
android:layout_marginLeft="4dip"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="@string/radio_issue_instructions_text"
/>
</LinearLayout>
<EditText android:id="@+id/report_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="14sp"
/>
</LinearLayout>

View File

@@ -84,7 +84,6 @@
<string name="development_settings_show_xmpp_text">Show GTalk service connection status</string>
<string name="development_settings_debug_app_label_text">Debug App:</string>
<string name="development_settings_show_sleep_text">Show sleep state on LED</string>
<string name="development_settings_show_maps_compass_text">Show compass in Maps</string>
<string name="development_settings_keep_screen_on_text">Keep screen on while plugged in</string>
<string name="monkey_screen_initialActivity_text"></string>
@@ -92,9 +91,6 @@
<string name="monkey_screen_start_text">Start</string>
<string name="monkey_screen_initial_activity_label">Initial Activity: </string>
<string name="radio_issue_submit_text">Submit report</string>
<string name="radio_issue_instructions_text">Enter a description of the issue.</string>
<string name="show_activity_clear_on_background_label">Clear on Background</string>
<string name="show_activity_task_affinity_label">Task Affinity</string>
<string name="show_activity_process_label">Process</string>
@@ -123,4 +119,18 @@
<string name="hard_keyboard_label">hardKeyboard:</string>
<string name="navigation_label">navigation:</string>
<string name="five_way_nav_label">five way nav:</string>
<string name="gles_version_label">GLES Version:</string>
<!-- Permission details related string attribtues -->
<string name="perm_name_text">Name : </string>
<string name="dialog_title_error">Error</string>
<string name="invalid_perm_name">Invalid Permission Name</string>
<string name="ok">Ok</string>
<string name="perm_desc_text">Desc : </string>
<string name="perm_group_text">Group : </string>
<string name="perm_protection_text">Protection Level : </string>
<string name="perm_source_text">Source package : </string>
<string name="perm_list_header_text">Apps using permission </string>
<string name="source_uid_text">Source uid : </string>
<string name="shared_pkgs_text">Packages accessing via shared uid : </string>
</resources>

View File

@@ -54,6 +54,7 @@ public class AppHwPref extends Activity {
private static final int TOUCHSCREEN = BASE + 1;
private static final int KEYBOARD_TYPE = BASE + 2;
private static final int NAVIGATION = BASE + 3;
private static final int GLES_VERSION = BASE + 4;
@Override
protected void onCreate(Bundle icicle) {
@@ -79,31 +80,32 @@ public class AppHwPref extends Activity {
setContentView(R.layout.application_hw_pref);
if(appHwPref != null) {
displayTextView(R.id.attr_package, pInfo.applicationInfo.loadLabel(mPm));
displayTextView(R.id.attr_touchscreen, appHwPref, TOUCHSCREEN);
displayTextView(R.id.attr_input_method, appHwPref, KEYBOARD_TYPE);
displayTextView(R.id.attr_navigation, appHwPref, NAVIGATION);
displayFlag(R.id.attr_hard_keyboard, ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD, appHwPref);
displayFlag(R.id.attr_five_way_nav, ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV, appHwPref);
displayTextView(R.id.attr_package, pInfo.applicationInfo.loadLabel(mPm));
displayTextView(R.id.attr_touchscreen, appHwPref, TOUCHSCREEN);
displayTextView(R.id.attr_input_method, appHwPref, KEYBOARD_TYPE);
displayTextView(R.id.attr_navigation, appHwPref, NAVIGATION);
displayFlag(R.id.attr_hard_keyboard, ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD, appHwPref);
displayFlag(R.id.attr_five_way_nav, ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV, appHwPref);
displayTextView(R.id.attr_gles_version, appHwPref, GLES_VERSION);
}
}
void displayFlag(int viewId, int flagMask, ConfigurationInfo[] appHwPref) {
if(appHwPref == null) {
return;
}
boolean flag = false;
for (int i = 0; i < appHwPref.length; i++) {
ConfigurationInfo pref = appHwPref[i];
if((pref.reqInputFeatures & flagMask) != 0) {
flag = true;
break;
}
if(appHwPref == null) {
return;
}
boolean flag = false;
for (int i = 0; i < appHwPref.length; i++) {
ConfigurationInfo pref = appHwPref[i];
if((pref.reqInputFeatures & flagMask) != 0) {
flag = true;
break;
}
}
if(flag) {
displayTextView(viewId, "true");
} else {
displayTextView(viewId, "false");
displayTextView(viewId, "false");
}
}
@@ -140,6 +142,9 @@ public class AppHwPref extends Activity {
case NAVIGATION:
str = getNavigationStr(config[i]);
break;
case GLES_VERSION:
str = config[i].getGlEsVersion();
break;
}
if(str != null) {
list.add(str);

View File

@@ -57,7 +57,6 @@ public class DevelopmentSettings extends Activity {
private CheckBox mShowUpdatesCB;
private CheckBox mShowBackgroundCB;
private CheckBox mShowSleepCB;
private CheckBox mShowMapsCompassCB;
private CheckBox mShowXmppCB;
private Spinner mMaxProcsSpinner;
private Spinner mWindowAnimationScaleSpinner;
@@ -69,7 +68,6 @@ public class DevelopmentSettings extends Activity {
private boolean mAlwaysFinish;
private int mProcessLimit;
private boolean mShowSleep;
private boolean mShowMapsCompass;
private boolean mShowXmpp;
private AnimationScaleSelectedListener mWindowAnimationScale
= new AnimationScaleSelectedListener(0);
@@ -106,8 +104,6 @@ public class DevelopmentSettings extends Activity {
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);
mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
mShowXmppCB.setOnClickListener(mShowXmppClicked);
mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
@@ -172,7 +168,6 @@ public class DevelopmentSettings extends Activity {
updateSharedOptions();
updateFlingerOptions();
updateSleepOptions();
updateMapsCompassOptions();
updateXmppOptions();
try {
@@ -293,31 +288,6 @@ public class DevelopmentSettings extends Activity {
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 writeXmppOptions() {
Settings.System.setShowGTalkServiceStatus(getContentResolver(), mShowXmpp);
}
@@ -410,16 +380,6 @@ public class DevelopmentSettings extends Activity {
}
};
private View.OnClickListener mShowMapsCompassClicked =
new View.OnClickListener() {
public void onClick(View v) {
mShowMapsCompass = ((CheckBox)v).isChecked();
writeMapsCompassOptions();
updateMapsCompassOptions();
}
};
private View.OnClickListener mShowXmppClicked = new View.OnClickListener() {
public void onClick(View v) {
mShowXmpp = ((CheckBox)v).isChecked();

View File

@@ -0,0 +1,305 @@
/*
**
** 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 com.android.development.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
/**
* This activity displays permission details including
* the list of apps using a permission.
*/
public class PermissionDetails extends Activity implements OnCancelListener, OnItemClickListener {
private static final String TAG = "PermissionDetails";
PackageManager mPm;
// layout inflater object used to inflate views
private LayoutInflater mInflater;
private AppListAdapter mAdapter;
// Dialog related
private static final int DLG_BASE = 0;
private static final int DLG_ERROR = DLG_BASE + 1;
private static final String PROTECTION_NORMAL="Normal";
private static final String PROTECTION_DANGEROUS="Dangerous";
private static final String PROTECTION_SIGNATURE="Signature";
private static final String PROTECTION_SIGNATURE_OR_SYSTEM="SignatureOrSystem";
private static final String KEY_APPS_USING_PERM="AppsUsingPerm";
private static final int HANDLER_MSG_BASE = 0;
private static final int HANDLER_MSG_GET_APPS = HANDLER_MSG_BASE + 1;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_MSG_GET_APPS:
ArrayList<PackageInfo> appList = msg.getData().getParcelableArrayList(KEY_APPS_USING_PERM);
createAppList(appList);
break;
}
}
};
// View Holder used when displaying views
static class AppViewHolder {
TextView pkgName;
}
class AppListAdapter extends BaseAdapter {
private List<PackageInfo> mList;
AppListAdapter(List<PackageInfo> list) {
mList = list;
}
public int getCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public long getItemId(int position) {
return position;
}
public PackageInfo getPkg(int position) {
return mList.get(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
AppViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.pkg_list_item, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new AppViewHolder();
holder.pkgName = (TextView) convertView.findViewById(R.id.pkg_name);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (AppViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder
PackageInfo pInfo = mList.get(position);
holder.pkgName.setText(pInfo.packageName);
return convertView;
}
}
private void createAppList(List<PackageInfo> list) {
Log.i(TAG, "list.size=" + list.size());
for (PackageInfo pkg : list) {
Log.i(TAG, "Adding pkg : " + pkg.packageName);
}
ListView listView = (ListView)findViewById(android.R.id.list);
mAdapter = new AppListAdapter(list);
ListView lv= (ListView) findViewById(android.R.id.list);
lv.setOnItemClickListener(this);
lv.setSaveEnabled(true);
lv.setItemsCanFocus(true);
listView.setAdapter(mAdapter);
}
private void getAppsUsingPerm(PermissionInfo pInfo) {
List<PackageInfo> list = mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
HashSet<PackageInfo> set = new HashSet<PackageInfo>();
for (PackageInfo pkg : list) {
if (pkg.requestedPermissions == null) {
continue;
}
for (String perm : pkg.requestedPermissions) {
if (perm.equalsIgnoreCase(pInfo.name)) {
Log.i(TAG, "Pkg:" + pkg.packageName+" uses permission");
set.add(pkg);
break;
}
}
}
ArrayList<PackageInfo> retList = new ArrayList<PackageInfo>();
for (PackageInfo pkg : set) {
retList.add(pkg);
}
Message msg = mHandler.obtainMessage(HANDLER_MSG_GET_APPS);
Bundle data = msg.getData();
data.putParcelableArrayList(KEY_APPS_USING_PERM, retList);
mHandler.dispatchMessage(msg);
}
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.permission_details);
Intent intent = getIntent();
String permName = intent.getStringExtra("permission");
if(permName == null) {
showDialogInner(DLG_ERROR);
}
mPm = getPackageManager();
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
PermissionInfo pInfo = null;
try {
pInfo = mPm.getPermissionInfo(permName,
PackageManager.GET_PERMISSIONS);
} catch (NameNotFoundException e) {
showDialogInner(DLG_ERROR);
}
setTextView(R.id.perm_name, pInfo.name);
setTextView(R.id.perm_desc, pInfo.descriptionRes);
setTextView(R.id.perm_group, pInfo.group);
setProtectionLevel(R.id.perm_protection, pInfo.protectionLevel);
setTextView(R.id.perm_source, pInfo.packageName);
ApplicationInfo appInfo = null;
try {
appInfo = mPm.getApplicationInfo(pInfo.packageName, 0);
String uidStr = mPm.getNameForUid(appInfo.uid);
setTextView(R.id.source_uid, uidStr);
} catch (NameNotFoundException e) {
}
boolean sharedVisibility = false;
// List of apps acquiring access via shared user id
LinearLayout sharedPanel = (LinearLayout) findViewById(R.id.shared_pkgs_panel);
if (appInfo != null) {
String[] sharedList = mPm.getPackagesForUid(appInfo.uid);
if ((sharedList != null) && (sharedList.length > 1)) {
sharedVisibility = true;
TextView label = (TextView) sharedPanel.findViewById(R.id.shared_pkgs_label);
TextView sharedView = (TextView) sharedPanel.findViewById(R.id.shared_pkgs);
label.setVisibility(View.VISIBLE);
StringBuilder buff = new StringBuilder();
buff.append(sharedList[0]);
for (int i = 1; i < sharedList.length; i++) {
buff.append(", ");
buff.append(sharedList[i]);
}
sharedView.setText(buff.toString());
}
}
if (sharedVisibility) {
sharedPanel.setVisibility(View.VISIBLE);
} else {
sharedPanel.setVisibility(View.GONE);
}
getAppsUsingPerm(pInfo);
}
private void setProtectionLevel(int viewId, int protectionLevel) {
String levelStr = "";
if (protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
levelStr = PROTECTION_NORMAL;
} else if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
levelStr = PROTECTION_DANGEROUS;
} else if (protectionLevel == PermissionInfo.PROTECTION_SIGNATURE) {
levelStr = PROTECTION_SIGNATURE;
} else if (protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
levelStr = PROTECTION_SIGNATURE_OR_SYSTEM;
} else {
levelStr = "Invalid";
}
setTextView(viewId, levelStr);
}
private void setTextView(int viewId, int textId) {
TextView view = (TextView)findViewById(viewId);
view.setText(textId);
}
private void setTextView(int viewId, String text) {
TextView view = (TextView)findViewById(viewId);
view.setText(text);
}
@Override
public Dialog onCreateDialog(int id) {
if (id == DLG_ERROR) {
return new AlertDialog.Builder(this)
.setTitle(R.string.dialog_title_error)
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}})
.setMessage(R.string.invalid_perm_name)
.setOnCancelListener(this)
.create();
}
return null;
}
private void showDialogInner(int id) {
// TODO better fix for this? Remove dialog so that it gets created again
removeDialog(id);
showDialog(id);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
}
public void onCancel(DialogInterface dialog) {
finish();
}
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Launch app details activity
}
}

View File

@@ -1,191 +0,0 @@
/*
** 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.provider.Checkin;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import android.telephony.ServiceState;
import android.text.format.DateFormat;
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;
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="appTitle">"Fallback"</string>
<string name="title">"Acción no admitida"</string>
<string name="error">"Esa acción no se admite actualmente."</string>
</resources>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="appTitle">"Fallback"</string>
<string name="title">"Ação não suportada"</string>
<string name="error">"Esta ação não é suportada no momento."</string>
</resources>

View File

@@ -38,9 +38,7 @@ public class DefaultActivity extends Activity {
// Enable the GPS.
// Not needed since this SDK will contain the Settings app.
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, LocationManager.GPS_PROVIDER);
locationManager.updateProviders();
// enable install from non market
Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);

View File

@@ -38,7 +38,6 @@ import android.os.Bundle;
import android.os.Exec;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -54,7 +53,6 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -105,8 +103,6 @@ public class Term extends Activity {
*/
private FileDescriptor mTermFd;
private boolean mShellRunning;
/**
* Used to send data to the remote process.
*/
@@ -185,7 +181,9 @@ public class Term extends Activity {
mKeyListener = new TermKeyListener();
mEmulatorView.setFocusable(true);
mEmulatorView.setFocusableInTouchMode(true);
mEmulatorView.requestFocus();
mEmulatorView.register(mKeyListener);
updatePrefs();
}
@@ -194,14 +192,11 @@ public class Term extends Activity {
int[] processId = new int[1];
createSubprocess(processId);
mShellRunning = true;
final int procId = processId[0];
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
mShellRunning = false;
}
};
@@ -1357,7 +1352,7 @@ class TerminalEmulator {
printableB = ' ';
}
Log.w(Term.LOG_TAG, "'" + Character.toString(printableB)
+ "' (" + Integer.toString((int) b) + ")");
+ "' (" + Integer.toString(b) + ")");
}
process(b);
mProcessedCharCount++;
@@ -2084,7 +2079,7 @@ class TerminalEmulator {
buf.append(" char: '");
buf.append((char) b);
buf.append("' (");
buf.append((int) b);
buf.append(b);
buf.append(")");
boolean firstArg = true;
for (int i = 0; i <= mArgIndex; i++) {
@@ -2604,6 +2599,7 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
private GestureDetector mGestureDetector;
private float mScrollRemainder;
private TermKeyListener mKeyListener;
/**
* Our message handler class. Implements a periodic callback.
@@ -2615,6 +2611,7 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
*
* @param msg The callback message.
*/
@Override
public void handleMessage(Message msg) {
if (msg.what == UPDATE) {
update();
@@ -2627,6 +2624,10 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
commonConstructor();
}
public void register(TermKeyListener listener) {
mKeyListener = listener;
}
public void setColors(int foreground, int background) {
mForeground = foreground;
mBackground = background;
@@ -2651,52 +2652,64 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return new BaseInputConnection(this, false) {
@Override
public boolean beginBatchEdit() {
return true;
}
@Override
public boolean clearMetaKeyStates(int states) {
return true;
}
@Override
public boolean commitCompletion(CompletionInfo text) {
return true;
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
sendText(text);
return true;
}
@Override
public boolean deleteSurroundingText(int leftLength, int rightLength) {
return true;
}
@Override
public boolean endBatchEdit() {
return true;
}
@Override
public boolean finishComposingText() {
return true;
}
@Override
public int getCursorCapsMode(int reqModes) {
return 0;
}
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request,
int flags) {
return null;
}
@Override
public CharSequence getTextAfterCursor(int n, int flags) {
return null;
}
@Override
public CharSequence getTextBeforeCursor(int n, int flags) {
return null;
}
@Override
public boolean performEditorAction(int actionCode) {
if(actionCode == EditorInfo.IME_ACTION_UNSPECIFIED) {
// The "return" key has been pressed on the IME.
@@ -2706,14 +2719,17 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
return false;
}
@Override
public boolean performContextMenuAction(int id) {
return true;
}
@Override
public boolean performPrivateCommand(String action, Bundle data) {
return true;
}
@Override
public boolean sendKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch(event.getKeyCode()) {
@@ -2725,17 +2741,19 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
return true;
}
@Override
public boolean setComposingText(CharSequence text, int newCursorPosition) {
return true;
}
@Override
public boolean setSelection(int start, int end) {
return true;
}
private void sendChar(int c) {
try {
mTermOut.write(c);
mapAndSend(c);
} catch (IOException ex) {
}
@@ -2745,11 +2763,16 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
try {
for(int i = 0; i < n; i++) {
char c = text.charAt(i);
mTermOut.write(c);
mapAndSend(c);
}
} catch (IOException e) {
}
}
private void mapAndSend(int c) throws IOException {
mTermOut.write(
mKeyListener.mapControlChar(c));
}
};
}
@@ -3161,6 +3184,35 @@ class TermKeyListener {
}
}
public int mapControlChar(int ch) {
int result = ch;
if (mControlKey.isActive()) {
// Search is the control key.
if (result >= 'a' && result <= 'z') {
result = (char) (result - 'a' + '\001');
} else if (result == ' ') {
result = 0;
} else if ((result == '[') || (result == '1')) {
result = 27;
} else if ((result == '\\') || (result == '.')) {
result = 28;
} else if ((result == ']') || (result == '0')) {
result = 29;
} else if ((result == '^') || (result == '6')) {
result = 30; // control-^
} else if ((result == '_') || (result == '5')) {
result = 31;
}
}
if (result > -1) {
mAltKey.adjustAfterKeypress();
mCapKey.adjustAfterKeypress();
mControlKey.adjustAfterKeypress();
}
return result;
}
/**
* Handle a keyDown event.
*
@@ -3201,30 +3253,7 @@ class TermKeyListener {
}
}
if (mControlKey.isActive()) {
// Search is the control key.
if (result >= 'a' && result <= 'z') {
result = (char) (result - 'a' + '\001');
} else if (result == ' ') {
result = 0;
} else if ((result == '[') || (result == '1')) {
result = 27;
} else if ((result == '\\') || (result == '.')) {
result = 28;
} else if ((result == ']') || (result == '0')) {
result = 29;
} else if ((result == '^') || (result == '6')) {
result = 30; // control-^
} else if ((result == '_') || (result == '5')) {
result = 31;
}
}
if (result > -1) {
mAltKey.adjustAfterKeypress();
mCapKey.adjustAfterKeypress();
mControlKey.adjustAfterKeypress();
}
result = mapControlChar(result);
return result;
}

View File

@@ -2,9 +2,16 @@
#
# swt
lib/libswt-carbon-3236.jnilib tools/lib/libswt-carbon-3236.jnilib
lib/libswt-pi-carbon-3236.jnilib tools/lib/libswt-pi-carbon-3236.jnilib
framework/swt.jar tools/lib/swt.jar
framework/org.eclipse.core.commands_3.2.0.I20060605-1400.jar tools/lib/org.eclipse.core.commands_3.2.0.I20060605-1400.jar
framework/org.eclipse.equinox.common_3.2.0.v20060603.jar tools/lib/org.eclipse.equinox.common_3.2.0.v20060603.jar
framework/org.eclipse.jface_3.2.0.I20060605-1400.jar tools/lib/org.eclipse.jface_3.2.0.I20060605-1400.jar
prebuilt/darwin-x86/swt/swt.jar tools/lib/x86/swt.jar
# JetCreator (only available on mac/windows)
external/sonivox/jet_tools/JetCreator tools/Jet/JetCreator
prebuilt/darwin-x86/jetcreator/libEASLIb.dylib tools/Jet/JetCreator/libEASLIb.dylib
external/sonivox/jet_tools/JetCreator_content tools/Jet/demo_content
external/sonivox/jet_tools/logic_templates tools/Jet/logic_templates
external/sonivox/docs/JET_Authoring_Guidelines.html docs/JetCreator/JET_Authoring_Guidelines.html
external/sonivox/docs/JET_Authoring_Guidelines_files docs/JetCreator/JET_Authoring_Guidelines_files
external/sonivox/docs/JET_Creator_User_Manual.html docs/JetCreator/JET_Creator_User_Manual.html
external/sonivox/docs/JET_Creator_User_Manual_files docs/JetCreator/JET_Creator_User_Manual_files

View File

@@ -2,11 +2,5 @@
#
# swt
lib/libswt-atk-gtk-3236.so tools/lib/libswt-atk-gtk-3236.so
lib/libswt-gtk-3236.so tools/lib/libswt-gtk-3236.so
lib/libswt-pi-gtk-3236.so tools/lib/libswt-pi-gtk-3236.so
lib/libswt-cairo-gtk-3236.so tools/lib/libswt-cairo-gtk-3236.so
framework/swt.jar tools/lib/swt.jar
framework/org.eclipse.core.commands_3.2.0.I20060605-1400.jar tools/lib/org.eclipse.core.commands_3.2.0.I20060605-1400.jar
framework/org.eclipse.equinox.common_3.2.0.v20060603.jar tools/lib/org.eclipse.equinox.common_3.2.0.v20060603.jar
framework/org.eclipse.jface_3.2.0.I20060605-1400.jar tools/lib/org.eclipse.jface_3.2.0.I20060605-1400.jar
prebuilt/linux-x86/swt/swt.jar tools/lib/x86/swt.jar
prebuilt/linux-x86_64/swt/swt.jar tools/lib/x86_64/swt.jar

View File

@@ -27,12 +27,15 @@ bin/dmtracedump tools/dmtracedump
bin/hprof-conv tools/hprof-conv
bin/mksdcard tools/mksdcard
# other tools
development/tools/scripts/add-accounts-sdk tools/add-accounts.py
# the uper-jar file that apps link against
out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
# eclipse files for SWT
framework/org.eclipse.core.commands_3.4.0.I20080509-2000.jar tools/lib/org.eclipse.core.commands_3.4.0.I20080509-2000.jar
framework/org.eclipse.equinox.common_3.4.0.v20080421-2006.jar tools/lib/org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
framework/org.eclipse.jface_3.4.2.M20090107-0800.jar tools/lib/org.eclipse.jface_3.4.2.M20090107-0800.jar
sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
development/tools/scripts/plugin.prop tools/lib/plugin.prop
@@ -93,6 +96,9 @@ framework/jcommon-1.0.12.jar tools/lib/jcommon-1.0.12.jar
framework/jfreechart-1.0.9.jar tools/lib/jfreechart-1.0.9.jar
framework/jfreechart-1.0.9-swt.jar tools/lib/jfreechart-1.0.9-swt.jar
# archquery to test VM architecture
framework/archquery.jar tools/lib/archquery.jar
# ddms
bin/ddms tools/ddms
framework/ddms.jar tools/lib/ddms.jar
@@ -121,6 +127,7 @@ framework/anttasks.jar tools/lib/anttasks.jar
# sdkmanager
bin/android tools/android
framework/sdklib.jar tools/lib/sdklib.jar
framework/sdkuilib.jar tools/lib/sdkuilib.jar
framework/sdkmanager.jar tools/lib/sdkmanager.jar
# emulator

View File

@@ -19,8 +19,12 @@ set -e # Fail this script as soon as a command fails -- fail early, fail fast
# will make some rm/mv commands to fail.
FORCE="1"
PROG_NAME="$0"
SDK_ZIP="$1"
DIST_DIR="$2"
TEMP_DIR="$3"
[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
function die() {
echo "Error:" $*
@@ -28,9 +32,23 @@ function die() {
exit 1
}
function usage() {
echo "Usage: ${PROG_NAME} linux_or_mac_sdk.zip output_dir [temp_dir]"
echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used."
status
exit 2
}
function status() {
echo "Current values:"
echo "- Input SDK: ${SDK_ZIP:-missing}"
echo "- Output dir: ${DIST_DIR:-missing}"
echo "- Temp dir: ${TEMP_DIR:-missing}"
}
function check() {
[ -f "$SDK_ZIP" ] || die "Pass the path of an existing Linux/Darwin SDK .zip as first parameter"
[ -d "$DIST_DIR" ] || die "Pass the output directory as second parameter"
[ -f "$SDK_ZIP" ] || usage
[ -d "$DIST_DIR" ] || usage
# Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
# provided zip filename.
@@ -82,21 +100,22 @@ function package() {
echo
echo "Packaging..."
DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
DEST="$DIST_DIR/$DEST_NAME"
DEST_NAME_ZIP="${DEST_NAME}.zip"
TEMP_SDK_DIR="$TEMP_DIR/$DEST_NAME"
# Unzip current linux/mac SDK and rename using the windows name
if [[ -n "$FORCE" || ! -d "$DEST" ]]; then
[ -e "$DEST" ] && rm -rfv "$DEST" # cleanup dest first if exists
if [[ -n "$FORCE" || ! -d "$TEMP_SDK_DIR" ]]; then
[ -e "$TEMP_SDK_DIR" ] && rm -rfv "$TEMP_SDK_DIR" # cleanup dest first if exists
UNZIPPED=`basename "$SDK_ZIP"`
UNZIPPED="$DIST_DIR/${UNZIPPED/.zip/}"
UNZIPPED="$TEMP_DIR/${UNZIPPED/.zip/}"
[ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED" # cleanup unzip dir (if exists)
unzip "$SDK_ZIP" -d "$DIST_DIR"
mv -v "$UNZIPPED" "$DEST"
unzip "$SDK_ZIP" -d "$TEMP_DIR"
mv -v "$UNZIPPED" "$TEMP_SDK_DIR"
fi
# Assert that the package contains only one platform
PLATFORMS="$DEST/platforms"
PLATFORMS="$TEMP_SDK_DIR/platforms"
THE_PLATFORM=`echo $PLATFORMS/*`
PLATFORM_TOOLS=$THE_PLATFORM/tools
echo "Platform found: " $THE_PLATFORM
@@ -107,53 +126,86 @@ function package() {
# USB Driver for ADB
mkdir -pv $DEST/usb_driver/x86
cp -rv development/host/windows/prebuilt/usb/driver/* $DEST/usb_driver/x86/
mkdir -pv $DEST/usb_driver/amd64
cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $DEST/usb_driver/amd64/
mkdir -pv $TEMP_SDK_DIR/usb_driver/x86
cp -rv development/host/windows/prebuilt/usb/driver/* $TEMP_SDK_DIR/usb_driver/x86/
mkdir -pv $TEMP_SDK_DIR/usb_driver/x86_64
cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $TEMP_SDK_DIR/usb_driver/x86_64/
# Remove obsolete stuff from tools & platform
TOOLS="$DEST/tools"
LIB="$DEST/tools/lib"
rm -v "$TOOLS"/{adb,emulator,traceview,draw9patch,hierarchyviewer,apkbuilder,ddms,dmtracedump,hprof-conv,mksdcard,sqlite3,android}
rm -v --force "$LIB"/*.so "$LIB"/*.jnilib
TOOLS="$TEMP_SDK_DIR/tools"
LIB="$TEMP_SDK_DIR/tools/lib"
rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator}
rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview}
rm -v "$LIB"/*/swt.jar
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
# Copy all the new stuff in tools
# Note: some tools are first copied here and then moved in platforms/<name>/tools/
cp -v out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"
cp -v prebuilt/windows/swt/*.{jar,dll} "$LIB"
cp -v out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"/
mkdir -pv "$LIB"/x86
cp -v prebuilt/windows/swt/swt.jar "$LIB"/x86/
mkdir -pv "$LIB"/x86_64
cp -v prebuilt/windows-x86_64/swt/swt.jar "$LIB"/x86_64/
# If you want the emulator NOTICE in the tools dir, uncomment the following line:
# cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
# We currently need libz from MinGW for aapt
cp -v /cygdrive/c/cygwin/bin/mgwz.dll "$TOOLS"
cp -v /cygdrive/c/cygwin/bin/mgwz.dll "$TOOLS"/
# Update a bunch of bat files
cp -v development/tools/apkbuilder/etc/apkbuilder.bat "$TOOLS"
cp -v development/tools/ddms/app/etc/ddms.bat "$TOOLS"
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"
cp -v development/tools/draw9patch/etc/draw9patch.bat "$TOOLS"
cp -v development/tools/sdkmanager/app/etc/android.bat "$TOOLS"
cp -v development/tools/apkbuilder/etc/apkbuilder.bat "$TOOLS"/
cp -v development/tools/ddms/app/etc/ddms.bat "$TOOLS"/
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"/
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"/
cp -v development/tools/draw9patch/etc/draw9patch.bat "$TOOLS"/
cp -v development/tools/sdkmanager/app/etc/android.bat "$TOOLS"/
# Put the JetCreator tools, content and docs (not available in the linux SDK)
JET="$TOOLS/Jet"
JETCREATOR="$JET/JetCreator"
JETDEMOCONTENT="$JET/demo_content"
JETLOGICTEMPLATES="$JET/logic_templates"
JETDOC="$TEMP_SDK_DIR/docs/JetCreator"
# need to rm these folders since a Mac SDK will have them and it might create a conflict
rm -rfv "$JET"
rm -rfv "$JETDOC"
# now create fresh folders for JetCreator
mkdir -v "$JET"
mkdir -v "$JETDOC"
cp -rv external/sonivox/jet_tools/JetCreator "$JETCREATOR"/
cp -rv external/sonivox/jet_tools/JetCreator_content "$JETDEMOCONTENT"/
cp -rv external/sonivox/jet_tools/logic_templates "$JETLOGICTEMPLATES"/
chmod -vR u+w "$JETCREATOR" # fixes an issue where Cygwin might copy the above as u+rx only
cp -v prebuilt/windows/jetcreator/EASDLL.dll "$JETCREATOR"/
cp -v external/sonivox/docs/JET_Authoring_Guidelines.html "$JETDOC"/
cp -rv external/sonivox/docs/JET_Authoring_Guidelines_files "$JETDOC"/
cp -v external/sonivox/docs/JET_Creator_User_Manual.html "$JETDOC"/
cp -rv external/sonivox/docs/JET_Creator_User_Manual_files "$JETDOC"/
# Copy or move platform specific tools to the default platform.
cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"
cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"/
# Note: mgwz.dll must be in same folder than aapt.exe
mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe,mgwz.dll} "$PLATFORM_TOOLS"
mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe,mgwz.dll} "$PLATFORM_TOOLS"/
# Fix EOL chars to make window users happy - fix all files at the top level only
# as well as all batch files including those in platforms/<name>/tools/
find "$DIST_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
find "$DIST_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
find "$TEMP_SDK_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
find "$TEMP_SDK_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
# Done.. Zip it
pushd "$DIST_DIR" > /dev/null
# Done.. Zip it. Clean the temp folder ONLY if the zip worked (to ease debugging)
pushd "$TEMP_DIR" > /dev/null
[ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
popd > /dev/null
# Now move the final zip from the temp dest to the final dist dir
mv -v "$TEMP_DIR/$DEST_NAME_ZIP" "$DIST_DIR/$DEST_NAME_ZIP"
echo "Done"
echo
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
@@ -165,6 +217,7 @@ function package() {
}
check
status
build
package

View File

@@ -130,6 +130,7 @@ public class Monkey {
float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];
MonkeyEventSource mEventSource;
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
/**
* Monitor operations happening in the system.
@@ -362,7 +363,7 @@ public class Monkey {
if (mScriptFileName != null) {
// script mode, ignore other options
mEventSource = new MonkeySourceScript(mScriptFileName);
mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
mEventSource.setVerbose(mVerbose);
} else {
// random source by default
@@ -401,7 +402,9 @@ public class Monkey {
signalPersistentProcesses();
}
mNetworkMonitor.start();
int crashedAtCycle = runMonkeyCycles();
mNetworkMonitor.stop();
synchronized (this) {
if (mRequestAnrTraces) {
@@ -423,6 +426,7 @@ public class Monkey {
try {
mAm.setActivityWatcher(null);
mNetworkMonitor.unregister(mAm);
} catch (RemoteException e) {
// just in case this was latent (after mCount cycles), make sure
// we report it
@@ -443,6 +447,9 @@ public class Monkey {
System.out.println(mDroppedFlipEvents);
}
// report network stats
mNetworkMonitor.dump();
if (crashedAtCycle < mCount - 1) {
System.err.println("** System appears to have crashed at event "
+ crashedAtCycle + " of " + mCount + " using seed " + mSeed);
@@ -602,6 +609,7 @@ public class Monkey {
try {
mAm.setActivityWatcher(new ActivityWatcher());
mNetworkMonitor.register(mAm);
} catch (RemoteException e) {
System.err.println("** Failed talking with activity manager!");
return false;

View File

@@ -50,6 +50,14 @@ public abstract class MonkeyEvent {
return eventType;
}
/**
* @return true if it is safe to throttle after this event, and false otherwise.
*/
public boolean isThrottlable() {
return true;
}
/**
* a method for injecting event
* @param iwm wires to current window manager

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2008 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.commands.monkey;
import java.util.LinkedList;
/**
* class for keeping a monkey event queue
*/
@SuppressWarnings("serial")
public class MonkeyEventQueue extends LinkedList<MonkeyEvent> {
private long mThrottle;
public MonkeyEventQueue(long throttle) {
super();
mThrottle = throttle;
}
@Override
public void addLast(MonkeyEvent e) {
super.add(e);
if (e.isThrottlable()) {
super.add(new MonkeyThrottleEvent(mThrottle));
}
}
}

View File

@@ -91,6 +91,11 @@ public class MonkeyKeyEvent extends MonkeyEvent {
mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode);
}
@Override
public boolean isThrottlable() {
return (getAction() == KeyEvent.ACTION_UP);
}
@Override
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
if (verbose > 1) {

View File

@@ -20,6 +20,7 @@ import android.app.IActivityManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -123,6 +124,11 @@ public class MonkeyMotionEvent extends MonkeyEvent {
mXPrecision, mYPrecision, mDeviceId, mEdgeFlags);
}
@Override
public boolean isThrottlable() {
return (getAction() == KeyEvent.ACTION_UP);
}
@Override
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {

View File

@@ -0,0 +1,105 @@
/**
** 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.commands.monkey;
import android.app.IActivityManager;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
/**
* Class for monitoring network connectivity during monkey runs.
*/
public class MonkeyNetworkMonitor extends IIntentReceiver.Stub {
private static final boolean LDEBUG = false;
private final IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
private long mCollectionStartTime; // time we started collecting data
private long mEventTime; // time of last event (connect, disconnect, etc.)
private int mLastNetworkType = -1; // unknown
private long mWifiElapsedTime = 0; // accumulated time spent on wifi since start()
private long mMobileElapsedTime = 0; // accumulated time spent on mobile since start()
private long mElapsedTime = 0; // amount of time spent between start() and stop()
public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
boolean ordered) throws RemoteException {
NetworkInfo ni = (NetworkInfo) intent.getParcelableExtra(
ConnectivityManager.EXTRA_NETWORK_INFO);
if (LDEBUG) System.out.println("Network state changed: "
+ "type=" + ni.getType() + ", state=" + ni.getState());
updateNetworkStats();
if (NetworkInfo.State.CONNECTED == ni.getState()) {
if (LDEBUG) System.out.println("Network connected");
mLastNetworkType = ni.getType();
} else if (NetworkInfo.State.DISCONNECTED == ni.getState()) {
if (LDEBUG) System.out.println("Network not connected");
mLastNetworkType = -1; // unknown since we're disconnected
}
mEventTime = SystemClock.elapsedRealtime();
}
private void updateNetworkStats() {
long timeNow = SystemClock.elapsedRealtime();
long delta = timeNow - mEventTime;
switch (mLastNetworkType) {
case ConnectivityManager.TYPE_MOBILE:
if (LDEBUG) System.out.println("Adding to mobile: " + delta);
mMobileElapsedTime += delta;
break;
case ConnectivityManager.TYPE_WIFI:
if (LDEBUG) System.out.println("Adding to wifi: " + delta);
mWifiElapsedTime += delta;
break;
default:
if (LDEBUG) System.out.println("Unaccounted for: " + delta);
break;
}
mElapsedTime = timeNow - mCollectionStartTime;
}
public void start() {
mWifiElapsedTime = 0;
mMobileElapsedTime = 0;
mElapsedTime = 0;
mEventTime = mCollectionStartTime = SystemClock.elapsedRealtime();
}
public void register(IActivityManager am) throws RemoteException {
if (LDEBUG) System.out.println("registering Receiver");
am.registerReceiver(null, this, filter, null);
}
public void unregister(IActivityManager am) throws RemoteException {
if (LDEBUG) System.out.println("unregistering Receiver");
am.unregisterReceiver(this);
}
public void stop() {
updateNetworkStats();
}
public void dump() {
System.out.println("## Network stats: elapsed time=" + mElapsedTime + "ms ("
+ mMobileElapsedTime + "ms mobile, "
+ mWifiElapsedTime + "ms wifi, "
+ (mElapsedTime - mMobileElapsedTime - mWifiElapsedTime) + "ms not connected)");
}
}

View File

@@ -31,7 +31,7 @@ import java.util.Random;
/**
* monkey event queue
*/
public class MonkeySourceRandom implements MonkeyEventSource{
public class MonkeySourceRandom implements MonkeyEventSource {
/** Key events that move around the UI. */
private static final int[] NAV_KEYS = {
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
@@ -168,7 +168,7 @@ public class MonkeySourceRandom implements MonkeyEventSource{
private float[] mFactors = new float[FACTORZ_COUNT];
private ArrayList<ComponentName> mMainApps;
private int mEventCount = 0; //total number of events generated so far
private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
private MonkeyEventQueue mQ;
private Random mRandom;
private int mVerbose = 0;
private long mThrottle = 0;
@@ -203,7 +203,7 @@ public class MonkeySourceRandom implements MonkeyEventSource{
mRandom = new SecureRandom();
mRandom.setSeed((seed == 0) ? -1 : seed);
mMainApps = MainApps;
mThrottle = throttle;
mQ = new MonkeyEventQueue(throttle);
}
/**
@@ -336,7 +336,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
downAt, MotionEvent.ACTION_UP, x, y, 0);
e.setIntermediateNote(false);
mQ.addLast(e);
addThrottle();
}
/**
@@ -387,7 +386,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
e.setIntermediateNote(false);
mQ.addLast(e);
}
addThrottle();
}
/**
@@ -420,13 +418,11 @@ public class MonkeySourceRandom implements MonkeyEventSource{
MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
mRandom.nextInt(mMainApps.size())));
mQ.addLast(e);
addThrottle();
return;
} else if (cls < mFactors[FACTOR_FLIP]) {
MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
mKeyboardOpen = !mKeyboardOpen;
mQ.addLast(e);
addThrottle();
return;
} else {
lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
@@ -437,8 +433,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
mQ.addLast(e);
addThrottle();
}
public boolean validate() {
@@ -472,8 +466,4 @@ public class MonkeySourceRandom implements MonkeyEventSource{
mQ.removeFirst();
return e;
}
private void addThrottle() {
mQ.addLast(new MonkeyThrottleEvent(MonkeyEvent.EVENT_TYPE_THROTTLE, mThrottle));
}
}

View File

@@ -35,18 +35,19 @@ import java.util.StringTokenizer;
* type= raw events
* count= 10
* speed= 1.0
* start data >>
* captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
* 0.06666667,0,0.0,0.0,65539,0)
* captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
* captureDispatchFlip(true)
* ...
*/
public class MonkeySourceScript implements MonkeyEventSource{
public class MonkeySourceScript implements MonkeyEventSource {
private int mEventCountInScript = 0; //total number of events in the file
private int mVerbose = 0;
private double mSpeed = 1.0;
private String mScriptFileName;
private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
private MonkeyEventQueue mQ;
private static final String HEADER_TYPE = "type=";
private static final String HEADER_COUNT = "count=";
@@ -80,12 +81,14 @@ public class MonkeySourceScript implements MonkeyEventSource{
// a line at the end of the header
private static final String STARTING_DATA_LINE = "start data >>";
private boolean mFileOpened = false;
FileInputStream mFStream;
DataInputStream mInputStream;
BufferedReader mBufferReader;
public MonkeySourceScript(String filename) {
public MonkeySourceScript(String filename, long throttle) {
mScriptFileName = filename;
mQ = new MonkeyEventQueue(throttle);
}
/**

View File

@@ -16,11 +16,10 @@
package com.android.commands.monkey;
import java.util.List;
import android.app.IActivityManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.view.IWindowManager;
import android.view.MotionEvent;
/**
@@ -29,8 +28,8 @@ import android.view.MotionEvent;
public class MonkeyThrottleEvent extends MonkeyEvent {
private long mThrottle;
public MonkeyThrottleEvent(int type, long throttle) {
super(type);
public MonkeyThrottleEvent(long throttle) {
super(MonkeyEvent.EVENT_TYPE_THROTTLE);
mThrottle = throttle;
}

View File

@@ -0,0 +1,13 @@
; Copyright (C) 2009 The Android Open Source Project
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.

View File

@@ -0,0 +1,15 @@
#!/bin/bash
#
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2009 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

View File

@@ -0,0 +1,15 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@@ -0,0 +1,15 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@@ -0,0 +1,13 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@@ -0,0 +1,13 @@
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,15 @@
#!/bin/sh
#
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

View File

@@ -0,0 +1,180 @@
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Subject: How to get the android source code using Cygwin and Git
Date: 2009/04/27
Updated: 2009/05/21
Table of content:
1- Goals and Requirements
2- Getting the code, the simple way
3- SSH issues
4- Advanced Tricks
-------------------------
1- Goals and Requirements
-------------------------
This document explains how to checkout the Android source from the git
repositories under Windows.
As stated in development/docs/howto_build_SDK.txt, one can't build the whole
Android source code under Windows. You can only build a the SDK tools for
Windows.
There are a number of caveats in checking out the code from Git under Windows.
This document tries to explain them.
First you will need to meet the following requirements:
- You must have Cygwin installed.
See http://www.cygwin.com/
- You must install Cyginw using the "Unix / Binary" mode.
If you don't do that, git will fail to properly compute some SHA1 keys.
- You need the "git" and "curl" packages to checkout the code.
If you plan to contribute, you might want to get "gitk" also.
Note: if you want to build the SDK, check the howto_build_SDK.txt file
for a list of extra required packages.
-----------------------------------
2- Getting the code, the simple way
-----------------------------------
Out of the box, "repo" and "git" will work just fine under Cygwin:
$ repo init -u git://android.git.kernel.org/platform/manifest.git
$ repo sync
And you're done. You can build as explained in howto_build_SDK.txt and ignore
the rest of this document.
-------------
3- SSH issues
-------------
If you maintain your own private repository using an SSH server, you might get
some "mux/ssh" errors. In this case try this:
$ repo init -u ssh://my.private.ssh.repo/platform/manifest.git
$ export GIT_SSH=ssh
$ repo sync
------------------
4- Advanced Tricks
------------------
There is one remaining issue with the default repo/git options:
If you plan on contributing, you will notice that even after a fresh "repo
sync" some projects are marked as having modified files. This happens on the
"bionic" and the "external/iptables" project. The issue is that they have files
which have the same name yet differ only by their case-sensitivity. Since the
Windows filesystem is not case-sensitive, this confuses Git.
Solution: we can simply ignore these projects as they are not needed to build
the Windows SDK.
To do this you just need to create a file .repo/local_manifest.xml that
provides a list of projects to ignore:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remove-project name="platform/external/iptables" />
</manifest>
The other thing we can do is tell git not to track the files that cause
problems:
cd bionic
git update-index --assume-unchanged \
libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
libc/kernel/common/linux/netfilter/xt_MARK.h \
libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
cd external/tcpdump;
git update-index --assume-unchanged \
tests/print-X.new \
tests/print-XX.new
Here's a script that takes care of all these details. It performs the repo
init, creates the appropriate local_manifest.xml, does a repo sync as
needed and tell git to ignore the offending files:
------------
#!/bin/bash
set -e # fail on errors
URL=ssh://android-git.corp.google.com:29418/platform/manifest.git
BRANCH=donut
if [ "$1" == "-b" ]; then shift; BRANCH=$1; shift; fi
# repo init if there's no .repo directory
if [[ ! -d .repo ]]; then
repo init -u $URL -b $BRANCH
fi
# create a local_manifest to exclude projects that cause problems under Windows
# due to the case-insenstivines of the file system.
L=.repo/local_manifest.xml
if [[ ! -f $L ]]; then
cat > $L <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remove-project name="platform/external/iptables" />
</manifest>
EOF
fi
# sync using the native ssh client if necessary
[[ $URL != ${URL/ssh/} ]] && export GIT_SSH=ssh
repo sync $@
# These files cause trouble too, we need to ignore them
(cd bionic;
git update-index --assume-unchanged \
libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
libc/kernel/common/linux/netfilter/xt_MARK.h \
libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
)
(cd external/tcpdump;
git update-index --assume-unchanged \
tests/print-X.new \
tests/print-XX.new
)
------------
Simply extract this to a "my_sync.sh" file and try the following:
$ mkdir android_src
$ cd android_src
$ chmod +x mysync.sh
$ ./mysync.sh
-end-

View File

@@ -849,6 +849,10 @@ fdhandler_close( FDHandler* f )
static void
fdhandler_shutdown( FDHandler* f )
{
/* prevent later fdhandler_close() to
* call the receiver's close.
*/
f->receiver->close = NULL;
if (f->out_first != NULL && !f->closing)
{
@@ -856,9 +860,6 @@ fdhandler_shutdown( FDHandler* f )
f->closing = 1;
fdhandler_remove(f);
fdhandler_prepend(f, &f->list->closing);
/* notify the receiver that we're closing */
receiver_close(f->receiver);
return;
}

View File

@@ -96,6 +96,14 @@ LOCAL_CFLAGS += $(common_cflags)
LOCAL_MODULE := stack_dump
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := check_stack.cpp trace_reader.cpp decoder.cpp armdis.cpp \
thumbdis.cpp opcode.cpp read_elf.cpp parse_options.cpp
LOCAL_C_INCLUDES += $(common_includes)
LOCAL_CFLAGS += $(common_cflags)
LOCAL_MODULE := check_stack
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := hist_trace.cpp trace_reader.cpp decoder.cpp
LOCAL_C_INCLUDES += $(common_includes)
@@ -139,3 +147,11 @@ LOCAL_C_INCLUDES += $(common_includes)
LOCAL_CFLAGS += $(common_cflags)
LOCAL_MODULE := profile_pid
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_regions.cpp trace_reader.cpp decoder.cpp \
read_elf.cpp parse_options.cpp
LOCAL_C_INCLUDES += $(common_includes)
LOCAL_CFLAGS += $(common_cflags)
LOCAL_MODULE := dump_regions
include $(BUILD_HOST_EXECUTABLE)

View File

@@ -5,7 +5,7 @@
#include "armdis.h"
#include "opcode.h"
static char *cond_names[] = {
static const char *cond_names[] = {
"eq",
"ne",
"cs",
@@ -32,7 +32,7 @@ static const char *shift_names[] = {
"ROR"
};
static char* cond_to_str(int cond) {
static const char* cond_to_str(int cond) {
return cond_names[cond];
}
@@ -180,7 +180,7 @@ char *Arm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr)
sprintf(rd_str, "r%d, ", rd);
}
char *sbit_str = "";
const char *sbit_str = "";
if (bit_s && !(flags & kNoSbit))
sbit_str = "s";
@@ -282,15 +282,15 @@ char *Arm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr)
const char *opname = opcode_names[opcode];
char *bang = "";
const char *bang = "";
if (write_back)
bang = "!";
char *carret = "";
const char *carret = "";
if (bit_s)
carret = "^";
char *comma = "";
const char *comma = "";
tmp_list[0] = 0;
for (int ii = 0; ii < 16; ++ii) {
if (reg_list & (1 << ii)) {
@@ -300,7 +300,7 @@ char *Arm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr)
}
}
char *addr_mode = "";
const char *addr_mode = "";
if (is_pre) {
if (is_up) {
addr_mode = "ib";
@@ -333,19 +333,19 @@ char *Arm::disasm_mem(uint32_t insn, char *ptr)
uint8_t rd = (insn >> 12) & 0xf;
uint16_t offset = insn & 0xfff;
char *opname = "ldr";
const char *opname = "ldr";
if (!is_load)
opname = "str";
char *bang = "";
const char *bang = "";
if (write_back)
bang = "!";
char *minus = "";
const char *minus = "";
if (is_up == 0)
minus = "-";
char *byte = "";
const char *byte = "";
if (is_byte)
byte = "b";
@@ -359,7 +359,7 @@ char *Arm::disasm_mem(uint32_t insn, char *ptr)
opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang);
}
} else {
char *transfer = "";
const char *transfer = "";
if (write_back)
transfer = "t";
sprintf(ptr, "%s%s%s%s\tr%d, [r%d], #%s%u",
@@ -394,7 +394,7 @@ char *Arm::disasm_mem(uint32_t insn, char *ptr)
return ptr;
}
char *transfer = "";
const char *transfer = "";
if (write_back)
transfer = "t";
@@ -432,11 +432,11 @@ char *Arm::disasm_memhalf(uint32_t insn, char *ptr)
uint8_t rm = insn & 0xf;
uint8_t offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf);
char *opname = "ldr";
const char *opname = "ldr";
if (is_load == 0)
opname = "str";
char *width = "";
const char *width = "";
if (bits_65 == 1)
width = "h";
else if (bits_65 == 2)
@@ -444,10 +444,10 @@ char *Arm::disasm_memhalf(uint32_t insn, char *ptr)
else
width = "sh";
char *bang = "";
const char *bang = "";
if (write_back)
bang = "!";
char *minus = "";
const char *minus = "";
if (is_up == 0)
minus = "-";
@@ -587,7 +587,7 @@ char *Arm::disasm_pld(uint32_t insn, char *ptr)
uint8_t is_up = (insn >> 23) & 0x1;
uint8_t rn = (insn >> 16) & 0xf;
char *minus = "";
const char *minus = "";
if (is_up == 0)
minus = "-";

View File

@@ -32,7 +32,9 @@ class StackFrame {
typedef SYM symbol_type;
static const uint32_t kCausedException = 0x01;
static const uint32_t kInterpreted = 0x02;
static const uint32_t kPopBarrier = (kCausedException | kInterpreted);
static const uint32_t kStartNative = 0x04;
static const uint32_t kPopBarrier = (kCausedException | kInterpreted
| kStartNative);
symbol_type *function; // the symbol for the function we entered
uint32_t addr; // return address when this function returns
@@ -43,7 +45,8 @@ class StackFrame {
template <class FRAME, class BASE = CallStackBase>
class CallStack : public BASE {
public:
public:
typedef FRAME frame_type;
typedef typename FRAME::symbol_type symbol_type;
typedef typename FRAME::symbol_type::region_type region_type;
typedef BASE base_type;
@@ -56,7 +59,7 @@ class CallStack : public BASE {
void threadStart(uint64_t time);
void threadStop(uint64_t time);
// Set to true if you don't want to see any Java methods
// Set to true if you don't want to see any Java methods ever
void setNativeOnly(bool nativeOnly) {
mNativeOnly = nativeOnly;
}
@@ -64,38 +67,36 @@ class CallStack : public BASE {
int getStackLevel() { return mTop; }
uint64_t getGlobalTime(uint64_t time) { return time + mSkippedTime; }
void showStack();
void showSnapshotStack();
private:
enum Action { NONE, PUSH, POP };
Action getAction(BBEvent *event, symbol_type *function);
Action getMethodAction(BBEvent *event, symbol_type *function);
void doSimplePush(symbol_type *function, uint32_t addr,
uint64_t time);
void doSimplePop(uint64_t time);
void doPush(BBEvent *event, symbol_type *function);
void doPop(BBEvent *event, symbol_type *function, Action methodAction);
void transitionToJava();
void transitionFromJava(uint64_t time);
TraceReaderType *mTrace;
bool mNativeOnly;
symbol_type mDummyFunction;
region_type mDummyRegion;
void showStack(FILE *stream);
int mNumFrames;
FRAME *mFrames;
int mTop; // index of the next stack frame to write
int mJavaTop;
private:
enum Action { NONE, PUSH, POP, NATIVE_PUSH };
int mSnapshotNumFrames;
FRAME *mSnapshotFrames;
int mSnapshotTop; // index of the next stack frame to write
Action getAction(BBEvent *event, symbol_type *function);
void doMethodAction(BBEvent *event, symbol_type *function);
void doMethodPop(BBEvent *event, uint32_t addr, const uint32_t flags);
void doSimplePush(symbol_type *function, uint32_t addr,
uint64_t time, int flags);
void doSimplePop(uint64_t time);
void doPush(BBEvent *event, symbol_type *function);
void doPop(BBEvent *event, symbol_type *function, Action methodAction);
TraceReaderType *mTrace;
// This is a global switch that disables Java methods from appearing
// on the stack.
bool mNativeOnly;
// This keeps track of whether native frames are currently allowed on the
// stack.
bool mAllowNativeFrames;
symbol_type mDummyFunction;
region_type mDummyRegion;
symbol_type *mPrevFunction;
BBEvent mPrevEvent;
@@ -124,10 +125,7 @@ CallStack<FRAME, BASE>::CallStack(int id, int numFrames, TraceReaderType *trace)
mNumFrames = numFrames;
mFrames = new FRAME[mNumFrames];
mTop = 0;
mSnapshotNumFrames = numFrames;
mSnapshotFrames = new FRAME[mSnapshotNumFrames];
mSnapshotTop = 0;
mAllowNativeFrames = true;
memset(&mDummyFunction, 0, sizeof(symbol_type));
memset(&mDummyRegion, 0, sizeof(region_type));
@@ -138,7 +136,6 @@ CallStack<FRAME, BASE>::CallStack(int id, int numFrames, TraceReaderType *trace)
memset(&mUserEvent, 0, sizeof(BBEvent));
mSkippedTime = 0;
mLastRunTime = 0;
mJavaTop = 0;
// Read the first two methods from the trace if we haven't already read
// from the method trace yet.
@@ -168,11 +165,29 @@ CallStack<FRAME, BASE>::updateStack(BBEvent *event, symbol_type *function)
// instead.
if (function->vm_sym != NULL)
function = function->vm_sym;
} else {
doMethodAction(event, function);
}
Action action = getAction(event, function);
Action methodAction = getMethodAction(event, function);
// Allow native frames if we are executing in the kernel.
if (!mAllowNativeFrames
&& (function->region->flags & region_type::kIsKernelRegion) == 0) {
action = NONE;
}
if (function->vm_sym != NULL) {
function = function->vm_sym;
function->vm_sym = NULL;
}
if (action == PUSH) {
doPush(event, function);
} else if (action == POP) {
doPop(event, function, NONE);
}
#if 0
// Pop off native functions before pushing or popping Java methods.
if (action == POP && mPrevFunction->vm_sym == NULL) {
// Pop off the previous function first.
@@ -197,11 +212,16 @@ CallStack<FRAME, BASE>::updateStack(BBEvent *event, symbol_type *function)
doPush(event, function);
}
}
#endif
// If the stack is now empty, then push the current function.
if (mTop == 0) {
uint64_t time = event->time - mSkippedTime;
doSimplePush(function, 0, time);
int flags = 0;
if (function->vm_sym != NULL) {
flags = FRAME::kInterpreted;
}
doSimplePush(function, 0, time, 0);
}
mPrevFunction = function;
@@ -366,8 +386,11 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
// Check for stack overflow
if (mTop >= mNumFrames) {
// Don't show the stack by default because this generates a lot
// of output and this is seen by users if there is an error when
// post-processing the trace. But this is useful for debugging.
#if 0
showStack();
showStack(stderr);
#endif
fprintf(stderr, "Error: stack overflow (%d frames)\n", mTop);
exit(1);
@@ -391,17 +414,20 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
}
#if 0
// For debugging only. Show the stack before entering the kernel
// exception-handling code.
if (function->flags & symbol_type::kIsVectorStart) {
printf("stack before entering exception\n");
showStack();
showStack(stderr);
}
#endif
// If the previous function was a vector table, then pop it
// If the top of stack is a vector table, then pop it
// off before pushing on the new function. Also, change the
// return address for the new function to the return address
// from the vector table.
if ((mPrevFunction->flags & symbol_type::kIsVectorTable) && mTop > 0) {
if (mTop > 0
&& (mFrames[mTop - 1].function->flags & symbol_type::kIsVectorTable)) {
retAddr = mFrames[mTop - 1].addr;
doSimplePop(time);
}
@@ -426,9 +452,10 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
&& mTop > 0) {
// We are switching from kernel mode to user mode.
#if 0
// For debugging.
printf(" doPush(): popping to user mode, bb_addr: 0x%08x\n",
event->bb_addr);
showStack();
showStack(stderr);
#endif
do {
// Pop off the kernel frames until we reach the one that
@@ -445,6 +472,7 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
}
} while (mTop > 0);
#if 0
// For debugging
printf(" doPush() popping to level %d, using retAddr 0x%08x\n",
mTop, retAddr);
#endif
@@ -456,44 +484,33 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
if ((function->flags & symbol_type::kIsVectorStart) && mTop > 0)
mFrames[mTop - 1].flags |= FRAME::kCausedException;
doSimplePush(function, retAddr, time);
// If the function being pushed is a Java method, then mark it on
// the stack so that we don't pop it off until we get a matching
// trace record from the method trace file.
int flags = 0;
if (function->vm_sym != NULL) {
flags = FRAME::kInterpreted;
}
doSimplePush(function, retAddr, time, flags);
}
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function,
uint32_t addr, uint64_t time)
void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function, uint32_t addr,
uint64_t time, int flags)
{
// Check for stack overflow
if (mTop >= mNumFrames) {
showStack();
showStack(stderr);
fprintf(stderr, "too many stack frames (%d)\n", mTop);
exit(1);
}
// Keep track of the number of Java methods we push on the stack.
if (!mNativeOnly && function->vm_sym != NULL) {
// If we are pushing the first Java method on the stack, then
// save a snapshot of the stack so that we can clean things up
// later when we pop off the last Java stack frame.
if (mJavaTop == 0) {
transitionToJava();
}
mJavaTop += 1;
}
mFrames[mTop].addr = addr;
mFrames[mTop].function = function;
mFrames[mTop].flags = 0;
mFrames[mTop].flags = flags;
mFrames[mTop].time = time;
mFrames[mTop].global_time = time + mSkippedTime;
// If the function being pushed is a Java method, then mark it on
// the stack so that we don't pop it off until we get a matching
// trace record from the method trace file.
if (function->vm_sym != NULL) {
mFrames[mTop].flags = FRAME::kInterpreted;
}
mFrames[mTop].push(mTop, time, this);
mTop += 1;
}
@@ -508,17 +525,25 @@ void CallStack<FRAME, BASE>::doSimplePop(uint64_t time)
mTop -= 1;
mFrames[mTop].pop(mTop, time, this);
// Keep track of the number of Java methods we have on the stack.
symbol_type *function = mFrames[mTop].function;
if (!mNativeOnly && function->vm_sym != NULL) {
mJavaTop -= 1;
if (mNativeOnly)
return;
// When there are no more Java stack frames, then clean up
// the client's stack. We need to do this because the client
// doesn't see the changes to the native stack underlying the
// fake Java stack until the last Java method is popped off.
if (mJavaTop == 0) {
transitionFromJava(time);
// If the stack is empty, then allow more native frames.
// Otherwise, if we are transitioning from Java to native, then allow
// more native frames.
// Otherwise, if we are transitioning from native to Java, then disallow
// more native frames.
if (mTop == 0) {
mAllowNativeFrames = true;
} else {
bool newerIsJava = (mFrames[mTop].flags & FRAME::kInterpreted) != 0;
bool olderIsJava = (mFrames[mTop - 1].flags & FRAME::kInterpreted) != 0;
if (newerIsJava && !olderIsJava) {
// We are transitioning from Java to native
mAllowNativeFrames = true;
} else if (!newerIsJava && olderIsJava) {
// We are transitioning from native to Java
mAllowNativeFrames = false;
}
}
}
@@ -565,7 +590,13 @@ void CallStack<FRAME, BASE>::doPop(BBEvent *event, symbol_type *function,
// Compare the function with the one in the stack frame.
if (function == mFrames[stackLevel].function) {
// We found a matching function. We want to pop up to but not
// including this frame.
// including this frame. But allow popping this frame if this
// method called itself and we have a method pop.
if (allowMethodPop && function == mPrevFunction) {
// pop this frame
break;
}
// do not pop this frame
stackLevel += 1;
break;
}
@@ -604,9 +635,11 @@ void CallStack<FRAME, BASE>::doPop(BBEvent *event, symbol_type *function,
stackLevel = 1;
#if 0
// If we are popping off a large number of stack frames, then
// we might have a bug.
if (mTop - stackLevel > 7) {
printf("popping thru level %d\n", stackLevel);
showStack();
showStack(stderr);
}
#endif
@@ -654,20 +687,45 @@ void CallStack<FRAME, BASE>::popAll(uint64_t time)
}
template<class FRAME, class BASE>
typename CallStack<FRAME, BASE>::Action
CallStack<FRAME, BASE>::getMethodAction(BBEvent *event, symbol_type *function)
void CallStack<FRAME, BASE>::doMethodPop(BBEvent *event, uint32_t addr,
const uint32_t flags)
{
if (function->vm_sym == NULL && mPrevFunction->vm_sym == NULL) {
return NONE;
uint64_t time = event->time - mSkippedTime;
// Search the stack from the top down for a frame that contains a
// matching method.
int stackLevel;
for (stackLevel = mTop - 1; stackLevel >= 0; --stackLevel) {
if (mFrames[stackLevel].flags & flags) {
// If we are searching for a native method, then don't bother trying
// to match the address.
if (flags == FRAME::kStartNative)
break;
symbol_type *func = mFrames[stackLevel].function;
uint32_t methodAddr = func->region->base_addr + func->addr;
if (methodAddr == addr) {
break;
}
}
}
Action action = NONE;
uint32_t prevAddr = mPrevFunction->addr + mPrevFunction->region->base_addr;
uint32_t addr = function->addr + function->region->base_addr;
// If we found a matching frame then pop the stack up to and including
// that frame.
if (stackLevel >= 0) {
// Pop the stack frames
for (int ii = mTop - 1; ii >= stackLevel; --ii)
doSimplePop(time);
}
}
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::doMethodAction(BBEvent *event, symbol_type *function)
{
// If the events get ahead of the method trace, then read ahead until we
// sync up again. This can happen if there is a pop of a method in the
// method trace for which we don't have a previous push.
// method trace for which we don't have a previous push. Such an unmatched
// pop can happen because the user can start tracing at any time and so
// there might already be a stack when we start tracing.
while (event->time >= sNextMethod.time) {
sCurrentMethod = sNextMethod;
if (mTrace->ReadMethod(&sNextMethod)) {
@@ -675,86 +733,43 @@ CallStack<FRAME, BASE>::getMethodAction(BBEvent *event, symbol_type *function)
}
}
if (event->time >= sCurrentMethod.time) {
if (addr == sCurrentMethod.addr || prevAddr == sCurrentMethod.addr) {
action = (sCurrentMethod.flags == 0) ? PUSH : POP;
// We found a match, so read the next record.
sCurrentMethod = sNextMethod;
if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
sNextMethod.time = ~0ull;
}
if (event->time >= sCurrentMethod.time && event->pid == sCurrentMethod.pid) {
uint64_t time = event->time - mSkippedTime;
int flags = sCurrentMethod.flags;
if (flags == kMethodEnter) {
doSimplePush(function, 0, time, FRAME::kInterpreted);
mAllowNativeFrames = false;
} else if (flags == kNativeEnter) {
doSimplePush(function, 0, time, FRAME::kStartNative);
mAllowNativeFrames = true;
} else if (flags == kMethodExit || flags == kMethodException) {
doMethodPop(event, sCurrentMethod.addr, FRAME::kInterpreted);
} else if (flags == kNativeExit || flags == kNativeException) {
doMethodPop(event, sCurrentMethod.addr, FRAME::kStartNative);
}
// We found a match, so read the next record. When we get to the end
// of the trace, we set the time to the maximum value (~0).
sCurrentMethod = sNextMethod;
if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
sNextMethod.time = ~0ull;
}
}
return action;
}
// When the first Java method is pushed on the stack, this method is
// called to save a snapshot of the current native stack so that the
// client's view of the native stack can be patched up later when the
// Java stack is empty.
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::transitionToJava()
void CallStack<FRAME, BASE>::showStack(FILE *stream)
{
mSnapshotTop = mTop;
fprintf(stream, "mTop: %d skippedTime: %llu\n", mTop, mSkippedTime);
for (int ii = 0; ii < mTop; ++ii) {
mSnapshotFrames[ii] = mFrames[ii];
}
}
// When the Java stack becomes empty, the native stack becomes
// visible. This method is called when the Java stack becomes empty
// to patch up the client's view of the native stack, which may have
// changed underneath the Java stack. The stack snapshot is used to
// create a sequence of pops and pushes to make the client's view of
// the native stack match the current native stack.
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::transitionFromJava(uint64_t time)
{
int top = mTop;
if (top > mSnapshotTop) {
top = mSnapshotTop;
}
for (int ii = 0; ii < top; ++ii) {
if (mSnapshotFrames[ii].function->addr == mFrames[ii].function->addr) {
continue;
}
// Pop off all the rest of the frames from the snapshot
for (int jj = top - 1; jj >= ii; --jj) {
mSnapshotFrames[jj].pop(jj, time, this);
}
// Push the new frames from the native stack
for (int jj = ii; jj < mTop; ++jj) {
mFrames[jj].push(jj, time, this);
}
break;
}
}
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::showStack()
{
fprintf(stderr, "mTop: %d skippedTime: %llu\n", mTop, mSkippedTime);
for (int ii = 0; ii < mTop; ++ii) {
fprintf(stderr, " %d: t %d gt %d f %x 0x%08x 0x%08x %s\n",
uint32_t addr = mFrames[ii].function->addr;
addr += mFrames[ii].function->region->vstart;
fprintf(stream, " %d: t %d gt %d f %x 0x%08x 0x%08x %s\n",
ii, mFrames[ii].time, mFrames[ii].global_time,
mFrames[ii].flags,
mFrames[ii].addr, mFrames[ii].function->addr,
mFrames[ii].addr, addr,
mFrames[ii].function->name);
}
}
template<class FRAME, class BASE>
void CallStack<FRAME, BASE>::showSnapshotStack()
{
fprintf(stderr, "mSnapshotTop: %d\n", mSnapshotTop);
for (int ii = 0; ii < mSnapshotTop; ++ii) {
fprintf(stderr, " %d: t %d f %x 0x%08x 0x%08x %s\n",
ii, mSnapshotFrames[ii].time, mSnapshotFrames[ii].flags,
mSnapshotFrames[ii].addr, mSnapshotFrames[ii].function->addr,
mSnapshotFrames[ii].function->name);
}
}
#endif /* CALL_STACK_H */

View File

@@ -0,0 +1,270 @@
// Copyright 2009 The Android Open Source Project
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include <assert.h>
#include "trace_reader.h"
#include "bitvector.h"
#include "parse_options.h"
#include "armdis.h"
typedef TraceReader<> TraceReaderType;
#include "parse_options-inl.h"
#include "callstack.h"
typedef CallStack<StackFrame<symbol_type> > CallStackType;
void compareStacks(uint64_t time, int pid);
void dumpStacks(int pid);
static uint64_t debugTime;
static const int kNumStackFrames = 500;
static const int kMaxThreads = (32 * 1024);
CallStackType *eStacks[kMaxThreads];
int numErrors;
static const int kMaxErrors = 3;
struct frame {
uint64_t time;
uint32_t addr;
const char *name;
bool isNative;
frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
this->time = time;
this->addr = addr;
this->name = name;
this->isNative = isNative;
}
};
class Stack {
public:
static const int kMaxFrames = 1000;
int top;
frame *frames[kMaxFrames];
Stack() {
top = 0;
}
void push(frame *pframe);
frame* pop();
void dump();
};
void Stack::push(frame *pframe) {
if (top == kMaxFrames) {
fprintf(stderr, "Error: stack overflow\n");
exit(1);
}
frames[top] = pframe;
top += 1;
}
frame *Stack::pop() {
if (top <= 0)
return NULL;
top -= 1;
return frames[top];
}
Stack *mStacks[kMaxThreads];
void Usage(const char *program)
{
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
program);
OptionsUsage();
}
int main(int argc, char **argv)
{
ParseOptions(argc, argv);
if (argc - optind != 2) {
Usage(argv[0]);
exit(1);
}
char *qemu_trace_file = argv[optind++];
char *elf_file = argv[optind++];
TraceReaderType *etrace = new TraceReaderType;
etrace->Open(qemu_trace_file);
etrace->ReadKernelSymbols(elf_file);
etrace->SetRoot(root);
TraceReaderType *mtrace = new TraceReaderType;
mtrace->Open(qemu_trace_file);
mtrace->ReadKernelSymbols(elf_file);
mtrace->SetRoot(root);
BBEvent event;
while (1) {
BBEvent ignored;
symbol_type *function;
MethodRec method_record;
symbol_type *sym;
TraceReaderType::ProcessState *proc;
frame *pframe;
if (mtrace->ReadMethodSymbol(&method_record, &sym, &proc))
break;
if (!IsValidPid(proc->pid))
continue;
// Get the stack for the current thread
Stack *mStack = mStacks[proc->pid];
// If the stack does not exist, then allocate a new one.
if (mStack == NULL) {
mStack = new Stack();
mStacks[proc->pid] = mStack;
}
int flags = method_record.flags;
if (flags == kMethodEnter || flags == kNativeEnter) {
pframe = new frame(method_record.time, method_record.addr,
sym == NULL ? NULL: sym->name,
method_record.flags == kNativeEnter);
mStack->push(pframe);
} else {
pframe = mStack->pop();
delete pframe;
}
do {
if (GetNextValidEvent(etrace, &event, &ignored, &function))
break;
if (event.bb_num == 0)
break;
// Get the stack for the current thread
CallStackType *eStack = eStacks[event.pid];
// If the stack does not exist, then allocate a new one.
if (eStack == NULL) {
eStack = new CallStackType(event.pid, kNumStackFrames, etrace);
eStacks[event.pid] = eStack;
}
if (debugTime != 0 && event.time >= debugTime)
printf("time: %llu debug time: %lld\n", event.time, debugTime);
// Update the stack
eStack->updateStack(&event, function);
} while (event.time < method_record.time);
compareStacks(event.time, event.pid);
}
for (int ii = 0; ii < kMaxThreads; ++ii) {
if (eStacks[ii])
eStacks[ii]->popAll(event.time);
}
delete etrace;
delete mtrace;
return 0;
}
void compareStacks(uint64_t time, int pid) {
CallStackType *eStack = eStacks[pid];
Stack *mStack = mStacks[pid];
frame **mFrames = mStack->frames;
frame *mframe;
int mTop = mStack->top;
int eTop = eStack->mTop;
CallStackType::frame_type *eFrames = eStack->mFrames;
// Count the number of non-native methods (ie, Java methods) on the
// Java method stack
int numNonNativeMethods = 0;
for (int ii = 0; ii < mTop; ++ii) {
if (!mFrames[ii]->isNative) {
numNonNativeMethods += 1;
}
}
// Count the number of Java methods on the native stack
int numMethods = 0;
for (int ii = 0; ii < eTop; ++ii) {
if (eFrames[ii].flags & CallStackType::frame_type::kInterpreted) {
numMethods += 1;
}
}
// Verify that the number of Java methods on both stacks are the same.
// Allow the native stack to have one less Java method because the
// native stack might be pushing a native function first.
if (numNonNativeMethods != numMethods && numNonNativeMethods != numMethods + 1) {
printf("\nDiff at time %llu pid %d: non-native %d numMethods %d\n",
time, pid, numNonNativeMethods, numMethods);
dumpStacks(pid);
numErrors += 1;
if (numErrors >= kMaxErrors)
exit(1);
}
// Verify that the Java methods on the method stack are the same
// as the Java methods on the native stack.
int mIndex = 0;
for (int ii = 0; ii < eTop; ++ii) {
// Ignore native functions on the native stack.
if ((eFrames[ii].flags & CallStackType::frame_type::kInterpreted) == 0)
continue;
uint32_t addr = eFrames[ii].function->addr;
addr += eFrames[ii].function->region->vstart;
while (mIndex < mTop && mFrames[mIndex]->isNative) {
mIndex += 1;
}
if (mIndex >= mTop)
break;
if (addr != mFrames[mIndex]->addr) {
printf("\nDiff at time %llu pid %d: frame %d\n", time, pid, ii);
dumpStacks(pid);
exit(1);
}
mIndex += 1;
}
}
void dumpStacks(int pid) {
CallStackType *eStack = eStacks[pid];
Stack *mStack = mStacks[pid];
frame *mframe;
int mTop = mStack->top;
printf("\nJava method stack\n");
for (int ii = 0; ii < mTop; ii++) {
mframe = mStack->frames[ii];
const char *native = mframe->isNative ? "n" : " ";
printf(" %s %d: %llu 0x%x %s\n",
native, ii, mframe->time, mframe->addr,
mframe->name == NULL ? "" : mframe->name);
}
int eTop = eStack->mTop;
CallStackType::frame_type *eFrames = eStack->mFrames;
int mIndex = 0;
printf("\nNative stack\n");
for (int ii = 0; ii < eTop; ++ii) {
uint32_t addr = eFrames[ii].function->addr;
addr += eFrames[ii].function->region->vstart;
const char *marker = " ";
if (eFrames[ii].flags & CallStackType::frame_type::kInterpreted) {
if (mIndex >= mTop || addr != mStack->frames[mIndex]->addr) {
marker = "*";
}
mIndex += 1;
}
printf(" %s %d: %d f %d 0x%08x %s\n",
marker, ii, eFrames[ii].time, eFrames[ii].flags, addr,
eFrames[ii].function->name);
}
}

View File

@@ -137,7 +137,7 @@ int main(int argc, char **argv)
continue;
if (strcmp(psym->name, ".plt") == 0)
continue;
char *ksym = " ";
const char *ksym = " ";
if (psym->region->flags & region_type::kIsKernelRegion)
ksym = "k";
printf("%s %s %s\n", ksym, psym->name, psym->region->path);

View File

@@ -0,0 +1,59 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include "trace_reader.h"
#include "parse_options.h"
typedef TraceReader<> TraceReaderType;
#include "parse_options-inl.h"
void Usage(const char *program)
{
fprintf(stderr, "Usage: %s [options] trace_file\n", program);
OptionsUsage();
}
int main(int argc, char **argv) {
// Parse the options
ParseOptions(argc, argv);
if (argc - optind != 1) {
Usage(argv[0]);
exit(1);
}
char *trace_filename = argv[optind];
TraceReader<> *trace = new TraceReader<>;
trace->Open(trace_filename);
trace->SetRoot(root);
while (1) {
BBEvent event, ignored;
symbol_type *dummy_sym;
if (GetNextValidEvent(trace, &event, &ignored, &dummy_sym))
break;
}
int num_procs;
ProcessState *processes = trace->GetProcesses(&num_procs);
ProcessState *pstate = &processes[0];
for (int ii = 0; ii < num_procs; ++ii, ++pstate) {
if (pstate->name == NULL)
pstate->name = "";
ProcessState *manager = pstate->addr_manager;
printf("pid %d regions: %d %s",
pstate->pid, manager->nregions, pstate->name);
for (int jj = 1; jj < pstate->argc; ++jj) {
printf(" %s", pstate->argv[jj]);
}
printf("\n");
trace->DumpRegions(stdout, pstate);
}
delete trace;
return 0;
}

View File

@@ -21,6 +21,7 @@ class HashTable {
typedef T value_type;
void Update(const char *key, T value);
bool Remove(const char *key);
T Find(const char *key);
entry_type* GetFirst();
entry_type* GetNext();
@@ -120,6 +121,31 @@ void HashTable<T>::Update(const char *key, T value)
num_entries_ += 1;
}
template<class T>
bool HashTable<T>::Remove(const char *key)
{
// Hash the key to get the table position
int len = strlen(key);
int pos = HashFunction(key) & mask_;
// Search the chain for a matching key and keep track of the previous
// element in the chain.
entry_type *prev = NULL;
for (entry_type *ptr = table_[pos]; ptr; prev = ptr, ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
if (prev == NULL) {
table_[pos] = ptr->next;
} else {
prev->next = ptr->next;
}
delete ptr->key;
delete ptr;
return true;
}
}
return false;
}
template<class T>
typename HashTable<T>::value_type HashTable<T>::Find(const char *key)
{

View File

@@ -42,6 +42,14 @@ inline bool IsValidEvent(BBEvent *event, symbol_type *sym)
return true;
}
inline bool IsValidPid(int pid) {
if (include_some_pids && pid_include_vector.GetBit(pid) == 0)
return false;
if (exclude_some_pids && pid_exclude_vector.GetBit(pid))
return false;
return true;
}
inline symbol_type *GetSymbol(TraceReaderType *trace, int pid, uint32_t addr,
uint64_t time)
{

View File

@@ -137,7 +137,7 @@ int main(int argc, char **argv) {
double insn_per_sec = 0;
if (elapsed_secs != 0)
insn_per_sec = num_dynamic_insn / elapsed_secs;
char *suffix = "";
const char *suffix = "";
if (insn_per_sec >= 1000000) {
insn_per_sec /= 1000000.0;
suffix = "M";

View File

@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
sum_time += pstate->cpu_time;
double per = 100.0 * pstate->cpu_time / total_time;
double sum_per = 100.0 * sum_time / total_time;
char *print_flags = "";
const char *print_flags = "";
if ((pstate->flags & ProcessState::kCalledExec) == 0)
print_flags = "T";
if (pstate->name == NULL)
@@ -84,10 +84,11 @@ int main(int argc, char **argv) {
printf("%5d %5d %10llu %6.2f %6.2f %5s %s",
pstate->pid, pstate->parent_pid, pstate->cpu_time,
per, sum_per, print_flags, pstate->name);
for (int ii = 1; ii < pstate->argc; ++ii) {
printf(" %s", pstate->argv[ii]);
for (int jj = 1; jj < pstate->argc; ++jj) {
printf(" %s", pstate->argv[jj]);
}
printf("\n");
}
delete trace;
return 0;
}

View File

@@ -118,7 +118,7 @@ int main(int argc, char **argv)
double per = 100.0 * sym->elapsed / total;
double sum_per = 100.0 * sum / total;
double secs = 1.0 * sym->elapsed / kMHz;
char *ksym = " ";
const char *ksym = " ";
if (sym->region->flags & region_type::kIsKernelRegion)
ksym = "k";
printf("%12.2f %11lld %6.2f %6.2f %s %s\n",

View File

@@ -208,7 +208,7 @@ int main(int argc, char **argv)
if (pStack == NULL) {
pStack = new CallStackType(event.pid, kNumStackFrames, trace);
stacks[event.pid] = pStack;
char *name = trace->GetProcessName(event.pid);
const char *name = trace->GetProcessName(event.pid);
dmtrace->addThread(event.pid, name);
}
@@ -267,7 +267,6 @@ int main(int argc, char **argv)
}
}
dmtrace->close();
delete dmtrace;
delete trace;

View File

@@ -20,7 +20,7 @@ int main(int argc, char **argv) {
if (trace->ReadAddr(&time, &addr, &flags))
break;
char *op = "ld";
const char *op = "ld";
if (flags == 1)
op = "st";
printf("%lld 0x%08x %s\n", time, addr, op);

View File

@@ -9,6 +9,66 @@ typedef TraceReader<> TraceReaderType;
#include "parse_options-inl.h"
struct frame {
uint64_t time;
uint32_t addr;
const char *name;
bool isNative;
frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
this->time = time;
this->addr = addr;
this->name = name;
this->isNative = isNative;
}
};
class Stack {
static const int kMaxFrames = 1000;
int top;
frame *frames[kMaxFrames];
public:
Stack() {
top = 0;
}
void push(frame *pframe);
frame* pop();
void dump();
};
void Stack::push(frame *pframe) {
if (top == kMaxFrames) {
fprintf(stderr, "Error: stack overflow\n");
exit(1);
}
frames[top] = pframe;
top += 1;
}
frame *Stack::pop() {
if (top <= 0)
return NULL;
top -= 1;
return frames[top];
}
void Stack::dump() {
frame *pframe;
for (int ii = 0; ii < top; ii++) {
pframe = frames[ii];
const char *native = pframe->isNative ? "n" : " ";
printf(" %s %d: %llu 0x%x %s\n",
native, ii, pframe->time, pframe->addr,
pframe->name == NULL ? "" : pframe->name);
}
}
static const int kMaxThreads = (32 * 1024);
Stack *stacks[kMaxThreads];
void Usage(const char *program)
{
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
@@ -34,9 +94,14 @@ int main(int argc, char **argv) {
MethodRec method_record;
symbol_type *sym;
TraceReaderType::ProcessState *proc;
frame *pframe;
if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
break;
if (!IsValidPid(proc->pid))
continue;
if (sym != NULL) {
printf("%lld p %d 0x%x %d %s\n",
method_record.time, proc->pid, method_record.addr,
@@ -46,7 +111,27 @@ int main(int argc, char **argv) {
method_record.time, proc->pid, method_record.addr,
method_record.flags);
}
proc->DumpStack();
// Get the stack for the current thread
Stack *pStack = stacks[proc->pid];
// If the stack does not exist, then allocate a new one.
if (pStack == NULL) {
pStack = new Stack();
stacks[proc->pid] = pStack;
}
int flags = method_record.flags;
if (flags == kMethodEnter || flags == kNativeEnter) {
pframe = new frame(method_record.time, method_record.addr,
sym == NULL ? NULL: sym->name,
method_record.flags == kNativeEnter);
pStack->push(pframe);
} else {
pframe = pStack->pop();
delete pframe;
}
pStack->dump();
}
return 0;
}

View File

@@ -15,17 +15,40 @@ typedef TraceReader<> TraceReaderType;
#include "parse_options-inl.h"
#include "callstack.h"
static uint64_t debugTime;
static uint64_t dumpTime = 0;
class MyFrame : public StackFrame<symbol_type> {
public:
void push(int stackLevel, uint64_t time, CallStackBase *base);
void pop(int stackLevel, uint64_t time, CallStackBase *base);
void getFrameType(char *type);
};
typedef CallStack<MyFrame> CallStackType;
void MyFrame::getFrameType(char *type)
{
strcpy(type, "----");
if (flags & kCausedException)
type[0] = 'e';
if (flags & kInterpreted)
type[1] = 'm';
if (function->region->flags & region_type::kIsKernelRegion)
type[2] = 'k';
if (function->flags & symbol_type::kIsVectorTable)
type[3] = 'v';
}
void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
{
printf("%llu en thr %d %3d", time, base->getId(), stackLevel);
char type[5];
if (dumpTime > 0)
return;
getFrameType(type);
printf("%llu en thr %d %s %3d", time, base->getId(), type, stackLevel);
for (int ii = 0; ii < stackLevel; ++ii)
printf(".");
printf(" 0x%08x %s\n", addr, function->name);
@@ -33,7 +56,13 @@ void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
{
printf("%llu x thr %d %3d", time, base->getId(), stackLevel);
char type[5];
if (dumpTime > 0)
return;
getFrameType(type);
printf("%llu x thr %d %s %3d", time, base->getId(), type, stackLevel);
for (int ii = 0; ii < stackLevel; ++ii)
printf(".");
printf(" 0x%08x %s\n", addr, function->name);
@@ -43,18 +72,36 @@ static const int kNumStackFrames = 500;
static const int kMaxThreads = (32 * 1024);
CallStackType *stacks[kMaxThreads];
static uint64_t debugTime;
void Usage(const char *program)
{
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
fprintf(stderr, "Usage: %s [options] [-- -d dumpTime] trace_name elf_file\n",
program);
OptionsUsage();
}
bool localParseOptions(int argc, char **argv)
{
bool err = false;
while (!err) {
int opt = getopt(argc, argv, "+d:");
if (opt == -1)
break;
switch (opt) {
case 'd':
dumpTime = strtoull(optarg, NULL, 0);
break;
default:
err = true;
break;
}
}
return err;
}
int main(int argc, char **argv)
{
ParseOptions(argc, argv);
localParseOptions(argc, argv);
if (argc - optind != 2) {
Usage(argv[0]);
exit(1);
@@ -66,9 +113,6 @@ int main(int argc, char **argv)
trace->Open(qemu_trace_file);
trace->ReadKernelSymbols(elf_file);
trace->SetRoot(root);
TraceHeader *qheader = trace->GetHeader();
uint64_t startTime = qheader->start_sec;
startTime = (startTime << 32) | qheader->start_usec;
BBEvent event;
while (1) {
@@ -93,6 +137,13 @@ int main(int argc, char **argv)
// Update the stack
pStack->updateStack(&event, function);
// If the user requested a stack dump at a certain time,
// and we are at that time, then dump the stack and exit.
if (dumpTime > 0 && event.time >= dumpTime) {
pStack->showStack(stdout);
break;
}
}
for (int ii = 0; ii < kMaxThreads; ++ii) {

View File

@@ -46,7 +46,7 @@ struct thumb_opcode
{
unsigned short value, mask; /* recognise instruction if (op&mask)==value */
Opcode opcode;
char * assembler; /* how to disassemble this instruction */
const char * assembler; /* how to disassemble this instruction */
};
/* format of the assembler string :
@@ -216,7 +216,7 @@ static struct thumb_opcode thumb_opcodes[] =
#define BDISP23(x,y) ((((((x) & 0x07ff) << 11) | ((y) & 0x07ff)) \
^ 0x200000) - 0x200000) /* 23bit */
static char * arm_conditional[] =
static const char * arm_conditional[] =
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
@@ -281,7 +281,7 @@ char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *resul
if ((insn1 & insn->mask) != insn->value)
continue;
char * c = insn->assembler;
const char * c = insn->assembler;
/* Special processing for Thumb 2-instruction BL sequence: */
if (!*c) { /* Check for empty (not NULL) assembler string. */

View File

@@ -131,7 +131,7 @@ BBReader::~BBReader()
delete decoder_;
}
void BBReader::Open(char *filename)
void BBReader::Open(const char *filename)
{
// Initialize the class variables
memset(&nextrec_, 0, sizeof(TimeRec));
@@ -268,7 +268,7 @@ InsnReader::~InsnReader()
delete decoder_;
}
void InsnReader::Open(char *filename)
void InsnReader::Open(const char *filename)
{
prev_time_ = 0;
time_diff_ = 0;
@@ -310,7 +310,7 @@ AddrReader::~AddrReader()
}
// Returns true if there is an error opening the file
bool AddrReader::Open(char *filename, char *suffix)
bool AddrReader::Open(const char *filename, const char *suffix)
{
struct stat stat_buf;
@@ -367,7 +367,7 @@ ExcReader::~ExcReader()
delete decoder_;
}
void ExcReader::Open(char *filename)
void ExcReader::Open(const char *filename)
{
prev_time_ = 0;
prev_recnum_ = 0;
@@ -421,7 +421,7 @@ PidReader::~PidReader()
delete decoder_;
}
void PidReader::Open(char *filename)
void PidReader::Open(const char *filename)
{
prev_time_ = 0;
@@ -561,7 +561,7 @@ MethodReader::~MethodReader()
delete decoder_;
}
bool MethodReader::Open(char *filename)
bool MethodReader::Open(const char *filename)
{
struct stat stat_buf;
@@ -686,8 +686,8 @@ TraceReaderBase::~TraceReaderBase()
delete[] static_filename_;
}
void TraceReaderBase::ReadTraceHeader(FILE *fstream, char *filename,
char *tracename, TraceHeader *header)
void TraceReaderBase::ReadTraceHeader(FILE *fstream, const char *filename,
const char *tracename, TraceHeader *header)
{
int rval = fread(header, sizeof(TraceHeader), 1, fstream);
if (rval != 1) {
@@ -721,7 +721,7 @@ void TraceReaderBase::ReadTraceHeader(FILE *fstream, char *filename,
}
void TraceReaderBase::Open(char *filename)
void TraceReaderBase::Open(const char *filename)
{
char *fname;
FILE *fstream;
@@ -840,7 +840,7 @@ static void CopyDexSymbolsToArray(DexFileList *dexfile,
}
}
void TraceReaderBase::ParseDexList(char *filename)
void TraceReaderBase::ParseDexList(const char *filename)
{
struct stat stat_buf;
static const int kBufSize = 4096;

View File

@@ -62,6 +62,19 @@ class TraceReader : public TraceReaderBase {
return NULL;
}
region_entry *MakePrivateCopy(region_entry *dest) {
dest->refs = 0;
dest->path = Strdup(path);
dest->vstart = vstart;
dest->vend = vend;
dest->base_addr = base_addr;
dest->file_offset = file_offset;
dest->flags = flags;
dest->nsymbols = nsymbols;
dest->symbols = symbols;
return dest;
}
int refs; // reference count
char *path;
uint32_t vstart;
@@ -100,6 +113,11 @@ class TraceReader : public TraceReaderBase {
static const int kHasKernelRegion = 0x08;
static const int kHasFirstMmap = 0x10;
struct methodFrame {
uint32_t addr;
bool isNative;
};
ProcessState() {
cpu_time = 0;
tgid = 0;
@@ -153,7 +171,7 @@ class TraceReader : public TraceReaderBase {
}
// Dumps the stack contents to standard output. For debugging.
void DumpStack();
void DumpStack(FILE *stream);
uint64_t cpu_time;
uint64_t start_time;
@@ -165,7 +183,7 @@ class TraceReader : public TraceReaderBase {
uint32_t flags;
int argc;
char **argv;
char *name;
const char *name;
int nregions; // num regions in use
int max_regions; // max regions allocated
region_type **regions;
@@ -173,7 +191,7 @@ class TraceReader : public TraceReaderBase {
ProcessState *addr_manager; // the address space manager process
ProcessState *next;
int method_stack_top;
uint32_t method_stack[kMaxMethodStackSize];
methodFrame method_stack[kMaxMethodStackSize];
symbol_type *current_method_sym;
};
@@ -184,12 +202,13 @@ class TraceReader : public TraceReaderBase {
void CopyKernelRegion(ProcessState *pstate);
void ClearRegions(ProcessState *pstate);
void CopyRegions(ProcessState *parent, ProcessState *child);
void DumpRegions(FILE *stream, ProcessState *pstate);
symbol_type *LookupFunction(int pid, uint32_t addr, uint64_t time);
symbol_type *GetSymbols(int *num_syms);
ProcessState *GetCurrentProcess() { return current_; }
ProcessState *GetProcesses(int *num_procs);
ProcessState *GetNextProcess();
char *GetProcessName(int pid);
const char *GetProcessName(int pid);
void SetRoot(const char *root) { root_ = root; }
void SetDemangle(bool demangle) { demangle_ = demangle; }
bool ReadMethodSymbol(MethodRec *method_record,
@@ -217,6 +236,10 @@ class TraceReader : public TraceReaderBase {
void AddRegion(ProcessState *pstate, region_type *region);
region_type *FindRegion(uint32_t addr, int nregions,
region_type **regions);
int FindRegionIndex(uint32_t addr, int nregions,
region_type **regions);
void FindAndRemoveRegion(ProcessState *pstate,
uint32_t vstart, uint32_t vend);
symbol_type *FindFunction(uint32_t addr, int nsyms,
symbol_type *symbols, bool exact_match);
symbol_type *FindCurrentMethod(int pid, uint64_t time);
@@ -276,11 +299,14 @@ TraceReader<T>::~TraceReader()
hash_entry_type *ptr;
for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
region_type *region = ptr->value;
int nsymbols = region->nsymbols;
for (int ii = 0; ii < nsymbols; ii++) {
delete[] region->symbols[ii].name;
// If the symbols are not shared with another region, then delete them.
if ((region->flags & region_type::kSharedSymbols) == 0) {
int nsymbols = region->nsymbols;
for (int ii = 0; ii < nsymbols; ii++) {
delete[] region->symbols[ii].name;
}
delete[] region->symbols;
}
delete[] region->symbols;
delete[] region->path;
// Do not delete the region itself here. Each region
@@ -422,7 +448,7 @@ TraceReader<T>::GetNextProcess()
}
template<class T>
char* TraceReader<T>::GetProcessName(int pid)
const char* TraceReader<T>::GetProcessName(int pid)
{
if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
return "(unknown)";
@@ -922,6 +948,63 @@ void TraceReader<T>::AddRegion(ProcessState *pstate, region_type *region)
qsort(manager->regions, nregions, sizeof(region_type*), cmp_region_addr<T>);
}
template<class T>
void TraceReader<T>::FindAndRemoveRegion(ProcessState *pstate, uint32_t vstart,
uint32_t vend)
{
ProcessState *manager = pstate->addr_manager;
int nregions = manager->nregions;
int index = FindRegionIndex(vstart, nregions, manager->regions);
region_type *region = manager->regions[index];
// If the region does not contain [vstart,vend], then return.
if (vstart < region->vstart || vend > region->vend)
return;
// If the existing region exactly matches the address range [vstart,vend]
// then remove the whole region.
if (vstart == region->vstart && vend == region->vend) {
// The regions are reference-counted.
if (region->refs == 0) {
// Free the region
hash_->Remove(region->path);
delete region;
} else {
region->refs -= 1;
}
if (nregions > 1) {
// Assign the region at the end of the array to this empty slot
manager->regions[index] = manager->regions[nregions - 1];
// Resort the regions into increasing start address
qsort(manager->regions, nregions - 1, sizeof(region_type*),
cmp_region_addr<T>);
}
manager->nregions = nregions - 1;
return;
}
// If the existing region contains the given range and ends at the
// end of the given range (a common case for some reason), then
// truncate the existing region so that it ends at vstart (because
// we are deleting the range [vstart,vend]).
if (vstart > region->vstart && vend == region->vend) {
region_type *truncated;
if (region->refs == 0) {
// This region is not shared, so truncate it directly
truncated = region;
} else {
// This region is shared, so make a copy that we can truncate
region->refs -= 1;
truncated = region->MakePrivateCopy(new region_type);
}
truncated->vend = vstart;
manager->regions[index] = truncated;
}
}
template<class T>
void TraceReader<T>::CopyRegions(ProcessState *parent, ProcessState *child)
{
@@ -940,6 +1023,20 @@ void TraceReader<T>::CopyRegions(ProcessState *parent, ProcessState *child)
}
}
template<class T>
void TraceReader<T>::DumpRegions(FILE *stream, ProcessState *pstate) {
ProcessState *manager = pstate->addr_manager;
for (int ii = 0; ii < manager->nregions; ++ii) {
fprintf(stream, " %08x - %08x offset: %5x nsyms: %4d refs: %d %s\n",
manager->regions[ii]->vstart,
manager->regions[ii]->vend,
manager->regions[ii]->file_offset,
manager->regions[ii]->nsymbols,
manager->regions[ii]->refs,
manager->regions[ii]->path);
}
}
template<class T>
typename TraceReader<T>::region_type *
TraceReader<T>::FindRegion(uint32_t addr, int nregions, region_type **regions)
@@ -964,6 +1061,30 @@ TraceReader<T>::FindRegion(uint32_t addr, int nregions, region_type **regions)
return regions[low];
}
template<class T>
int TraceReader<T>::FindRegionIndex(uint32_t addr, int nregions,
region_type **regions)
{
int high = nregions;
int low = -1;
while (low + 1 < high) {
int middle = (high + low) / 2;
uint32_t middle_addr = regions[middle]->vstart;
if (middle_addr == addr)
return middle;
if (middle_addr > addr)
high = middle;
else
low = middle;
}
// If we get here then we did not find an exact address match. So use
// the closest region address that is less than the given address.
if (low < 0)
low = 0;
return low;
}
template<class T>
typename TraceReader<T>::symbol_type *
TraceReader<T>::FindFunction(uint32_t addr, int nsyms, symbol_type *symbols,
@@ -1004,15 +1125,12 @@ TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
uint32_t sym_addr = addr - cached_func_->region->base_addr;
if (sym_addr >= cached_func_->addr
&& sym_addr < (cached_func_ + 1)->addr) {
// If this function is the virtual machine interpreter, then
// read the method trace to find the "real" method name based
// on the current time and pid.
if (cached_func_->flags & symbol_type::kIsInterpreter) {
symbol_type *sym = FindCurrentMethod(pid, time);
if (sym != NULL) {
sym->vm_sym = cached_func_;
return sym;
}
// Check if there is a Java method on the method trace.
symbol_type *sym = FindCurrentMethod(pid, time);
if (sym != NULL) {
sym->vm_sym = cached_func_;
return sym;
}
return cached_func_;
}
@@ -1037,15 +1155,11 @@ TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
if (cached_func_ != NULL) {
cached_func_->region = region;
// If this function is the virtual machine interpreter, then
// read the method trace to find the "real" method name based
// on the current time and pid.
if (cached_func_->flags & symbol_type::kIsInterpreter) {
symbol_type *sym = FindCurrentMethod(pid, time);
if (sym != NULL) {
sym->vm_sym = cached_func_;
return sym;
}
// Check if there is a Java method on the method trace.
symbol_type *sym = FindCurrentMethod(pid, time);
if (sym != NULL) {
sym->vm_sym = cached_func_;
return sym;
}
}
@@ -1139,11 +1253,17 @@ void TraceReader<T>::HandlePidEvent(PidEvent *event)
current_->exit_val = event->pid;
current_->flags |= ProcessState::kCalledExit;
break;
case kPidMunmap:
FindAndRemoveRegion(current_, event->vstart, event->vend);
break;
case kPidMmap:
{
region_type *region;
region_type *existing_region = hash_->Find(event->path);
if (existing_region == NULL || existing_region->vstart != event->vstart) {
if (existing_region == NULL
|| existing_region->vstart != event->vstart
|| existing_region->vend != event->vend
|| existing_region->file_offset != event->offset) {
// Create a new region and add it to the current process'
// address space.
region = new region_type;
@@ -1165,8 +1285,6 @@ void TraceReader<T>::HandlePidEvent(PidEvent *event)
} else {
region->nsymbols = existing_region->nsymbols;
region->symbols = existing_region->symbols;
region->path = existing_region->path;
delete[] event->path;
region->flags |= region_type::kSharedSymbols;
}
@@ -1263,10 +1381,12 @@ int TraceReader<T>::FindCurrentPid(uint64_t time)
}
template <class T>
void TraceReader<T>::ProcessState::DumpStack()
void TraceReader<T>::ProcessState::DumpStack(FILE *stream)
{
const char *native;
for (int ii = 0; ii < method_stack_top; ii++) {
printf("%2d: 0x%08x\n", ii, method_stack[ii]);
native = method_stack[ii].isNative ? "n" : " ";
fprintf(stream, "%2d: %s 0x%08x\n", ii, native, method_stack[ii].addr);
}
}
@@ -1276,13 +1396,17 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
{
uint32_t addr;
int top = pstate->method_stack_top;
if (method_rec->flags == kMethodEnter) {
int flags = method_rec->flags;
bool isNative;
if (flags == kMethodEnter || flags == kNativeEnter) {
// Push this method on the stack
if (top >= pstate->kMaxMethodStackSize) {
fprintf(stderr, "Stack overflow at time %llu\n", method_rec->time);
exit(1);
}
pstate->method_stack[top] = method_rec->addr;
pstate->method_stack[top].addr = method_rec->addr;
isNative = (flags == kNativeEnter);
pstate->method_stack[top].isNative = isNative;
pstate->method_stack_top = top + 1;
addr = method_rec->addr;
} else {
@@ -1292,14 +1416,27 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
return;
}
top -= 1;
addr = pstate->method_stack[top];
if (addr != method_rec->addr) {
addr = pstate->method_stack[top].addr;
// If this is a non-native method then the address we are popping should
// match the top-of-stack address. Native pops don't always match the
// address of the native push for some reason.
if (addr != method_rec->addr && !pstate->method_stack[top].isNative) {
fprintf(stderr,
"Stack method (0x%x) at index %d does not match trace record (0x%x) at time %llu\n",
addr, top, method_rec->addr, method_rec->time);
for (int ii = 0; ii <= top; ii++) {
fprintf(stderr, " %d: 0x%x\n", ii, pstate->method_stack[ii]);
}
pstate->DumpStack(stderr);
exit(1);
}
// If we are popping a native method, then the top-of-stack should also
// be a native method.
bool poppingNative = (flags == kNativeExit) || (flags == kNativeException);
if (poppingNative != pstate->method_stack[top].isNative) {
fprintf(stderr,
"Popping native vs. non-native mismatch at index %d time %llu\n",
top, method_rec->time);
pstate->DumpStack(stderr);
exit(1);
}
@@ -1309,8 +1446,17 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
pstate->current_method_sym = NULL;
return;
}
addr = pstate->method_stack[top - 1];
addr = pstate->method_stack[top - 1].addr;
isNative = pstate->method_stack[top - 1].isNative;
}
// If the top-of-stack is a native method, then set the current method
// to NULL.
if (isNative) {
pstate->current_method_sym = NULL;
return;
}
ProcessState *manager = pstate->addr_manager;
region_type *region = FindRegion(addr, manager->nregions, manager->regions);
uint32_t sym_addr = addr - region->base_addr;
@@ -1323,6 +1469,11 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
}
}
// Returns the current top-of-stack Java method, if any, for the given pid
// at the given time. The "time" parameter must be monotonically increasing
// across successive calls to this method.
// If the Java method stack is empty or if a native JNI method is on the
// top of the stack, then this method returns NULL.
template <class T>
typename TraceReader<T>::symbol_type*
TraceReader<T>::FindCurrentMethod(int pid, uint64_t time)

View File

@@ -83,7 +83,7 @@ class TraceReaderBase {
friend class BBReader;
void Open(char *filename);
void Open(const char *filename);
void Close();
void WriteHeader(TraceHeader *header);
inline bool ReadBB(BBEvent *event);
@@ -120,10 +120,10 @@ class TraceReaderBase {
private:
int FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
void ReadTraceHeader(FILE *fstream, char *filename,
char *tracename, TraceHeader *header);
void ReadTraceHeader(FILE *fstream, const char *filename,
const char *tracename, TraceHeader *header);
PidEvent *FindMmapDexFileEvent();
void ParseDexList(char *filename);
void ParseDexList(const char *filename);
char *static_filename_;
FILE *static_fstream_;
@@ -159,7 +159,7 @@ class BBReader {
public:
explicit BBReader(TraceReaderBase *trace);
~BBReader();
void Open(char *filename);
void Open(const char *filename);
void Close();
bool ReadBB(BBEvent *event);
@@ -193,7 +193,7 @@ class InsnReader {
InsnReader();
~InsnReader();
void Open(char *filename);
void Open(const char *filename);
void Close();
uint64_t ReadInsnTime(uint64_t min_time);
@@ -209,7 +209,7 @@ class AddrReader {
AddrReader();
~AddrReader();
bool Open(char *filename, char *suffix);
bool Open(const char *filename, const char *suffix);
void Close();
bool ReadAddr(uint64_t *time, uint32_t *addr);
@@ -225,7 +225,7 @@ class ExcReader {
ExcReader();
~ExcReader();
void Open(char *filename);
void Open(const char *filename);
void Close();
bool ReadExc(uint64_t *time, uint32_t *current_pc,
uint64_t *recnum, uint32_t *target_pc,
@@ -243,7 +243,7 @@ class PidReader {
PidReader();
~PidReader();
void Open(char *filename);
void Open(const char *filename);
void Close();
bool ReadPidEvent(struct PidEvent *event);
void Dispose(struct PidEvent *event);
@@ -258,7 +258,7 @@ class MethodReader {
MethodReader();
~MethodReader();
bool Open(char *filename);
bool Open(const char *filename);
void Close();
bool ReadMethod(MethodRec *method_record);

View File

@@ -34,6 +34,7 @@
#include <errno.h>
#include <string.h>
#include <cutils/log.h>
#include <cutils/native_handle.h>
#include <cutils/sockets.h>
#include <hardware/sensors.h>
@@ -123,16 +124,19 @@ typedef struct SensorControl {
/* this must return a file descriptor that will be used to read
* the sensors data (it is passed to data__data_open() below
*/
static int
static native_handle_t*
control__open_data_source(struct sensors_control_device_t *dev)
{
SensorControl* ctl = (void*)dev;
native_handle_t* handle;
if (ctl->fd < 0) {
ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
}
D("%s: fd=%d", __FUNCTION__, ctl->fd);
return ctl->fd;
handle = native_handle_create(1, 0);
handle->data[0] = ctl->fd;
return handle;
}
static int
@@ -244,7 +248,7 @@ data__now_ns(void)
}
static int
data__data_open(struct sensors_data_device_t *dev, int fd)
data__data_open(struct sensors_data_device_t *dev, native_handle_t* handle)
{
SensorData* data = (void*)dev;
int i;
@@ -258,7 +262,9 @@ data__data_open(struct sensors_data_device_t *dev, int fd)
data->timeStart = 0;
data->timeOffset = 0;
data->events_fd = dup(fd);
data->events_fd = dup(handle->data[0]);
native_handle_close(handle);
native_handle_delete(handle);
return 0;
}

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=160

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=160

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=160

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=120

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=120

36
emulator/tools/Android.mk Normal file
View File

@@ -0,0 +1,36 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# this file is used to build emulator-specific program tools
# that should only run in the emulator.
#
LOCAL_PATH := $(call my-dir)
ifneq ($(TARGET_PRODUCT),sim)
# The 'qemu-props' program is run from /system/etc/init.goldfish.rc
# to setup various system properties sent by the emulator program.
#
include $(CLEAR_VARS)
LOCAL_MODULE := qemu-props
LOCAL_SRC_FILES := qemu-props.c
LOCAL_SHARED_LIBRARIES := libcutils
# we don't want this in 'user' builds which don't have
# emulator-specific binaries.
LOCAL_MODULE_TAGS := debug
include $(BUILD_EXECUTABLE)
endif # TARGET_PRODUCT != sim

114
emulator/tools/qemu-props.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* this program is used to read a set of system properties and their values
* from the emulator program and set them in the currently-running emulated
* system. It does so by connecting to the 'boot-properties' qemud service.
*
* This program should be run as root and called from
* /system/etc/init.goldfish.rc exclusively.
*/
#define LOG_TAG "qemu-props"
#define DEBUG 1
#if DEBUG
# include <cutils/log.h>
# define DD(...) LOGI(__VA_ARGS__)
#else
# define DD(...) ((void)0)
#endif
#include <cutils/properties.h>
#include <unistd.h>
#include <hardware/qemud.h>
/* Name of the qemud service we want to connect to.
*/
#define QEMUD_SERVICE "boot-properties"
#define MAX_TRIES 5
int main(void)
{
int qemud_fd, count = 0;
/* try to connect to the qemud service */
{
int tries = MAX_TRIES;
while (1) {
qemud_fd = qemud_channel_open( "boot-properties" );
if (qemud_fd >= 0)
break;
if (--tries <= 0) {
DD("Could not connect after too many tries. Aborting");
return 1;
}
DD("waiting 1s to wait for qemud.");
sleep(1);
}
}
DD("connected to '%s' qemud service.", QEMUD_SERVICE);
/* send the 'list' command to the service */
if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
DD("could not send command to '%s' service", QEMUD_SERVICE);
return 1;
}
/* read each system property as a single line from the service,
* until exhaustion.
*/
for (;;)
{
#define BUFF_SIZE (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
char* q;
char temp[BUFF_SIZE];
int len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);
if (len < 0 || len > BUFF_SIZE-1)
break;
temp[len] = '\0'; /* zero-terminate string */
DD("received: %.*s", len, temp);
/* separate propery name from value */
q = strchr(temp, '=');
if (q == NULL) {
DD("invalid format, ignored.");
continue;
}
*q++ = '\0';
if (property_set(temp, q) < 0) {
DD("could not set property '%s' to '%s'", temp, q);
} else {
count += 1;
}
}
/* finally, close the channel and exit */
close(qemud_fd);
DD("exiting (%d properties set).", count);
return 0;
}

View File

@@ -34,6 +34,7 @@
<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
<classpathentry kind="src" path="frameworks/base/core/java"/>
<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
<classpathentry kind="src" path="frameworks/base/im/java"/>
<classpathentry kind="src" path="frameworks/base/location/java"/>
@@ -45,6 +46,7 @@
<classpathentry kind="src" path="frameworks/base/services/java"/>
<classpathentry kind="src" path="frameworks/base/telephony/java"/>
<classpathentry kind="src" path="frameworks/base/test-runner"/>
<classpathentry kind="src" path="frameworks/base/tts/java"/>
<classpathentry kind="src" path="frameworks/base/wifi/java"/>
<classpathentry kind="src" path="frameworks/policies/base/phone"/>
<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
@@ -62,6 +64,7 @@
<classpathentry kind="src" path="development/samples/SkeletonApp/tests/src"/>
<classpathentry kind="src" path="development/samples/Snake/src"/>
<classpathentry kind="src" path="development/samples/Snake/tests/src"/>
<classpathentry kind="src" path="development/apps/Term/src"/>
<classpathentry kind="src" path="dalvik/libcore/annotation/src/main/java"/>
<classpathentry kind="src" path="dalvik/libcore/archive/src/main/java"/>
<classpathentry kind="src" path="dalvik/libcore/auth/src/main/java"/>
@@ -99,6 +102,7 @@
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/tts/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java"/>
<classpathentry kind="src" path="out/target/common/R"/>
<classpathentry kind="src" path="external/tagsoup/src"/>

5
ndk/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
build/prebuilt
out
apps/*/project/libs
.gitignore

3
ndk/Android.mk Normal file
View File

@@ -0,0 +1,3 @@
# Please keep this file empty. It is only used to avoid breaking the Android build
# when the NDK sources are stored in the git repository alongside the rest of the
# platform.

18
ndk/GNUmakefile Normal file
View File

@@ -0,0 +1,18 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# DO NOT MODIFY THIS FILE
include build/core/main.mk
# END OF FILE

33
ndk/README.TXT Normal file
View File

@@ -0,0 +1,33 @@
Android Native Development Kit (NDK)
Welcome, this NDK is designed to allow Android application developers
to include native code in their Android application packages, compiled
as JNI shared libraries.
A high-level overview of the NDK's features and limitations can be found
in docs/OVERVIEW.TXT. Please read this document as it contains crucial
information for correct usage.
See docs/STABLE-APIS.TXT for the list of frozen binary APIs exposed by
this NDK, as well as the corresponding system image versions that support
them.
Before using the NDK, you will need to follow the steps described by
docs/INSTALL.TXT which lists the NDK pre-requisites and the steps needed
to set it up properly on your machine.
We recommend developers to make themselves familiar with JNI concepts. Also
note that the NDK is *not* a good way to write non-JNI native code for the
Android platform.
See docs/HOWTO.TXT for a few useful tips and tricks when using the NDK.
See docs/SYSTEM-ISSUES.TXT for a list of important issues related to
the Android system images that all NDK developers should be aware of.
Finally, discussions related to the Android NDK happen on the public
"android-ndk" forum located at the following address:
http://groups.google.com/group/android-ndk

View File

@@ -0,0 +1,2 @@
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := hello-jni

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hellojni"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" />
<application android:label="@string/app_name">
<activity android:name=".HelloJni"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-3

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HelloJni</string>
</resources>

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.hellojni;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class HelloJni extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* Create a TextView and set its content.
* the text is retrieved by calling a native
* function.
*/
TextView tv = new TextView(this);
tv.setText( stringFromJNI() );
setContentView(tv);
}
/* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native String stringFromJNI();
/* This is another native method declaration that is *not*
* implemented by 'hello-jni'. This is simply to show that
* you can declare as many native methods in your Java code
* as you want, their implementation is searched in the
* currently loaded native libraries only the first time
* you call them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
public native String unimplementedStringFromJNI();
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.HelloJni/lib/libhello-jni.so at
* installation time by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.HelloJni.tests"
android:versionCode="1"
android:versionName="1.0">
<!-- We add an application tag here just so that we can indicate that
this package needs to link against the android.test library,
which is needed when building test cases. -->
<application>
<uses-library android:name="android.test.runner" />
</application>
<!--
This declares that this application uses the instrumentation test runner targeting
the package of com.example.HelloJni. To run the tests use the command:
"adb shell am instrument -w com.example.HelloJni.tests/android.test.InstrumentationTestRunner"
-->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.HelloJni"
android:label="Tests for HelloJni"/>
</manifest>

View File

@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-3

View File

@@ -0,0 +1,21 @@
package com.example.HelloJni;
import android.test.ActivityInstrumentationTestCase;
/**
* This is a simple framework for a test of an Application. See
* {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
* how to write and extend Application tests.
* <p/>
* To run this test, you can type:
* adb shell am instrument -w \
* -e class com.example.HelloJni.HelloJniTest \
* com.example.HelloJni.tests/android.test.InstrumentationTestRunner
*/
public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> {
public HelloJniTest() {
super("com.example.HelloJni", HelloJni.class);
}
}

View File

@@ -0,0 +1,2 @@
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := twolib-first twolib-second

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.twolibs"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" />
<application android:label="@string/app_name">
<activity android:name=".TwoLibs"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-3

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TwoLib</string>
</resources>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007 The Android Open Source Project
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,31 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.platform_library.client;
import com.example.android.platform_library.PlatformLibrary;
package com.example.twolibs;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.os.Bundle;
/**
* Use a custom platform library.
*/
public class Client extends Activity {
public class TwoLibs extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Call an API on the library.
PlatformLibrary pl = new PlatformLibrary();
int res = pl.getInt(false);
TextView tv = new TextView(this);
int x = 1000;
int y = 42;
// We'll just make our own view to show the result.
TextView tv = new TextView(this);
tv.setText("Got from lib: " + res);
// here, we dynamically load the library at runtime
// before calling the native method.
//
System.loadLibrary("twolib-second");
int z = add(x, y);
tv.setText( "The sum of " + x + " and " + y + " is " + z );
setContentView(tv);
}
}
public native int add(int x, int y);
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.TwoLib.tests"
android:versionCode="1"
android:versionName="1.0">
<!-- We add an application tag here just so that we can indicate that
this package needs to link against the android.test library,
which is needed when building test cases. -->
<application>
<uses-library android:name="android.test.runner" />
</application>
<!--
This declares that this application uses the instrumentation test runner targeting
the package of com.example.TwoLib. To run the tests use the command:
"adb shell am instrument -w com.example.TwoLib.tests/android.test.InstrumentationTestRunner"
-->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.TwoLib"
android:label="Tests for TwoLib"/>
</manifest>

View File

@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-3

View File

@@ -0,0 +1,21 @@
package com.example.TwoLib;
import android.test.ActivityInstrumentationTestCase;
/**
* This is a simple framework for a test of an Application. See
* {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
* how to write and extend Application tests.
* <p/>
* To run this test, you can type:
* adb shell am instrument -w \
* -e class com.example.TwoLib.TwoLibTest \
* com.example.TwoLib.tests/android.test.InstrumentationTestRunner
*/
public class TwoLibTest extends ActivityInstrumentationTestCase<TwoLib> {
public TwoLibTest() {
super("com.example.TwoLib", TwoLib.class);
}
}

View File

@@ -0,0 +1,62 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this script is used to record an application definition in the
# NDK build system, before performing any build whatsoever.
#
# It is included repeatedly from build/core/main.mk and expects a
# variable named '_application_mk' which points to a given Application.mk
# file that will be included here. The latter must define a few variables
# to describe the application to the build system, and the rest of the
# code here will perform book-keeping and basic checks
#
$(call assert-defined, _application_mk)
$(call clear-vars, $(NDK_APP_VARS))
include $(_application_mk)
$(call check-required-vars,$(NDK_APP_VARS_REQUIRED),$(_application_mk))
# strip the 'lib' prefix in front of APP_MODULES modules
APP_MODULES := $(call strip-lib-prefix,$(APP_MODULES))
# check that APP_OPTIM, if defined, is either 'release' or 'debug'
$(if $(filter-out release debug,$(APP_OPTIM)),\
$(call __ndk_info, The APP_OPTIM defined in $(_application_mk) must only be 'release' or 'debug')\
$(call __ndk_error,Aborting)\
)
_dir := $(patsubst %/,%,$(dir $(_application_mk)))
_name := $(notdir $(_dir))
_app := NDK_APP.$(_name)
$(if $(strip $(APP.$(_app).defined)),\
$(call __ndk_info,Weird, the application $(_name) is already defined by $(APP.$(_app).defined))\
$(call __ndk_error,Aborting)\
)
APP.$(_app).defined := $(_application_mk)
# Record all app-specific variable definitions
$(foreach __name,$(NDK_APP_VARS),\
$(eval $(_app).$(__name) := $($(__name)))\
)
# Record the Application.mk for debugging
$(_app).Application.mk := $(_application_mk)
NDK_ALL_APPS += $(_name)

View File

@@ -0,0 +1,65 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this script is included repeatedly by main.mk to add a new toolchain
# definition to the NDK build system.
#
# 'toolchain_config' must be defined as the path of a toolchain
# configuration file (config.mk) that will be included here.
#
$(call assert-defined, _config_mk)
# The list of variables that must or may be defined
# by the toolchain configuration file
#
NDK_TOOLCHAIN_VARS_REQUIRED := TOOLCHAIN_ABIS
NDK_TOOLCHAIN_VARS_OPTIONAL :=
# Clear variables that are supposed to be defined by the config file
$(call clear-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED))
$(call clear-vars,$(NDK_TOOLCHAIN_VARS_OPTIONAL))
# Include the config file
include $(_config_mk)
# Check that the proper variables were defined
$(call check-required-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED),$(_config_mk))
# Check that the file didn't do something stupid
$(call assert-defined, _config_mk)
# Now record the toolchain-specific informatio
_dir := $(patsubst %/,%,$(dir $(_config_mk)))
_name := $(notdir $(_dir))
_abis := $(TOOLCHAIN_ABIS)
_toolchain := NDK_TOOLCHAIN.$(_name)
# check that the toolchain name is unique
$(if $(strip $($(_toolchain).defined)),\
$(call __ndk_error,Toolchain $(_name) defined in $(_parent) is\
already defined in $(NDK_TOOLCHAIN.$(_name).defined)))
$(_toolchain).defined := $(_toolchain_config)
$(_toolchain).abis := $(_abis)
$(_toolchain).setup := $(wildcard $(_dir)/setup.mk)
$(if $(strip $($(_toolchain).setup)),,\
$(call __ndk_error, Toolchain $(_name) lacks a setup.mk in $(_dir)))
NDK_ALL_TOOLCHAINS += $(_name)
NDK_ALL_ABIS += $(_abis)
# done

View File

@@ -0,0 +1,173 @@
# Copyright (C) 2008 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.
#
# we expect the 'my' variable to be defined, either to
# 'HOST_' or 'TARGET_', and this allows us to call the
# appropriate compiler with $($(my)CC)
#
$(call assert-defined,my)
# LOCAL_MAKEFILE must also exist and name the Android.mk that
# included the module build script.
#
$(call assert-defined,LOCAL_MAKEFILE)
include $(BUILD_SYSTEM)/build-module.mk
# list of generated object files
LOCAL_OBJECTS :=
# always define ANDROID when building binaries
#
LOCAL_CFLAGS := -DANDROID $(LOCAL_CFLAGS)
#
# Add the default system shared libraries to the build
#
ifndef LOCAL_IS_HOST_MODULE
ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
LOCAL_SHARED_LIBRARIES += $(TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES)
else
LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
endif
endif
#
# Check LOCAL_CPP_EXTENSION, use '.cpp' by default
#
LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION))
ifeq ($(LOCAL_CPP_EXTENSION),)
LOCAL_CPP_EXTENSION := .cpp
else
ifneq ($(words $(LOCAL_CPP_EXTENSION)),1)
$(call __ndk_info, LOCAL_CPP_EXTENSION in $(LOCAL_MAKEFILE) must be one word only, not '$(LOCAL_CPP_EXTENSION)')
$(call __ndk_error, Aborting)
endif
endif
#
# If LOCAL_ALLOW_UNDEFINED_SYMBOLS, the linker will allow the generation
# of a binary that uses undefined symbols.
#
ifeq ($(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)),)
LOCAL_LDFLAGS := $(LOCAL_LDFLAGS) $($(my)NO_UNDEFINED_LDFLAGS)
endif
#
# The original Android build system allows you to use the .arm prefix
# to a source file name to indicate that it should be defined in either
# 'thumb' or 'arm' mode, depending on the value of LOCAL_ARM_MODE
#
# First, check LOCAL_ARM_MODE, it should be empty, 'thumb' or 'arm'
# We make the default 'thumb'
#
LOCAL_ARM_MODE := $(strip $(LOCAL_ARM_MODE))
ifeq ($(LOCAL_ARM_MODE),)
LOCAL_ARM_MODE := thumb
else
ifneq ($(words $(LOCAL_ARM_MODE)),1)
$(call __ndk_info, LOCAL_ARM_MODE in $(LOCAL_MAKEFILE) must be one word, not '$(LOCAL_ARM_MODE)')
$(call __ndk_error, Aborting)
endif
# check that LOCAL_ARM_MODE is defined to either 'arm' or 'thumb'
$(if $(filter-out thumb arm, $(LOCAL_ARM_MODE)),\
$(call __ndk_info, LOCAL_ARM_MODE must be defined to either 'arm' or 'thumb' in $(LOCAL_MAKEFILE) not '$(LOCAL_ARM_MODE)')\
$(call __ndk_error, Aborting)\
)
endif
LOCAL_ARM_TEXT_arm = arm$(space)$(space)
LOCAL_ARM_TEXT_thumb = thumb
LOCAL_ARM_CFLAGS := $(TARGET_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS)
LOCAL_ARM_TEXT := $(LOCAL_ARM_TEXT_$(LOCAL_ARM_MODE))
# As a special case, the original Android build system
# allows one to specify that certain source files can be
# forced to build in ARM mode by using a '.arm' suffix
# after the extension, e.g.
#
# LOCAL_SRC_FILES := foo.c.arm
#
# to build source file $(LOCAL_PATH)/foo.c as ARM
#
#
# Build C source files into .o
#
ifeq ($(LOCAL_ARM_MODE),arm)
arm_sources := $(LOCAL_SRC_FILES)
else
arm_sources := $(filter %.arm,$(LOCAL_SRC_FILES))
thumb_sources := $(filter-out %.arm,$(LOCAL_SRC_FILES))
endif
# First, build the 'thumb' sources
#
LOCAL_ARM_MODE := thumb
$(foreach src,$(filter %.c,$(thumb_sources)), $(call compile-c-source,$(src)))
$(foreach src,$(filter %.S,$(thumb_sources)), $(call compile-s-source,$(src)))
$(foreach src,$(filter %$(LOCAL_CPP_EXTENSION),$(thumb_sources)),\
$(call compile-cpp-source,$(src)))
# Then, the 'ARM' ones
#
LOCAL_ARM_MODE := arm
arm_sources := $(arm_sources:%.arm=%)
$(foreach src,$(filter %.c,$(arm_sources)), $(call compile-c-source,$(src)))
$(foreach src,$(filter %.S,$(arm_sources)), $(call compile-s-source,$(src)))
$(foreach src,$(filter %$(LOCAL_CPP_EXTENSION),$(arm_sources)),\
$(call compile-cpp-source,$(src)))
#
# The compile-xxx-source calls updated LOCAL_OBJECTS and LOCAL_DEPENDENCY_DIRS
#
ALL_DEPENDENCY_DIRS += $(sort $(LOCAL_DEPENDENCY_DIRS))
CLEAN_OBJS_DIRS += $(LOCAL_OBJS_DIR)
#
# Handle the static and shared libraries this module depends on
#
LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
LOCAL_SHARED_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_SHARED_LIBRARIES))
static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
shared_libraries := $(call map,shared-library-path,$(LOCAL_SHARED_LIBRARIES)) \
$(TARGET_PREBUILT_SHARED_LIBRARIES)
$(LOCAL_BUILT_MODULE): $(static_libraries) $(shared_libraries)
# If LOCAL_LDLIBS contains anything like -l<library> then
# prepend a -L$(SYSROOT)/usr/lib to it to ensure that the linker
# looks in the right location
#
ifneq ($(filter -l%,$(LOCAL_LDLIBS)),)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib $(LOCAL_LDLIBS)
endif
$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS := $(LOCAL_OBJECTS)
$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(TARGET_LDFLAGS) $(LOCAL_LDFLAGS)
$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS := $(LOCAL_LDLIBS) $(TARGET_LDLIBS)
$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))

View File

@@ -0,0 +1,47 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this file is included from Android.mk files to build a target-specific
# executable program
#
LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE
LOCAL_MODULE_CLASS := EXECUTABLE
LOCAL_MAKEFILE := $(local-makefile)
$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
# only adjust the build if this module is needed by the current app
ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
# we are building target objects
my := TARGET_
LOCAL_BUILT_MODULE := $(call executable-path,$(LOCAL_MODULE))
LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE)
include $(BUILD_SYSTEM)/build-binary.mk
$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
@ mkdir -p $(dir $@)
@ echo "Executable : $(PRIVATE_NAME)"
$(hide) $(cmd-build-executable)
ALL_EXECUTABLES += $(LOCAL_BUILT_MODULE)
include $(BUILD_SYSTEM)/install-binary.mk
endif # filter LOCAL_MODULE in NDK_APP_MODULES

View File

@@ -0,0 +1,78 @@
# Copyright (C) 2008 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.
#
#
# Base rules shared to control the build of all modules.
# This should be included from build-binary.mk
#
$(call assert-defined,LOCAL_MODULE_CLASS LOCAL_BUILD_SCRIPT LOCAL_BUILT_MODULE)
# Check LOCAL_IS_HOST_MODULE and define 'my' as either HOST_ or TARGET_
#
LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
ifdef LOCAL_IS_HOST_MODULE
ifneq ($(LOCAL_IS_HOST_MODULE),true)
$(call __ndk_log,$(LOCAL_PATH): LOCAL_IS_HOST_MODULE must be "true" or empty, not "$(LOCAL_IS_HOST_MODULE)")
endif
my := HOST_
else
my := TARGET_
endif
# Compute 'intermediates' which is the location where we're going to store
# intermediate generated files like object (.o) files.
#
intermediates := $($(my)OBJS)
# LOCAL_INTERMEDIATES lists the targets that are generated by this module
#
LOCAL_INTERMEDIATES := $(LOCAL_BUILT_MODULE)
# LOCAL_BUILD_MODE will be either release or debug
#
ifneq ($(NDK_APP_OPTIM),)
LOCAL_BUILD_MODE := $(NDK_APP_OPTIM)
else
LOCAL_BUILD_MODE := release
endif
#
# Ensure that 'make <module>' and 'make clean-<module>' work
#
.PHONY: $(LOCAL_MODULE)
$(LOCAL_MODULE): $(LOCAL_BUILT_MODULE)
cleantarget := clean-$(LOCAL_MODULE)
.PHONY: $(cleantarget)
clean: $(cleantarget)
$(cleantarget): PRIVATE_MODULE := $(LOCAL_MODULE)
$(cleantarget): PRIVATE_CLEAN_FILES := $(PRIVATE_CLEAN_FILES) \
$(LOCAL_BUILT_MODULE) \
$(LOCAL_INSTALLED_MODULE) \
$(intermediates)
$(cleantarget)::
@echo "Clean: $(PRIVATE_MODULE)"
$(hide) rm -rf $(PRIVATE_CLEAN_FILES)
#
# Register module
#
ALL_MODULES += $(LOCAL_MODULE)

View File

@@ -0,0 +1,47 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this file is included from Android.mk files to build a target-specific
# shared library
#
LOCAL_BUILD_SCRIPT := BUILD_SHARED_LIBRARY
LOCAL_MODULE_CLASS := SHARED_LIBRARY
LOCAL_MAKEFILE := $(local-makefile)
$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
# only adjust the build if this module is needed by the current app
ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
# we are building target objects
my := TARGET_
LOCAL_BUILT_MODULE := $(call shared-library-path,$(LOCAL_MODULE))
LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE)
include $(BUILD_SYSTEM)/build-binary.mk
$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
@ mkdir -p $(dir $@)
@ echo "SharedLibrary : $(PRIVATE_NAME)"
$(hide) $(cmd-build-shared-library)
ALL_SHARED_LIBRARIES += $(LOCAL_BUILT_MODULE)
include $(BUILD_SYSTEM)/install-binary.mk
endif # filter LOCAL_MODULE in NDK_APP_MODULES

View File

@@ -0,0 +1,46 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this file is included from Android.mk files to build a target-specific
# static library
#
LOCAL_BUILD_SCRIPT := BUILD_STATIC_LIBRARY
LOCAL_MODULE_CLASS := STATIC_LIBRARY
LOCAL_MAKEFILE := $(local-makefile)
$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
# only adjust the build if this module is needed by the current app
ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
# we are building target objects
my := TARGET_
LOCAL_BUILT_MODULE := $(call static-library-path,$(LOCAL_MODULE))
LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE)
include $(BUILD_SYSTEM)/build-binary.mk
$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
@ mkdir -p $(dir $@)
@ echo "StaticLibrary : $(PRIVATE_NAME)"
$(hide) rm -rf $@
$(hide) $(cmd-build-static-library)
ALL_STATIC_LIBRARIES += $(LOCAL_BUILT_MODULE)
endif # filter LOCAL_MODULE in NDK_APP_MODULES

View File

@@ -0,0 +1,37 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# this file is included repeatedly from Android.mk files in order to clean
# the module-specific variables from the environment,
NDK_LOCAL_VARS := \
LOCAL_MODULE \
LOCAL_SRC_FILES \
LOCAL_C_INCLUDES \
LOCAL_CFLAGS \
LOCAL_CXXFLAGS \
LOCAL_CPPFLAGS \
LOCAL_LDFLAGS \
LOCAL_ARFLAGS \
LOCAL_CPP_EXTENSION \
LOCAL_STATIC_LIBRARIES \
LOCAL_STATIC_WHOLE_LIBRARIES \
LOCAL_SHARED_LIBRARIES \
LOCAL_MAKEFILE \
LOCAL_NO_UNDEFINED_SYMBOLS \
LOCAL_ARM_MODE \
$(call clear-vars, $(NDK_LOCAL_VARS))

View File

@@ -0,0 +1,483 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Common definitions for the Android NDK build system
#
# We use the GNU Make Standard Library
include build/gmsl/gmsl
# This is the Android NDK version number as a list of three items:
# major, minor, revision
#
ndk_version := 1 0 0
# Used to output warnings and error from the library, it's possible to
# disable any warnings or errors by overriding these definitions
# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
__ndk_name := Android NDK
__ndk_info = $(info $(__ndk_name): $1 $2 $3 $4 $5)
__ndk_warning = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
__ndk_error = $(error $(__ndk_name): $1 $2 $3 $4 $5)
ifdef NDK_NO_WARNINGS
__ndk_warning :=
endif
ifdef NDK_NO_ERRORS
__ndk_error :=
endif
# If NDK_TRACE is enabled then calls to the library functions are
# traced to stdout using warning messages with their arguments
ifdef NDK_TRACE
__ndk_tr1 = $(warning $0('$1'))
__ndk_tr2 = $(warning $0('$1','$2'))
__ndk_tr3 = $(warning $0('$1','$2','$3'))
else
__ndk_tr1 :=
__ndk_tr2 :=
__ndk_tr3 :=
endif
# -----------------------------------------------------------------------------
# Function : ndk_log
# Arguments: 1: text to print when NDK_LOG is defined
# Returns : None
# Usage : $(call ndk_log,<some text>)
# -----------------------------------------------------------------------------
ifdef NDK_LOG
ndk_log = $(info $(__ndk_name): $1)
else
ndk_log :=
endif
# -----------------------------------------------------------------------------
# Macro : empty
# Returns : an empty macro
# Usage : $(empty)
# -----------------------------------------------------------------------------
empty :=
# -----------------------------------------------------------------------------
# Macro : space
# Returns : a single space
# Usage : $(space)
# -----------------------------------------------------------------------------
space := $(empty) $(empty)
# -----------------------------------------------------------------------------
# Function : last2
# Arguments: a list
# Returns : the penultimate (next-to-last) element of a list
# Usage : $(call last2, <LIST>)
# -----------------------------------------------------------------------------
last2 = $(word $(words $1), x $1)
# -----------------------------------------------------------------------------
# Function : last3
# Arguments: a list
# Returns : the antepenultimate (second-next-to-last) element of a list
# Usage : $(call last3, <LIST>)
# -----------------------------------------------------------------------------
last3 = $(word $(words $1), x x $1)
# -----------------------------------------------------------------------------
# Macro : this-makefile
# Returns : the name of the current Makefile in the inclusion stack
# Usage : $(this-makefile)
# -----------------------------------------------------------------------------
this-makefile = $(lastword $(MAKEFILE_LIST))
# -----------------------------------------------------------------------------
# Macro : local-makefile
# Returns : the name of the last parsed Android.mk file
# Usage : $(local-makefile)
# -----------------------------------------------------------------------------
local-makefile = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST)))
# -----------------------------------------------------------------------------
# Function : assert-defined
# Arguments: 1: list of variable names
# Returns : None
# Usage : $(call assert-defined, VAR1 VAR2 VAR3...)
# Rationale: Checks that all variables listed in $1 are defined, or abort the
# build
# -----------------------------------------------------------------------------
assert-defined = $(foreach __varname,$(strip $1),\
$(if $(strip $($(__varname))),,\
$(call __ndk_error, Assertion failure: $(__varname) is not defined)\
)\
)
# -----------------------------------------------------------------------------
# Function : clear-vars
# Arguments: 1: list of variable names
# 2: file where the variable should be defined
# Returns : None
# Usage : $(call clear-vars, VAR1 VAR2 VAR3...)
# Rationale: Clears/undefines all variables in argument list
# -----------------------------------------------------------------------------
clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty)))
# -----------------------------------------------------------------------------
# Function : check-required-vars
# Arguments: 1: list of variable names
# 2: file where the variable(s) should be defined
# Returns : None
# Usage : $(call check-required-vars, VAR1 VAR2 VAR3..., <file>)
# Rationale: Checks that all required vars listed in $1 were defined by $2
# or abort the build with an error
# -----------------------------------------------------------------------------
check-required-vars = $(foreach __varname,$1,\
$(if $(strip $($(__varname))),,\
$(call __ndk_info, Required variable $(__varname) is not defined by $2)\
$(call __ndk_error,Aborting)\
)\
)
# -----------------------------------------------------------------------------
# Function : modules-clear
# Arguments: None
# Returns : None
# Usage : $(call modules-clear)
# Rationale: clears the list of defined modules known by the build system
# -----------------------------------------------------------------------------
modules-clear = $(eval __ndk_modules := $(empty_set))
# -----------------------------------------------------------------------------
# Function : modules-add
# Arguments: 1: module name
# 2: path to Android.mk where the module is defined
# Returns : None
# Usage : $(call modules-add,<modulename>,<Android.mk path>)
# Rationale: add a new module. If it is already defined, print an error message
# and abort.
# -----------------------------------------------------------------------------
modules-add = \
$(if $(call set_is_member,$(__ndk_modules),$1),\
$(call __ndk_info,Trying to define local module '$1' in $2.)\
$(call __ndk_info,But this module was already defined by $(__ndk_modules.$1).)\
$(call __ndk_error,Aborting.)\
)\
$(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\
$(eval __ndk_modules.$1 := $2)\
# -----------------------------------------------------------------------------
# Function : check-user-define
# Arguments: 1: name of variable that must be defined by the user
# 2: name of Makefile where the variable should be defined
# 3: name/description of the Makefile where the check is done, which
# must be included by $2
# Returns : None
# -----------------------------------------------------------------------------
check-user-define = $(if $(strip $($1)),,\
$(call __ndk_error,Missing $1 before including $3 in $2))
# -----------------------------------------------------------------------------
# This is used to check that LOCAL_MODULE is properly defined by an Android.mk
# file before including one of the $(BUILD_SHARED_LIBRARY), etc... files.
#
# Function : check-user-LOCAL_MODULE
# Arguments: 1: name/description of the included build Makefile where the
# check is done
# Returns : None
# Usage : $(call check-user-LOCAL_MODULE, BUILD_SHARED_LIBRARY)
# -----------------------------------------------------------------------------
check-defined-LOCAL_MODULE = \
$(call check-user-define,LOCAL_MODULE,$(local-makefile),$(1)) \
$(if $(call seq,$(words $(LOCAL_MODULE)),1),,\
$(call __ndk_info,LOCAL_MODULE definition in $(local-makefile) must not contain space)\
$(call __ndk_error,Please correct error. Aborting)\
)
# -----------------------------------------------------------------------------
# Strip any 'lib' prefix in front of a given string.
#
# Function : strip-lib-prefix
# Arguments: 1: module name
# Returns : module name, without any 'lib' prefix if any
# Usage : $(call strip-lib-prefix,$(LOCAL_MODULE))
# -----------------------------------------------------------------------------
strip-lib-prefix = $(1:lib%=%)
# -----------------------------------------------------------------------------
# This is used to strip any lib prefix from LOCAL_MODULE, then check that
# the corresponding module name is not already defined.
#
# Function : check-user-LOCAL_MODULE
# Arguments: 1: path of Android.mk where this LOCAL_MODULE is defined
# Returns : None
# Usage : $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
# -----------------------------------------------------------------------------
check-LOCAL_MODULE = \
$(eval LOCAL_MODULE := $$(call strip-lib-prefix,$$(LOCAL_MODULE)))\
$(call modules-add,$(LOCAL_MODULE),$1)
# -----------------------------------------------------------------------------
# Macro : my-dir
# Returns : the directory of the current Makefile
# Usage : $(my-dir)
# -----------------------------------------------------------------------------
my-dir = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
# -----------------------------------------------------------------------------
# Function : all-makefiles-under
# Arguments: 1: directory path
# Returns : a list of all makefiles immediately below some directory
# Usage : $(call all-makefiles-under, <some path>)
# -----------------------------------------------------------------------------
all-makefiles-under = $(wildcard $1/*/Android.mk)
# -----------------------------------------------------------------------------
# Macro : all-subdir-makefiles
# Returns : list of all makefiles in subdirectories of the current Makefile's
# location
# Usage : $(all-subdir-makefiles)
# -----------------------------------------------------------------------------
all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir))
# =============================================================================
#
# Application.mk support
#
# =============================================================================
# the list of variables that *must* be defined in Application.mk files
NDK_APP_VARS_REQUIRED := APP_MODULES APP_PROJECT_PATH
# the list of variables that *may* be defined in Application.mk files
NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS
# the list of all variables that may appear in an Application.mk file
NDK_APP_VARS := $(NDK_APP_VARS_REQUIRED) $(NDK_APP_VARS_OPTIONAL)
# =============================================================================
#
# Android.mk support
#
# =============================================================================
# =============================================================================
#
# Generated files support
#
# =============================================================================
# -----------------------------------------------------------------------------
# Function : host-static-library-path
# Arguments : 1: library module name (e.g. 'foo')
# Returns : location of generated host library name (e.g. '..../libfoo.a)
# Usage : $(call host-static-library-path,<modulename>)
# -----------------------------------------------------------------------------
host-static-library-path = $(HOST_OUT)/lib$1.a
# -----------------------------------------------------------------------------
# Function : host-executable-path
# Arguments : 1: executable module name (e.g. 'foo')
# Returns : location of generated host executable name (e.g. '..../foo)
# Usage : $(call host-executable-path,<modulename>)
# -----------------------------------------------------------------------------
host-executable-path = $(HOST_OUT)/$1$(HOST_EXE)
# -----------------------------------------------------------------------------
# Function : static-library-path
# Arguments : 1: library module name (e.g. 'foo')
# Returns : location of generated static library name (e.g. '..../libfoo.a)
# Usage : $(call static-library-path,<modulename>)
# -----------------------------------------------------------------------------
static-library-path = $(TARGET_OUT)/lib$1.a
# -----------------------------------------------------------------------------
# Function : shared-library-path
# Arguments : 1: library module name (e.g. 'foo')
# Returns : location of generated shared library name (e.g. '..../libfoo.so)
# Usage : $(call shared-library-path,<modulename>)
# -----------------------------------------------------------------------------
shared-library-path = $(TARGET_OUT)/lib$1.so
# -----------------------------------------------------------------------------
# Function : executable-path
# Arguments : 1: executable module name (e.g. 'foo')
# Returns : location of generated exectuable name (e.g. '..../foo)
# Usage : $(call executable-path,<modulename>)
# -----------------------------------------------------------------------------
executable-path = $(TARGET_OUT)/$1
# =============================================================================
#
# Build commands support
#
# =============================================================================
# -----------------------------------------------------------------------------
# Macro : hide
# Returns : nothing
# Usage : $(hide)<make commands>
# Rationale: To be used as a prefix for Make build commands to hide them
# by default during the build. To show them, set V=1 in your
# environment or command-line.
#
# For example:
#
# foo.o: foo.c
# -->|$(hide) <build-commands>
#
# Where '-->|' stands for a single tab character.
#
# -----------------------------------------------------------------------------
ifeq ($(V),1)
hide = $(empty)
else
hide = @
endif
# -----------------------------------------------------------------------------
# Template : ev-compile-c-source
# Arguments : 1: single C source file name (relative to LOCAL_PATH)
# 2: target object file (without path)
# Returns : None
# Usage : $(eval $(call ev-compile-c-source,<srcfile>,<objfile>)
# Rationale : Internal template evaluated by compile-c-source and
# compile-s-source
# -----------------------------------------------------------------------------
define ev-compile-c-source
_SRC:=$$(LOCAL_PATH)/$(1)
_OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
$$(_OBJ): PRIVATE_SRC := $$(_SRC)
$$(_OBJ): PRIVATE_OBJ := $$(_OBJ)
$$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
$$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE)
$$(_OBJ): PRIVATE_ARM_TEXT := $$(LOCAL_ARM_TEXT)
$$(_OBJ): PRIVATE_CC := $$($$(my)CC)
$$(_OBJ): PRIVATE_CFLAGS := $$($$(my)CFLAGS) \
$$($$(my)$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \
$$(LOCAL_C_INCLUDES:%=-I%) \
-I$$(LOCAL_PATH) \
$$(LOCAL_CFLAGS) \
$$(NDK_APP_CPPFLAGS) \
$$(NDK_APP_CFLAGS)
$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
@mkdir -p $$(dir $$(PRIVATE_OBJ))
@echo "Compile $$(PRIVATE_ARM_TEXT) : $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)"
$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c \
-MMD -MP -MF $$(PRIVATE_OBJ).d.tmp \
$$(PRIVATE_SRC) \
-o $$(PRIVATE_OBJ)
$$(call cmd-process-deps,$$(PRIVATE_OBJ))
LOCAL_OBJECTS += $$(_OBJ)
LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ))
endef
# -----------------------------------------------------------------------------
# Function : compile-c-source
# Arguments : 1: single C source file name (relative to LOCAL_PATH)
# Returns : None
# Usage : $(call compile-c-source,<srcfile>)
# Rationale : Setup everything required to build a single C source file
# -----------------------------------------------------------------------------
compile-c-source = $(eval $(call ev-compile-c-source,$1,$(1:%.c=%.o)))
# -----------------------------------------------------------------------------
# Function : compile-s-source
# Arguments : 1: single Assembly source file name (relative to LOCAL_PATH)
# Returns : None
# Usage : $(call compile-s-source,<srcfile>)
# Rationale : Setup everything required to build a single Assembly source file
# -----------------------------------------------------------------------------
compile-s-source = $(eval $(call ev-compile-s-source,$1,$(1:%.S=%.o)))
# -----------------------------------------------------------------------------
# Template : ev-compile-cpp-source
# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
# 2: target object file (without path)
# Returns : None
# Usage : $(eval $(call ev-compile-cpp-source,<srcfile>,<objfile>)
# Rationale : Internal template evaluated by compile-cpp-source
# -----------------------------------------------------------------------------
define ev-compile-cpp-source
_SRC:=$$(LOCAL_PATH)/$(1)
_OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
$$(_OBJ): PRIVATE_SRC := $$(_SRC)
$$(_OBJ): PRIVATE_OBJ := $$(_OBJ)
$$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
$$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE)
$$(_OBJ): PRIVATE_ARM_TEXT := $$(LOCAL_ARM_TEXT)
$$(_OBJ): PRIVATE_CXX := $$($$(my)CXX)
$$(_OBJ): PRIVATE_CXXFLAGS := $$($$(my)CXXFLAGS) \
$$($$(my)$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \
$$(LOCAL_C_INCLUDES:%=-I%) \
-I$$(LOCAL_PATH) \
$$(LOCAL_CFLAGS) \
$$(NDK_APP_CPPFLAGS) \
$$(NDK_APP_CXXFLAGS) \
$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
@mkdir -p $$(dir $$(PRIVATE_OBJ))
@echo "Compile++ $$(PRIVATE_ARM_TEXT): $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)"
$(hide) $$(PRIVATE_CXX) $$(PRIVATE_CXXFLAGS) -c \
-MMD -MP -MF $$(PRIVATE_OBJ).d.tmp \
$$(PRIVATE_SRC) \
-o $$(PRIVATE_OBJ)
$$(call cmd-process-deps,$$(PRIVATE_OBJ))
LOCAL_OBJECTS += $$(_OBJ)
LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ))
endef
# -----------------------------------------------------------------------------
# Function : compile-cpp-source
# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
# Returns : None
# Usage : $(call compile-c-source,<srcfile>)
# Rationale : Setup everything required to build a single C++ source file
# -----------------------------------------------------------------------------
compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.o)))
# -----------------------------------------------------------------------------
# Command : cmd-process-deps
# Arguments : 1: object file path
# Returns : None
# Usage : $(call cmd-process-deps,<objectfile>)
# Rationale : To be used as a Make build command to process the dependencies
# generated by the compiler (in <obj>.d.tmp) into ones suited
# for our build system. See the comments in build/core/mkdeps.sh
# for more details.
# -----------------------------------------------------------------------------
cmd-process-deps = $(hide) $(BUILD_SYSTEM)/mkdeps.sh $(1) $(1).d.tmp $(1).d
# -----------------------------------------------------------------------------
# Command : cmd-install-file
# Arguments : 1: source file
# 2: destination file
# Returns : None
# Usage : $(call cmd-install-file,<srcfile>,<dstfile>)
# Rationale : To be used as a Make build command to copy/install a file to
# a given location.
# -----------------------------------------------------------------------------
define cmd-install-file
@mkdir -p $(dir $2)
$(hide) cp -fp $1 $2
endef

View File

@@ -0,0 +1,32 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Installed module handling
#
LOCAL_INSTALLED_MODULE := $(NDK_APP_DEST)/$(notdir $(LOCAL_BUILT_MODULE))
$(LOCAL_INSTALLED_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
$(LOCAL_INSTALLED_MODULE): PRIVATE_SRC := $(LOCAL_BUILT_MODULE)
$(LOCAL_INSTALLED_MODULE): PRIVATE_DEST := $(NDK_APP_DEST)
$(LOCAL_INSTALLED_MODULE): PRIVATE_DST := $(LOCAL_INSTALLED_MODULE)
$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
@ echo "Install : $(PRIVATE_NAME) => $(PRIVATE_DEST)"
$(hide) mkdir -p $(PRIVATE_DEST)
$(hide) install -p $(PRIVATE_SRC) $(PRIVATE_DST)
$(hide) $(call cmd-strip, $(PRIVATE_DST))
ALL_INSTALLED_MODULES += $(LOCAL_INSTALLED_MODULE)

294
ndk/build/core/main.mk Normal file
View File

@@ -0,0 +1,294 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ====================================================================
#
# Define the main configuration variables, and read the host-specific
# configuration file that is normally generated by build/host-setup.sh
#
# ====================================================================
# Include common definitions
include build/core/definitions.mk
# The location of the build system files
BUILD_SYSTEM := build/core
# Where all generated files will be stored during a build
NDK_OUT := out
# Read the host-specific configuration file in $(NDK_OUT)
#
HOST_CONFIG_MAKE := $(NDK_OUT)/host/config.mk
ifeq ($(strip $(wildcard $(HOST_CONFIG_MAKE))),)
$(call __ndk_info,\
The configuration file '$(HOST_CONFIG_MAKE)' doesnt' exist.)
$(call __ndk_info,\
Please run 'build/host-setup.sh' to generate it.)
$(call __ndk_error, Aborting)
endif
include $(HOST_CONFIG_MAKE)
HOST_PREBUILT_TAG := $(HOST_TAG)
# Location where all prebuilt binaries for a given host architectures
# will be stored.
HOST_PREBUILT := build/prebuilt/$(HOST_TAG)
# Where all app-specific generated files will be stored
NDK_APP_OUT := $(NDK_OUT)/apps
# Where all host-specific generated files will be stored
NDK_HOST_OUT := $(NDK_OUT)/host/$(HOST_TAG)
# ====================================================================
#
# Read all toolchain-specific configuration files.
#
# Each toolchain must have a corresponding config.mk file located
# in build/toolchains/<name>/ that will be included here.
#
# Each one of these files should define the following variables:
# TOOLCHAIN_NAME toolchain name (e.g. arm-eabi-4.2.1)
# TOOLCHAIN_ABIS list of target ABIs supported by the toolchain.
#
# Then, it should include $(ADD_TOOLCHAIN) which will perform
# book-keeping for the build system.
#
# ====================================================================
# the build script to include in each toolchain config.mk
ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
# the list of all toolchains in this NDK
NDK_ALL_TOOLCHAINS :=
NDK_ALL_ABIS :=
TOOLCHAIN_CONFIGS := $(wildcard build/toolchains/*/config.mk)
$(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
$(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
)
#$(info ALL_TOOLCHAINS=$(ALL_TOOLCHAINS))
NDK_TARGET_TOOLCHAIN := $(firstword $(NDK_ALL_TOOLCHAINS))
$(call ndk_log, Default toolchain is $(NDK_TARGET_TOOLCHAIN))
NDK_ALL_TOOLCHAINS := $(call uniq,$(NDK_ALL_TOOLCHAINS))
NDK_ALL_ABIS := $(call uniq,$(NDK_ALL_ABIS))
$(call ndk_log, This NDK supports the following toolchains and target ABIs:)
$(foreach tc,$(NDK_ALL_TOOLCHAINS),\
$(call ndk_log, $(space)$(space)$(tc): $(NDK_TOOLCHAIN.$(tc).abis))\
)
# ====================================================================
#
# Read all application configuration files
#
# Each 'application' must have a corresponding Application.mk file
# located in apps/<name> where <name> is a liberal name that doesn't
# contain any space in it, used to uniquely identify the
#
# Each one of these files should define the following required
# variables:
#
# APP_MODULES the list of modules needed by this application
#
# APP_PROJECT_PATH
# path to the Java project root directory where the
# generated binaries will be copied to. The NDK will
# place them in appropriate locations so they are
# properly picked by aapt, the Android Packager tool,
# when generating your applications.
#
# As well as the following *optional* variables:
#
# APP_OPTIM either 'release' or 'debug'
#
# APP_CPPFLAGS extra flags passed when building C and C++ sources
# of application modules
#
# APP_CFLAGS extra flags passed when building C sources of
# application's modules (not C++ ones)
#
# APP_CXXFLAGS extra flags passed when building C++ sources of
# application's modules (not C ones)
#
# ====================================================================
NDK_ALL_APPS :=
NDK_APPLICATIONS := $(wildcard apps/*/Application.mk)
$(foreach _application_mk, $(NDK_APPLICATIONS),\
$(eval include $(BUILD_SYSTEM)/add-application.mk)\
)
# clean up environment, just to be safe
$(call clear-vars, $(NDK_APP_VARS))
ifeq ($(strip $(NDK_ALL_APPS)),)
$(call __ndk_info,\
The NDK could not find a proper application description under apps/*/Application.mk)
$(call __ndk_info,\
Please follow the instructions in docs/NDK-APPS.TXT to write one.)
$(call __ndk_error, Aborting)
endif
ifeq ($(strip $(APP)),)
$(call __ndk_info,\
The APP variable is undefined or empty.)
$(call __ndk_info,\
Please define it to one of: $(NDK_ALL_APPS))
$(call __ndk_info,\
You can also add new applications by writing an Application.mk file.)
$(call __ndk_info,\
See docs/APPLICATION-MK.TXT for details.)
$(call __ndk_error, Aborting)
endif
# now check that APP doesn't contain an unknown app name
# if it does, we ignore them if there is at least one known
# app name in the list. Otherwise, abort with an error message
#
_unknown_apps := $(filter-out $(NDK_ALL_APPS),$(APP))
_known_apps := $(filter $(NDK_ALL_APPS),$(APP))
NDK_APPS := $(APP)
$(if $(_unknown_apps),\
$(if $(_known_apps),\
$(call __ndk_info,WARNING:\
Removing unknown names from APP variable: $(_unknown_apps))\
$(eval NDK_APPS := $(_known_apps))\
,\
$(call __ndk_info,\
The APP variable contains unknown app names: $(_unknown_apps))\
$(call __ndk_info,\
Please use one of: $(NDK_ALL_APPS))\
$(call __ndk_error, Aborting)\
)\
)
$(call __ndk_info,Building for application '$(NDK_APPS)')
# ====================================================================
#
# Prepare the build for parsing Android.mk files
#
# ====================================================================
# These phony targets are used to control various stages of the build
.PHONY: all \
host_libraries host_executables \
installed_modules \
executables libraries static_libraries shared_libraries \
clean clean-config clean-objs-dir \
clean-executables clean-libraries \
clean-installed-modules
# These macros are used in Android.mk to include the corresponding
# build script that will parse the LOCAL_XXX variable definitions.
#
CLEAR_VARS := $(BUILD_SYSTEM)/clear-vars.mk
BUILD_HOST_EXECUTABLE := $(BUILD_SYSTEM)/build-host-executable.mk
BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk
BUILD_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-static-library.mk
BUILD_SHARED_LIBRARY := $(BUILD_SYSTEM)/build-shared-library.mk
BUILD_EXECUTABLE := $(BUILD_SYSTEM)/build-executable.mk
ANDROID_MK_INCLUDED := \
$(CLEAR_VARS) \
$(BUILD_HOST_EXECUTABLE) \
$(BUILD_HOST_STATIC_LIBRARY) \
$(BUILD_STATIC_LIBRARY) \
$(BUILD_SHARED_LIBRARY) \
$(BUILD_EXECUTABLE) \
# this is the list of directories containing dependency information
# generated during the build. It will be updated by build scripts
# when module definitions are parsed.
#
ALL_DEPENDENCY_DIRS :=
# this is the list of all generated files that we would need to clean
ALL_HOST_EXECUTABLES :=
ALL_HOST_STATIC_LIBRARIES :=
ALL_STATIC_LIBRARIES :=
ALL_SHARED_LIBRARIES :=
ALL_EXECUTABLES :=
ALL_INSTALLED_MODULES :=
# the first rule
all: installed_modules host_libraries host_executables
# ====================================================================
#
# For each platform/abi combo supported by the application, we should
# setup the toolchain and parse all module definitions files again
# to build the right dependency tree.
#
# All this work is performed by build/core/setup-toolchain.mk
#
# ====================================================================
# XXX: For now, only support one platform and one target ABI with
# only one toolchain.
#
TARGET_PLATFORM := android-1.5
TARGET_ARCH_ABI := arm
TARGET_ARCH := arm
TARGET_TOOLCHAIN := $(NDK_TARGET_TOOLCHAIN)
include build/core/setup-toolchain.mk
# ====================================================================
#
# Now finish the build preparation with a few rules that depend on
# what has been effectively parsed and recorded previously
#
# ====================================================================
clean: clean-intermediates clean-installed-modules
distclean: clean clean-config
installed_modules: libraries $(ALL_INSTALLED_MODULES)
host_libraries: $(HOST_STATIC_LIBRARIES)
host_executables: $(HOST_EXECUTABLES)
static_libraries: $(STATIC_LIBRARIES)
shared_libraries: $(SHARED_LIBRARIES)
executables: $(EXECUTABLES)
libraries: static_libraries shared_libraries
clean-host-intermediates:
$(hide) rm -rf $(HOST_EXECUTABLES) $(HOST_STATIC_LIBRARIES)
clean-intermediates: clean-host-intermediates
$(hide) rm -rf $(EXECUTABLES) $(STATIC_LIBRARIES) $(SHARED_LIBRARIES)
clean-installed-modules:
$(hide) rm -rf $(ALL_INSTALLED_MODULES)
clean-config:
$(hide) rm -f $(CONFIG_MAKE) $(CONFIG_H)
# include dependency information
ALL_DEPENDENCY_DIRS := $(sort $(ALL_DEPENDENCY_DIRS))
-include $(wildcard $(ALL_DEPENDENCY_DIRS:%=%/*.d))

51
ndk/build/core/mkdeps.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/sh
#
# Copyright (C) 2008 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.
#
# This script is used to transform the dependency files generated by GCC
# For example, a typical .d file will have a line like:
#
# source.o: /full/path/to/source.c other.h headers.h
# ...
#
# the script is used to replace 'source.o' to a full path, as in
#
# objs/intermediates/emulator/source.o: /full/path/to/source.c other.h headers.h
#
# parameters
#
# $1: object file (full path)
# $2: source dependency file to modify (erased on success)
# $3: target source dependency file
#
# quote the object path. we change a single '.' into
# a '\.' since this will be parsed by sed.
#
OBJECT=`echo $1 | sed -e s/\\\\./\\\\\\\\./g`
#echo OBJECT=$OBJECT
OBJ_NAME=`basename $OBJECT`
#echo OBJ_NAME=$OBJ_NAME
# we replace $OBJ_NAME with $OBJECT only if $OBJ_NAME starts the line
# that's because some versions of GCC (e.g. 4.2.3) already produce
# a correct dependency line with the full path to the object file.
# In this case, we don't want to touch anything
#
cat $2 | sed -e s%^$OBJ_NAME%$OBJECT%g > $3 && rm -f $2

Some files were not shown because too many files have changed in this diff Show More