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:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
*~
|
||||
*.bak
|
||||
*.pyc
|
||||
Thumbs.db
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -142,13 +142,6 @@
|
||||
android:layout_below="@id/font_hinting"
|
||||
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>
|
||||
|
||||
|
||||
135
apps/Development/res/layout/permission_details.xml
Executable file
135
apps/Development/res/layout/permission_details.xml
Executable 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>
|
||||
|
||||
39
apps/Development/res/layout/pkg_list_item.xml
Executable file
39
apps/Development/res/layout/pkg_list_item.xml
Executable 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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
21
apps/Fallback/res/values-es-rUS/strings.xml
Normal file
21
apps/Fallback/res/values-es-rUS/strings.xml
Normal 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>
|
||||
21
apps/Fallback/res/values-pt/strings.xml
Normal file
21
apps/Fallback/res/values-pt/strings.xml
Normal 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>
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -130,7 +130,8 @@ public class Monkey {
|
||||
|
||||
float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];
|
||||
MonkeyEventSource mEventSource;
|
||||
|
||||
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
|
||||
|
||||
/**
|
||||
* Monitor operations happening in the system.
|
||||
*/
|
||||
@@ -222,14 +223,14 @@ public class Monkey {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the procrank tool to insert system status information into the debug report.
|
||||
*/
|
||||
private void reportProcRank() {
|
||||
commandLineReport("procrank", "procrank");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run "cat /data/anr/traces.txt". Wait about 5 seconds first, to let the asynchronous
|
||||
* report writing complete.
|
||||
@@ -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
|
||||
@@ -442,6 +446,9 @@ public class Monkey {
|
||||
System.out.print(" flips=");
|
||||
System.out.println(mDroppedFlipEvents);
|
||||
}
|
||||
|
||||
// report network stats
|
||||
mNetworkMonitor.dump();
|
||||
|
||||
if (crashedAtCycle < mCount - 1) {
|
||||
System.err.println("** System appears to have crashed at event "
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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)");
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
13
docs/copyright-templates/asm.txt
Normal file
13
docs/copyright-templates/asm.txt
Normal 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.
|
||||
15
docs/copyright-templates/bash.txt
Normal file
15
docs/copyright-templates/bash.txt
Normal 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.
|
||||
27
docs/copyright-templates/bsd/c.txt
Normal file
27
docs/copyright-templates/bsd/c.txt
Normal 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.
|
||||
*/
|
||||
15
docs/copyright-templates/c.txt
Normal file
15
docs/copyright-templates/c.txt
Normal 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.
|
||||
*/
|
||||
15
docs/copyright-templates/java.txt
Normal file
15
docs/copyright-templates/java.txt
Normal 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.
|
||||
*/
|
||||
13
docs/copyright-templates/make.txt
Normal file
13
docs/copyright-templates/make.txt
Normal 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.
|
||||
13
docs/copyright-templates/plain.txt
Normal file
13
docs/copyright-templates/plain.txt
Normal 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.
|
||||
15
docs/copyright-templates/sh.txt
Normal file
15
docs/copyright-templates/sh.txt
Normal 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.
|
||||
15
docs/copyright-templates/xml.txt
Normal file
15
docs/copyright-templates/xml.txt
Normal 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.
|
||||
-->
|
||||
180
docs/howto_SDK_git_cygwin.txt
Normal file
180
docs/howto_SDK_git_cygwin.txt
Normal 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-
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = "-";
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
270
emulator/qtools/check_stack.cpp
Normal file
270
emulator/qtools/check_stack.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
59
emulator/qtools/dump_regions.cpp
Normal file
59
emulator/qtools/dump_regions.cpp
Normal 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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
2
emulator/skins/HVGA-L/hardware.ini
Normal file
2
emulator/skins/HVGA-L/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=160
|
||||
2
emulator/skins/HVGA-P/hardware.ini
Normal file
2
emulator/skins/HVGA-P/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=160
|
||||
2
emulator/skins/HVGA/hardware.ini
Normal file
2
emulator/skins/HVGA/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=160
|
||||
2
emulator/skins/QVGA-L/hardware.ini
Normal file
2
emulator/skins/QVGA-L/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=120
|
||||
2
emulator/skins/QVGA-P/hardware.ini
Normal file
2
emulator/skins/QVGA-P/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=120
|
||||
36
emulator/tools/Android.mk
Normal file
36
emulator/tools/Android.mk
Normal 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
114
emulator/tools/qemu-props.c
Normal 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;
|
||||
}
|
||||
@@ -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
5
ndk/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
build/prebuilt
|
||||
out
|
||||
apps/*/project/libs
|
||||
.gitignore
|
||||
|
||||
3
ndk/Android.mk
Normal file
3
ndk/Android.mk
Normal 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
18
ndk/GNUmakefile
Normal 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
33
ndk/README.TXT
Normal 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
|
||||
|
||||
2
ndk/apps/hello-jni/Application.mk
Normal file
2
ndk/apps/hello-jni/Application.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
APP_PROJECT_PATH := $(call my-dir)/project
|
||||
APP_MODULES := hello-jni
|
||||
16
ndk/apps/hello-jni/project/AndroidManifest.xml
Normal file
16
ndk/apps/hello-jni/project/AndroidManifest.xml
Normal 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>
|
||||
11
ndk/apps/hello-jni/project/default.properties
Normal file
11
ndk/apps/hello-jni/project/default.properties
Normal 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
|
||||
4
ndk/apps/hello-jni/project/res/values/strings.xml
Normal file
4
ndk/apps/hello-jni/project/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">HelloJni</string>
|
||||
</resources>
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
21
ndk/apps/hello-jni/project/tests/AndroidManifest.xml
Normal file
21
ndk/apps/hello-jni/project/tests/AndroidManifest.xml
Normal 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>
|
||||
11
ndk/apps/hello-jni/project/tests/default.properties
Normal file
11
ndk/apps/hello-jni/project/tests/default.properties
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
2
ndk/apps/two-libs/Application.mk
Normal file
2
ndk/apps/two-libs/Application.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
APP_PROJECT_PATH := $(call my-dir)/project
|
||||
APP_MODULES := twolib-first twolib-second
|
||||
16
ndk/apps/two-libs/project/AndroidManifest.xml
Normal file
16
ndk/apps/two-libs/project/AndroidManifest.xml
Normal 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>
|
||||
11
ndk/apps/two-libs/project/default.properties
Normal file
11
ndk/apps/two-libs/project/default.properties
Normal 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
|
||||
4
ndk/apps/two-libs/project/res/values/strings.xml
Normal file
4
ndk/apps/two-libs/project/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">TwoLib</string>
|
||||
</resources>
|
||||
@@ -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);
|
||||
|
||||
// We'll just make our own view to show the result.
|
||||
TextView tv = new TextView(this);
|
||||
tv.setText("Got from lib: " + res);
|
||||
TextView tv = new TextView(this);
|
||||
int x = 1000;
|
||||
int y = 42;
|
||||
|
||||
// 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);
|
||||
}
|
||||
21
ndk/apps/two-libs/project/tests/AndroidManifest.xml
Normal file
21
ndk/apps/two-libs/project/tests/AndroidManifest.xml
Normal 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>
|
||||
11
ndk/apps/two-libs/project/tests/default.properties
Normal file
11
ndk/apps/two-libs/project/tests/default.properties
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
62
ndk/build/core/add-application.mk
Normal file
62
ndk/build/core/add-application.mk
Normal 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)
|
||||
65
ndk/build/core/add-toolchain.mk
Normal file
65
ndk/build/core/add-toolchain.mk
Normal 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
|
||||
173
ndk/build/core/build-binary.mk
Normal file
173
ndk/build/core/build-binary.mk
Normal 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))
|
||||
47
ndk/build/core/build-executable.mk
Normal file
47
ndk/build/core/build-executable.mk
Normal 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
|
||||
78
ndk/build/core/build-module.mk
Normal file
78
ndk/build/core/build-module.mk
Normal 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)
|
||||
|
||||
|
||||
47
ndk/build/core/build-shared-library.mk
Normal file
47
ndk/build/core/build-shared-library.mk
Normal 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
|
||||
46
ndk/build/core/build-static-library.mk
Normal file
46
ndk/build/core/build-static-library.mk
Normal 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
|
||||
37
ndk/build/core/clear-vars.mk
Normal file
37
ndk/build/core/clear-vars.mk
Normal 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))
|
||||
|
||||
483
ndk/build/core/definitions.mk
Normal file
483
ndk/build/core/definitions.mk
Normal 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
|
||||
32
ndk/build/core/install-binary.mk
Normal file
32
ndk/build/core/install-binary.mk
Normal 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
294
ndk/build/core/main.mk
Normal 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
51
ndk/build/core/mkdeps.sh
Executable 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
Reference in New Issue
Block a user