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">
|
android:icon="@drawable/ic_launcher_devtools">
|
||||||
|
|
||||||
<uses-library android:name="android.test.runner" />
|
<uses-library android:name="android.test.runner" />
|
||||||
<uses-library android:name="com.google.android.maps" />
|
|
||||||
|
|
||||||
<activity android:name="Development" android:label="Dev Tools"
|
<activity android:name="Development" android:label="Dev Tools"
|
||||||
android:icon="@drawable/ic_launcher_devtools">
|
android:icon="@drawable/ic_launcher_devtools">
|
||||||
@@ -132,5 +131,11 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</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>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -77,6 +77,14 @@
|
|||||||
<TextView android:id="@+id/attr_five_way_nav"
|
<TextView android:id="@+id/attr_five_way_nav"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"/>
|
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>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
|||||||
@@ -143,13 +143,6 @@
|
|||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:text="@string/development_settings_show_xmpp_text" />
|
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>
|
</RelativeLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|||||||
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_show_xmpp_text">Show GTalk service connection status</string>
|
||||||
<string name="development_settings_debug_app_label_text">Debug App:</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_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="development_settings_keep_screen_on_text">Keep screen on while plugged in</string>
|
||||||
|
|
||||||
<string name="monkey_screen_initialActivity_text"></string>
|
<string name="monkey_screen_initialActivity_text"></string>
|
||||||
@@ -92,9 +91,6 @@
|
|||||||
<string name="monkey_screen_start_text">Start</string>
|
<string name="monkey_screen_start_text">Start</string>
|
||||||
<string name="monkey_screen_initial_activity_label">Initial Activity: </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_clear_on_background_label">Clear on Background</string>
|
||||||
<string name="show_activity_task_affinity_label">Task Affinity</string>
|
<string name="show_activity_task_affinity_label">Task Affinity</string>
|
||||||
<string name="show_activity_process_label">Process</string>
|
<string name="show_activity_process_label">Process</string>
|
||||||
@@ -123,4 +119,18 @@
|
|||||||
<string name="hard_keyboard_label">hardKeyboard:</string>
|
<string name="hard_keyboard_label">hardKeyboard:</string>
|
||||||
<string name="navigation_label">navigation:</string>
|
<string name="navigation_label">navigation:</string>
|
||||||
<string name="five_way_nav_label">five way nav:</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>
|
</resources>
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class AppHwPref extends Activity {
|
|||||||
private static final int TOUCHSCREEN = BASE + 1;
|
private static final int TOUCHSCREEN = BASE + 1;
|
||||||
private static final int KEYBOARD_TYPE = BASE + 2;
|
private static final int KEYBOARD_TYPE = BASE + 2;
|
||||||
private static final int NAVIGATION = BASE + 3;
|
private static final int NAVIGATION = BASE + 3;
|
||||||
|
private static final int GLES_VERSION = BASE + 4;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle icicle) {
|
protected void onCreate(Bundle icicle) {
|
||||||
@@ -85,6 +86,7 @@ public class AppHwPref extends Activity {
|
|||||||
displayTextView(R.id.attr_navigation, appHwPref, NAVIGATION);
|
displayTextView(R.id.attr_navigation, appHwPref, NAVIGATION);
|
||||||
displayFlag(R.id.attr_hard_keyboard, ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD, appHwPref);
|
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);
|
displayFlag(R.id.attr_five_way_nav, ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV, appHwPref);
|
||||||
|
displayTextView(R.id.attr_gles_version, appHwPref, GLES_VERSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +142,9 @@ public class AppHwPref extends Activity {
|
|||||||
case NAVIGATION:
|
case NAVIGATION:
|
||||||
str = getNavigationStr(config[i]);
|
str = getNavigationStr(config[i]);
|
||||||
break;
|
break;
|
||||||
|
case GLES_VERSION:
|
||||||
|
str = config[i].getGlEsVersion();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(str != null) {
|
if(str != null) {
|
||||||
list.add(str);
|
list.add(str);
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ public class DevelopmentSettings extends Activity {
|
|||||||
private CheckBox mShowUpdatesCB;
|
private CheckBox mShowUpdatesCB;
|
||||||
private CheckBox mShowBackgroundCB;
|
private CheckBox mShowBackgroundCB;
|
||||||
private CheckBox mShowSleepCB;
|
private CheckBox mShowSleepCB;
|
||||||
private CheckBox mShowMapsCompassCB;
|
|
||||||
private CheckBox mShowXmppCB;
|
private CheckBox mShowXmppCB;
|
||||||
private Spinner mMaxProcsSpinner;
|
private Spinner mMaxProcsSpinner;
|
||||||
private Spinner mWindowAnimationScaleSpinner;
|
private Spinner mWindowAnimationScaleSpinner;
|
||||||
@@ -69,7 +68,6 @@ public class DevelopmentSettings extends Activity {
|
|||||||
private boolean mAlwaysFinish;
|
private boolean mAlwaysFinish;
|
||||||
private int mProcessLimit;
|
private int mProcessLimit;
|
||||||
private boolean mShowSleep;
|
private boolean mShowSleep;
|
||||||
private boolean mShowMapsCompass;
|
|
||||||
private boolean mShowXmpp;
|
private boolean mShowXmpp;
|
||||||
private AnimationScaleSelectedListener mWindowAnimationScale
|
private AnimationScaleSelectedListener mWindowAnimationScale
|
||||||
= new AnimationScaleSelectedListener(0);
|
= new AnimationScaleSelectedListener(0);
|
||||||
@@ -106,8 +104,6 @@ public class DevelopmentSettings extends Activity {
|
|||||||
mShowBackgroundCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1003));
|
mShowBackgroundCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1003));
|
||||||
mShowSleepCB = (CheckBox)findViewById(R.id.show_sleep);
|
mShowSleepCB = (CheckBox)findViewById(R.id.show_sleep);
|
||||||
mShowSleepCB.setOnClickListener(mShowSleepClicked);
|
mShowSleepCB.setOnClickListener(mShowSleepClicked);
|
||||||
mShowMapsCompassCB = (CheckBox)findViewById(R.id.show_maps_compass);
|
|
||||||
mShowMapsCompassCB.setOnClickListener(mShowMapsCompassClicked);
|
|
||||||
mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
|
mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
|
||||||
mShowXmppCB.setOnClickListener(mShowXmppClicked);
|
mShowXmppCB.setOnClickListener(mShowXmppClicked);
|
||||||
mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
|
mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
|
||||||
@@ -172,7 +168,6 @@ public class DevelopmentSettings extends Activity {
|
|||||||
updateSharedOptions();
|
updateSharedOptions();
|
||||||
updateFlingerOptions();
|
updateFlingerOptions();
|
||||||
updateSleepOptions();
|
updateSleepOptions();
|
||||||
updateMapsCompassOptions();
|
|
||||||
updateXmppOptions();
|
updateXmppOptions();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -293,31 +288,6 @@ public class DevelopmentSettings extends Activity {
|
|||||||
mShowSleepCB.setChecked(mShowSleep);
|
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() {
|
private void writeXmppOptions() {
|
||||||
Settings.System.setShowGTalkServiceStatus(getContentResolver(), mShowXmpp);
|
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() {
|
private View.OnClickListener mShowXmppClicked = new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mShowXmpp = ((CheckBox)v).isChecked();
|
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.
|
// Enable the GPS.
|
||||||
// Not needed since this SDK will contain the Settings app.
|
// 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);
|
Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, LocationManager.GPS_PROVIDER);
|
||||||
locationManager.updateProviders();
|
|
||||||
|
|
||||||
// enable install from non market
|
// enable install from non market
|
||||||
Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
|
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.Exec;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -54,7 +53,6 @@ import android.view.inputmethod.EditorInfo;
|
|||||||
import android.view.inputmethod.ExtractedText;
|
import android.view.inputmethod.ExtractedText;
|
||||||
import android.view.inputmethod.ExtractedTextRequest;
|
import android.view.inputmethod.ExtractedTextRequest;
|
||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -105,8 +103,6 @@ public class Term extends Activity {
|
|||||||
*/
|
*/
|
||||||
private FileDescriptor mTermFd;
|
private FileDescriptor mTermFd;
|
||||||
|
|
||||||
private boolean mShellRunning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to send data to the remote process.
|
* Used to send data to the remote process.
|
||||||
*/
|
*/
|
||||||
@@ -185,7 +181,9 @@ public class Term extends Activity {
|
|||||||
mKeyListener = new TermKeyListener();
|
mKeyListener = new TermKeyListener();
|
||||||
|
|
||||||
mEmulatorView.setFocusable(true);
|
mEmulatorView.setFocusable(true);
|
||||||
|
mEmulatorView.setFocusableInTouchMode(true);
|
||||||
mEmulatorView.requestFocus();
|
mEmulatorView.requestFocus();
|
||||||
|
mEmulatorView.register(mKeyListener);
|
||||||
|
|
||||||
updatePrefs();
|
updatePrefs();
|
||||||
}
|
}
|
||||||
@@ -194,14 +192,11 @@ public class Term extends Activity {
|
|||||||
int[] processId = new int[1];
|
int[] processId = new int[1];
|
||||||
|
|
||||||
createSubprocess(processId);
|
createSubprocess(processId);
|
||||||
mShellRunning = true;
|
|
||||||
|
|
||||||
final int procId = processId[0];
|
final int procId = processId[0];
|
||||||
|
|
||||||
final Handler handler = new Handler() {
|
final Handler handler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
mShellRunning = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1357,7 +1352,7 @@ class TerminalEmulator {
|
|||||||
printableB = ' ';
|
printableB = ' ';
|
||||||
}
|
}
|
||||||
Log.w(Term.LOG_TAG, "'" + Character.toString(printableB)
|
Log.w(Term.LOG_TAG, "'" + Character.toString(printableB)
|
||||||
+ "' (" + Integer.toString((int) b) + ")");
|
+ "' (" + Integer.toString(b) + ")");
|
||||||
}
|
}
|
||||||
process(b);
|
process(b);
|
||||||
mProcessedCharCount++;
|
mProcessedCharCount++;
|
||||||
@@ -2084,7 +2079,7 @@ class TerminalEmulator {
|
|||||||
buf.append(" char: '");
|
buf.append(" char: '");
|
||||||
buf.append((char) b);
|
buf.append((char) b);
|
||||||
buf.append("' (");
|
buf.append("' (");
|
||||||
buf.append((int) b);
|
buf.append(b);
|
||||||
buf.append(")");
|
buf.append(")");
|
||||||
boolean firstArg = true;
|
boolean firstArg = true;
|
||||||
for (int i = 0; i <= mArgIndex; i++) {
|
for (int i = 0; i <= mArgIndex; i++) {
|
||||||
@@ -2604,6 +2599,7 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
|
|
||||||
private GestureDetector mGestureDetector;
|
private GestureDetector mGestureDetector;
|
||||||
private float mScrollRemainder;
|
private float mScrollRemainder;
|
||||||
|
private TermKeyListener mKeyListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our message handler class. Implements a periodic callback.
|
* Our message handler class. Implements a periodic callback.
|
||||||
@@ -2615,6 +2611,7 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
*
|
*
|
||||||
* @param msg The callback message.
|
* @param msg The callback message.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
if (msg.what == UPDATE) {
|
if (msg.what == UPDATE) {
|
||||||
update();
|
update();
|
||||||
@@ -2627,6 +2624,10 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
commonConstructor();
|
commonConstructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void register(TermKeyListener listener) {
|
||||||
|
mKeyListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
public void setColors(int foreground, int background) {
|
public void setColors(int foreground, int background) {
|
||||||
mForeground = foreground;
|
mForeground = foreground;
|
||||||
mBackground = background;
|
mBackground = background;
|
||||||
@@ -2651,52 +2652,64 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||||
return new BaseInputConnection(this, false) {
|
return new BaseInputConnection(this, false) {
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean beginBatchEdit() {
|
public boolean beginBatchEdit() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean clearMetaKeyStates(int states) {
|
public boolean clearMetaKeyStates(int states) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean commitCompletion(CompletionInfo text) {
|
public boolean commitCompletion(CompletionInfo text) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||||
sendText(text);
|
sendText(text);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean endBatchEdit() {
|
public boolean endBatchEdit() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean finishComposingText() {
|
public boolean finishComposingText() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getCursorCapsMode(int reqModes) {
|
public int getCursorCapsMode(int reqModes) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ExtractedText getExtractedText(ExtractedTextRequest request,
|
public ExtractedText getExtractedText(ExtractedTextRequest request,
|
||||||
int flags) {
|
int flags) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public CharSequence getTextAfterCursor(int n, int flags) {
|
public CharSequence getTextAfterCursor(int n, int flags) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public CharSequence getTextBeforeCursor(int n, int flags) {
|
public CharSequence getTextBeforeCursor(int n, int flags) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean performEditorAction(int actionCode) {
|
public boolean performEditorAction(int actionCode) {
|
||||||
if(actionCode == EditorInfo.IME_ACTION_UNSPECIFIED) {
|
if(actionCode == EditorInfo.IME_ACTION_UNSPECIFIED) {
|
||||||
// The "return" key has been pressed on the IME.
|
// The "return" key has been pressed on the IME.
|
||||||
@@ -2706,14 +2719,17 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean performContextMenuAction(int id) {
|
public boolean performContextMenuAction(int id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean performPrivateCommand(String action, Bundle data) {
|
public boolean performPrivateCommand(String action, Bundle data) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean sendKeyEvent(KeyEvent event) {
|
public boolean sendKeyEvent(KeyEvent event) {
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
switch(event.getKeyCode()) {
|
switch(event.getKeyCode()) {
|
||||||
@@ -2725,17 +2741,19 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean setSelection(int start, int end) {
|
public boolean setSelection(int start, int end) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendChar(int c) {
|
private void sendChar(int c) {
|
||||||
try {
|
try {
|
||||||
mTermOut.write(c);
|
mapAndSend(c);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2745,11 +2763,16 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener {
|
|||||||
try {
|
try {
|
||||||
for(int i = 0; i < n; i++) {
|
for(int i = 0; i < n; i++) {
|
||||||
char c = text.charAt(i);
|
char c = text.charAt(i);
|
||||||
mTermOut.write(c);
|
mapAndSend(c);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} 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.
|
* Handle a keyDown event.
|
||||||
*
|
*
|
||||||
@@ -3201,30 +3253,7 @@ class TermKeyListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mControlKey.isActive()) {
|
result = mapControlChar(result);
|
||||||
// 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,16 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# swt
|
# swt
|
||||||
lib/libswt-carbon-3236.jnilib tools/lib/libswt-carbon-3236.jnilib
|
prebuilt/darwin-x86/swt/swt.jar tools/lib/x86/swt.jar
|
||||||
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
|
# JetCreator (only available on mac/windows)
|
||||||
framework/org.eclipse.equinox.common_3.2.0.v20060603.jar tools/lib/org.eclipse.equinox.common_3.2.0.v20060603.jar
|
external/sonivox/jet_tools/JetCreator tools/Jet/JetCreator
|
||||||
framework/org.eclipse.jface_3.2.0.I20060605-1400.jar tools/lib/org.eclipse.jface_3.2.0.I20060605-1400.jar
|
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
|
# swt
|
||||||
lib/libswt-atk-gtk-3236.so tools/lib/libswt-atk-gtk-3236.so
|
prebuilt/linux-x86/swt/swt.jar tools/lib/x86/swt.jar
|
||||||
lib/libswt-gtk-3236.so tools/lib/libswt-gtk-3236.so
|
prebuilt/linux-x86_64/swt/swt.jar tools/lib/x86_64/swt.jar
|
||||||
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
|
|
||||||
@@ -27,12 +27,15 @@ bin/dmtracedump tools/dmtracedump
|
|||||||
bin/hprof-conv tools/hprof-conv
|
bin/hprof-conv tools/hprof-conv
|
||||||
bin/mksdcard tools/mksdcard
|
bin/mksdcard tools/mksdcard
|
||||||
|
|
||||||
# other tools
|
|
||||||
development/tools/scripts/add-accounts-sdk tools/add-accounts.py
|
|
||||||
|
|
||||||
# the uper-jar file that apps link against
|
# the uper-jar file that apps link against
|
||||||
out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
|
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
|
sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
|
||||||
development/tools/scripts/plugin.prop tools/lib/plugin.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.jar tools/lib/jfreechart-1.0.9.jar
|
||||||
framework/jfreechart-1.0.9-swt.jar tools/lib/jfreechart-1.0.9-swt.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
|
# ddms
|
||||||
bin/ddms tools/ddms
|
bin/ddms tools/ddms
|
||||||
framework/ddms.jar tools/lib/ddms.jar
|
framework/ddms.jar tools/lib/ddms.jar
|
||||||
@@ -121,6 +127,7 @@ framework/anttasks.jar tools/lib/anttasks.jar
|
|||||||
# sdkmanager
|
# sdkmanager
|
||||||
bin/android tools/android
|
bin/android tools/android
|
||||||
framework/sdklib.jar tools/lib/sdklib.jar
|
framework/sdklib.jar tools/lib/sdklib.jar
|
||||||
|
framework/sdkuilib.jar tools/lib/sdkuilib.jar
|
||||||
framework/sdkmanager.jar tools/lib/sdkmanager.jar
|
framework/sdkmanager.jar tools/lib/sdkmanager.jar
|
||||||
|
|
||||||
# emulator
|
# 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.
|
# will make some rm/mv commands to fail.
|
||||||
FORCE="1"
|
FORCE="1"
|
||||||
|
|
||||||
|
PROG_NAME="$0"
|
||||||
SDK_ZIP="$1"
|
SDK_ZIP="$1"
|
||||||
DIST_DIR="$2"
|
DIST_DIR="$2"
|
||||||
|
TEMP_DIR="$3"
|
||||||
|
[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
|
||||||
|
|
||||||
|
|
||||||
function die() {
|
function die() {
|
||||||
echo "Error:" $*
|
echo "Error:" $*
|
||||||
@@ -28,9 +32,23 @@ function die() {
|
|||||||
exit 1
|
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() {
|
function check() {
|
||||||
[ -f "$SDK_ZIP" ] || die "Pass the path of an existing Linux/Darwin SDK .zip as first parameter"
|
[ -f "$SDK_ZIP" ] || usage
|
||||||
[ -d "$DIST_DIR" ] || die "Pass the output directory as second parameter"
|
[ -d "$DIST_DIR" ] || usage
|
||||||
|
|
||||||
# Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
|
# Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
|
||||||
# provided zip filename.
|
# provided zip filename.
|
||||||
@@ -82,21 +100,22 @@ function package() {
|
|||||||
echo
|
echo
|
||||||
echo "Packaging..."
|
echo "Packaging..."
|
||||||
DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
|
DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
|
||||||
DEST="$DIST_DIR/$DEST_NAME"
|
|
||||||
DEST_NAME_ZIP="${DEST_NAME}.zip"
|
DEST_NAME_ZIP="${DEST_NAME}.zip"
|
||||||
|
|
||||||
|
TEMP_SDK_DIR="$TEMP_DIR/$DEST_NAME"
|
||||||
|
|
||||||
# Unzip current linux/mac SDK and rename using the windows name
|
# Unzip current linux/mac SDK and rename using the windows name
|
||||||
if [[ -n "$FORCE" || ! -d "$DEST" ]]; then
|
if [[ -n "$FORCE" || ! -d "$TEMP_SDK_DIR" ]]; then
|
||||||
[ -e "$DEST" ] && rm -rfv "$DEST" # cleanup dest first if exists
|
[ -e "$TEMP_SDK_DIR" ] && rm -rfv "$TEMP_SDK_DIR" # cleanup dest first if exists
|
||||||
UNZIPPED=`basename "$SDK_ZIP"`
|
UNZIPPED=`basename "$SDK_ZIP"`
|
||||||
UNZIPPED="$DIST_DIR/${UNZIPPED/.zip/}"
|
UNZIPPED="$TEMP_DIR/${UNZIPPED/.zip/}"
|
||||||
[ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED" # cleanup unzip dir (if exists)
|
[ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED" # cleanup unzip dir (if exists)
|
||||||
unzip "$SDK_ZIP" -d "$DIST_DIR"
|
unzip "$SDK_ZIP" -d "$TEMP_DIR"
|
||||||
mv -v "$UNZIPPED" "$DEST"
|
mv -v "$UNZIPPED" "$TEMP_SDK_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Assert that the package contains only one platform
|
# Assert that the package contains only one platform
|
||||||
PLATFORMS="$DEST/platforms"
|
PLATFORMS="$TEMP_SDK_DIR/platforms"
|
||||||
THE_PLATFORM=`echo $PLATFORMS/*`
|
THE_PLATFORM=`echo $PLATFORMS/*`
|
||||||
PLATFORM_TOOLS=$THE_PLATFORM/tools
|
PLATFORM_TOOLS=$THE_PLATFORM/tools
|
||||||
echo "Platform found: " $THE_PLATFORM
|
echo "Platform found: " $THE_PLATFORM
|
||||||
@@ -107,53 +126,86 @@ function package() {
|
|||||||
|
|
||||||
|
|
||||||
# USB Driver for ADB
|
# USB Driver for ADB
|
||||||
mkdir -pv $DEST/usb_driver/x86
|
mkdir -pv $TEMP_SDK_DIR/usb_driver/x86
|
||||||
cp -rv development/host/windows/prebuilt/usb/driver/* $DEST/usb_driver/x86/
|
cp -rv development/host/windows/prebuilt/usb/driver/* $TEMP_SDK_DIR/usb_driver/x86/
|
||||||
mkdir -pv $DEST/usb_driver/amd64
|
mkdir -pv $TEMP_SDK_DIR/usb_driver/x86_64
|
||||||
cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $DEST/usb_driver/amd64/
|
cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $TEMP_SDK_DIR/usb_driver/x86_64/
|
||||||
|
|
||||||
# Remove obsolete stuff from tools & platform
|
# Remove obsolete stuff from tools & platform
|
||||||
TOOLS="$DEST/tools"
|
TOOLS="$TEMP_SDK_DIR/tools"
|
||||||
LIB="$DEST/tools/lib"
|
LIB="$TEMP_SDK_DIR/tools/lib"
|
||||||
rm -v "$TOOLS"/{adb,emulator,traceview,draw9patch,hierarchyviewer,apkbuilder,ddms,dmtracedump,hprof-conv,mksdcard,sqlite3,android}
|
rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator}
|
||||||
rm -v --force "$LIB"/*.so "$LIB"/*.jnilib
|
rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview}
|
||||||
|
rm -v "$LIB"/*/swt.jar
|
||||||
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
|
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
|
||||||
|
|
||||||
|
|
||||||
# Copy all the new stuff in tools
|
# Copy all the new stuff in tools
|
||||||
# Note: some tools are first copied here and then moved in platforms/<name>/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 out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"/
|
||||||
cp -v prebuilt/windows/swt/*.{jar,dll} "$LIB"
|
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:
|
# If you want the emulator NOTICE in the tools dir, uncomment the following line:
|
||||||
# cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
|
# cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
|
||||||
|
|
||||||
# We currently need libz from MinGW for aapt
|
# 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
|
# Update a bunch of bat files
|
||||||
cp -v development/tools/apkbuilder/etc/apkbuilder.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/ddms/app/etc/ddms.bat "$TOOLS"/
|
||||||
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"
|
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"/
|
||||||
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"
|
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"/
|
||||||
cp -v development/tools/draw9patch/etc/draw9patch.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/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.
|
# 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
|
# 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
|
# 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/
|
# 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 "$TEMP_SDK_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 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
|
||||||
|
|
||||||
# Done.. Zip it
|
# Done.. Zip it. Clean the temp folder ONLY if the zip worked (to ease debugging)
|
||||||
pushd "$DIST_DIR" > /dev/null
|
pushd "$TEMP_DIR" > /dev/null
|
||||||
[ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
|
[ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
|
||||||
zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
|
zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
|
||||||
popd > /dev/null
|
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 "Done"
|
||||||
echo
|
echo
|
||||||
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
|
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
|
||||||
@@ -165,6 +217,7 @@ function package() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check
|
check
|
||||||
|
status
|
||||||
build
|
build
|
||||||
package
|
package
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ public class Monkey {
|
|||||||
|
|
||||||
float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];
|
float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];
|
||||||
MonkeyEventSource mEventSource;
|
MonkeyEventSource mEventSource;
|
||||||
|
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor operations happening in the system.
|
* Monitor operations happening in the system.
|
||||||
@@ -362,7 +363,7 @@ public class Monkey {
|
|||||||
|
|
||||||
if (mScriptFileName != null) {
|
if (mScriptFileName != null) {
|
||||||
// script mode, ignore other options
|
// script mode, ignore other options
|
||||||
mEventSource = new MonkeySourceScript(mScriptFileName);
|
mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
|
||||||
mEventSource.setVerbose(mVerbose);
|
mEventSource.setVerbose(mVerbose);
|
||||||
} else {
|
} else {
|
||||||
// random source by default
|
// random source by default
|
||||||
@@ -401,7 +402,9 @@ public class Monkey {
|
|||||||
signalPersistentProcesses();
|
signalPersistentProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mNetworkMonitor.start();
|
||||||
int crashedAtCycle = runMonkeyCycles();
|
int crashedAtCycle = runMonkeyCycles();
|
||||||
|
mNetworkMonitor.stop();
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mRequestAnrTraces) {
|
if (mRequestAnrTraces) {
|
||||||
@@ -423,6 +426,7 @@ public class Monkey {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mAm.setActivityWatcher(null);
|
mAm.setActivityWatcher(null);
|
||||||
|
mNetworkMonitor.unregister(mAm);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// just in case this was latent (after mCount cycles), make sure
|
// just in case this was latent (after mCount cycles), make sure
|
||||||
// we report it
|
// we report it
|
||||||
@@ -443,6 +447,9 @@ public class Monkey {
|
|||||||
System.out.println(mDroppedFlipEvents);
|
System.out.println(mDroppedFlipEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// report network stats
|
||||||
|
mNetworkMonitor.dump();
|
||||||
|
|
||||||
if (crashedAtCycle < mCount - 1) {
|
if (crashedAtCycle < mCount - 1) {
|
||||||
System.err.println("** System appears to have crashed at event "
|
System.err.println("** System appears to have crashed at event "
|
||||||
+ crashedAtCycle + " of " + mCount + " using seed " + mSeed);
|
+ crashedAtCycle + " of " + mCount + " using seed " + mSeed);
|
||||||
@@ -602,6 +609,7 @@ public class Monkey {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mAm.setActivityWatcher(new ActivityWatcher());
|
mAm.setActivityWatcher(new ActivityWatcher());
|
||||||
|
mNetworkMonitor.register(mAm);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
System.err.println("** Failed talking with activity manager!");
|
System.err.println("** Failed talking with activity manager!");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ public abstract class MonkeyEvent {
|
|||||||
return eventType;
|
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
|
* a method for injecting event
|
||||||
* @param iwm wires to current window manager
|
* @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);
|
mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isThrottlable() {
|
||||||
|
return (getAction() == KeyEvent.ACTION_UP);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
|
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.app.IActivityManager;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
|
||||||
@@ -123,6 +124,11 @@ public class MonkeyMotionEvent extends MonkeyEvent {
|
|||||||
mXPrecision, mYPrecision, mDeviceId, mEdgeFlags);
|
mXPrecision, mYPrecision, mDeviceId, mEdgeFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isThrottlable() {
|
||||||
|
return (getAction() == KeyEvent.ACTION_UP);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
|
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
|
* monkey event queue
|
||||||
*/
|
*/
|
||||||
public class MonkeySourceRandom implements MonkeyEventSource{
|
public class MonkeySourceRandom implements MonkeyEventSource {
|
||||||
/** Key events that move around the UI. */
|
/** Key events that move around the UI. */
|
||||||
private static final int[] NAV_KEYS = {
|
private static final int[] NAV_KEYS = {
|
||||||
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
|
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 float[] mFactors = new float[FACTORZ_COUNT];
|
||||||
private ArrayList<ComponentName> mMainApps;
|
private ArrayList<ComponentName> mMainApps;
|
||||||
private int mEventCount = 0; //total number of events generated so far
|
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 Random mRandom;
|
||||||
private int mVerbose = 0;
|
private int mVerbose = 0;
|
||||||
private long mThrottle = 0;
|
private long mThrottle = 0;
|
||||||
@@ -203,7 +203,7 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
mRandom = new SecureRandom();
|
mRandom = new SecureRandom();
|
||||||
mRandom.setSeed((seed == 0) ? -1 : seed);
|
mRandom.setSeed((seed == 0) ? -1 : seed);
|
||||||
mMainApps = MainApps;
|
mMainApps = MainApps;
|
||||||
mThrottle = throttle;
|
mQ = new MonkeyEventQueue(throttle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,7 +336,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
downAt, MotionEvent.ACTION_UP, x, y, 0);
|
downAt, MotionEvent.ACTION_UP, x, y, 0);
|
||||||
e.setIntermediateNote(false);
|
e.setIntermediateNote(false);
|
||||||
mQ.addLast(e);
|
mQ.addLast(e);
|
||||||
addThrottle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -387,7 +386,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
e.setIntermediateNote(false);
|
e.setIntermediateNote(false);
|
||||||
mQ.addLast(e);
|
mQ.addLast(e);
|
||||||
}
|
}
|
||||||
addThrottle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,13 +418,11 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
|
MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
|
||||||
mRandom.nextInt(mMainApps.size())));
|
mRandom.nextInt(mMainApps.size())));
|
||||||
mQ.addLast(e);
|
mQ.addLast(e);
|
||||||
addThrottle();
|
|
||||||
return;
|
return;
|
||||||
} else if (cls < mFactors[FACTOR_FLIP]) {
|
} else if (cls < mFactors[FACTOR_FLIP]) {
|
||||||
MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
|
MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
|
||||||
mKeyboardOpen = !mKeyboardOpen;
|
mKeyboardOpen = !mKeyboardOpen;
|
||||||
mQ.addLast(e);
|
mQ.addLast(e);
|
||||||
addThrottle();
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
|
lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
|
||||||
@@ -437,8 +433,6 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
|
|
||||||
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
|
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
|
||||||
mQ.addLast(e);
|
mQ.addLast(e);
|
||||||
|
|
||||||
addThrottle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validate() {
|
public boolean validate() {
|
||||||
@@ -472,8 +466,4 @@ public class MonkeySourceRandom implements MonkeyEventSource{
|
|||||||
mQ.removeFirst();
|
mQ.removeFirst();
|
||||||
return e;
|
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
|
* type= raw events
|
||||||
* count= 10
|
* count= 10
|
||||||
* speed= 1.0
|
* speed= 1.0
|
||||||
|
* start data >>
|
||||||
* captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
|
* captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
|
||||||
* 0.06666667,0,0.0,0.0,65539,0)
|
* 0.06666667,0,0.0,0.0,65539,0)
|
||||||
* captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
|
* captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
|
||||||
* captureDispatchFlip(true)
|
* 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 mEventCountInScript = 0; //total number of events in the file
|
||||||
private int mVerbose = 0;
|
private int mVerbose = 0;
|
||||||
private double mSpeed = 1.0;
|
private double mSpeed = 1.0;
|
||||||
private String mScriptFileName;
|
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_TYPE = "type=";
|
||||||
private static final String HEADER_COUNT = "count=";
|
private static final String HEADER_COUNT = "count=";
|
||||||
@@ -80,12 +81,14 @@ public class MonkeySourceScript implements MonkeyEventSource{
|
|||||||
// a line at the end of the header
|
// a line at the end of the header
|
||||||
private static final String STARTING_DATA_LINE = "start data >>";
|
private static final String STARTING_DATA_LINE = "start data >>";
|
||||||
private boolean mFileOpened = false;
|
private boolean mFileOpened = false;
|
||||||
|
|
||||||
FileInputStream mFStream;
|
FileInputStream mFStream;
|
||||||
DataInputStream mInputStream;
|
DataInputStream mInputStream;
|
||||||
BufferedReader mBufferReader;
|
BufferedReader mBufferReader;
|
||||||
|
|
||||||
public MonkeySourceScript(String filename) {
|
public MonkeySourceScript(String filename, long throttle) {
|
||||||
mScriptFileName = filename;
|
mScriptFileName = filename;
|
||||||
|
mQ = new MonkeyEventQueue(throttle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
package com.android.commands.monkey;
|
package com.android.commands.monkey;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import android.app.IActivityManager;
|
import android.app.IActivityManager;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,8 +28,8 @@ import android.view.MotionEvent;
|
|||||||
public class MonkeyThrottleEvent extends MonkeyEvent {
|
public class MonkeyThrottleEvent extends MonkeyEvent {
|
||||||
private long mThrottle;
|
private long mThrottle;
|
||||||
|
|
||||||
public MonkeyThrottleEvent(int type, long throttle) {
|
public MonkeyThrottleEvent(long throttle) {
|
||||||
super(type);
|
super(MonkeyEvent.EVENT_TYPE_THROTTLE);
|
||||||
mThrottle = 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
|
static void
|
||||||
fdhandler_shutdown( FDHandler* f )
|
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)
|
if (f->out_first != NULL && !f->closing)
|
||||||
{
|
{
|
||||||
@@ -856,9 +860,6 @@ fdhandler_shutdown( FDHandler* f )
|
|||||||
f->closing = 1;
|
f->closing = 1;
|
||||||
fdhandler_remove(f);
|
fdhandler_remove(f);
|
||||||
fdhandler_prepend(f, &f->list->closing);
|
fdhandler_prepend(f, &f->list->closing);
|
||||||
|
|
||||||
/* notify the receiver that we're closing */
|
|
||||||
receiver_close(f->receiver);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,14 @@ LOCAL_CFLAGS += $(common_cflags)
|
|||||||
LOCAL_MODULE := stack_dump
|
LOCAL_MODULE := stack_dump
|
||||||
include $(BUILD_HOST_EXECUTABLE)
|
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)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_SRC_FILES := hist_trace.cpp trace_reader.cpp decoder.cpp
|
LOCAL_SRC_FILES := hist_trace.cpp trace_reader.cpp decoder.cpp
|
||||||
LOCAL_C_INCLUDES += $(common_includes)
|
LOCAL_C_INCLUDES += $(common_includes)
|
||||||
@@ -139,3 +147,11 @@ LOCAL_C_INCLUDES += $(common_includes)
|
|||||||
LOCAL_CFLAGS += $(common_cflags)
|
LOCAL_CFLAGS += $(common_cflags)
|
||||||
LOCAL_MODULE := profile_pid
|
LOCAL_MODULE := profile_pid
|
||||||
include $(BUILD_HOST_EXECUTABLE)
|
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 "armdis.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
static char *cond_names[] = {
|
static const char *cond_names[] = {
|
||||||
"eq",
|
"eq",
|
||||||
"ne",
|
"ne",
|
||||||
"cs",
|
"cs",
|
||||||
@@ -32,7 +32,7 @@ static const char *shift_names[] = {
|
|||||||
"ROR"
|
"ROR"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char* cond_to_str(int cond) {
|
static const char* cond_to_str(int cond) {
|
||||||
return cond_names[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);
|
sprintf(rd_str, "r%d, ", rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *sbit_str = "";
|
const char *sbit_str = "";
|
||||||
if (bit_s && !(flags & kNoSbit))
|
if (bit_s && !(flags & kNoSbit))
|
||||||
sbit_str = "s";
|
sbit_str = "s";
|
||||||
|
|
||||||
@@ -282,15 +282,15 @@ char *Arm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr)
|
|||||||
|
|
||||||
const char *opname = opcode_names[opcode];
|
const char *opname = opcode_names[opcode];
|
||||||
|
|
||||||
char *bang = "";
|
const char *bang = "";
|
||||||
if (write_back)
|
if (write_back)
|
||||||
bang = "!";
|
bang = "!";
|
||||||
|
|
||||||
char *carret = "";
|
const char *carret = "";
|
||||||
if (bit_s)
|
if (bit_s)
|
||||||
carret = "^";
|
carret = "^";
|
||||||
|
|
||||||
char *comma = "";
|
const char *comma = "";
|
||||||
tmp_list[0] = 0;
|
tmp_list[0] = 0;
|
||||||
for (int ii = 0; ii < 16; ++ii) {
|
for (int ii = 0; ii < 16; ++ii) {
|
||||||
if (reg_list & (1 << 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_pre) {
|
||||||
if (is_up) {
|
if (is_up) {
|
||||||
addr_mode = "ib";
|
addr_mode = "ib";
|
||||||
@@ -333,19 +333,19 @@ char *Arm::disasm_mem(uint32_t insn, char *ptr)
|
|||||||
uint8_t rd = (insn >> 12) & 0xf;
|
uint8_t rd = (insn >> 12) & 0xf;
|
||||||
uint16_t offset = insn & 0xfff;
|
uint16_t offset = insn & 0xfff;
|
||||||
|
|
||||||
char *opname = "ldr";
|
const char *opname = "ldr";
|
||||||
if (!is_load)
|
if (!is_load)
|
||||||
opname = "str";
|
opname = "str";
|
||||||
|
|
||||||
char *bang = "";
|
const char *bang = "";
|
||||||
if (write_back)
|
if (write_back)
|
||||||
bang = "!";
|
bang = "!";
|
||||||
|
|
||||||
char *minus = "";
|
const char *minus = "";
|
||||||
if (is_up == 0)
|
if (is_up == 0)
|
||||||
minus = "-";
|
minus = "-";
|
||||||
|
|
||||||
char *byte = "";
|
const char *byte = "";
|
||||||
if (is_byte)
|
if (is_byte)
|
||||||
byte = "b";
|
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);
|
opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *transfer = "";
|
const char *transfer = "";
|
||||||
if (write_back)
|
if (write_back)
|
||||||
transfer = "t";
|
transfer = "t";
|
||||||
sprintf(ptr, "%s%s%s%s\tr%d, [r%d], #%s%u",
|
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;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *transfer = "";
|
const char *transfer = "";
|
||||||
if (write_back)
|
if (write_back)
|
||||||
transfer = "t";
|
transfer = "t";
|
||||||
|
|
||||||
@@ -432,11 +432,11 @@ char *Arm::disasm_memhalf(uint32_t insn, char *ptr)
|
|||||||
uint8_t rm = insn & 0xf;
|
uint8_t rm = insn & 0xf;
|
||||||
uint8_t offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf);
|
uint8_t offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf);
|
||||||
|
|
||||||
char *opname = "ldr";
|
const char *opname = "ldr";
|
||||||
if (is_load == 0)
|
if (is_load == 0)
|
||||||
opname = "str";
|
opname = "str";
|
||||||
|
|
||||||
char *width = "";
|
const char *width = "";
|
||||||
if (bits_65 == 1)
|
if (bits_65 == 1)
|
||||||
width = "h";
|
width = "h";
|
||||||
else if (bits_65 == 2)
|
else if (bits_65 == 2)
|
||||||
@@ -444,10 +444,10 @@ char *Arm::disasm_memhalf(uint32_t insn, char *ptr)
|
|||||||
else
|
else
|
||||||
width = "sh";
|
width = "sh";
|
||||||
|
|
||||||
char *bang = "";
|
const char *bang = "";
|
||||||
if (write_back)
|
if (write_back)
|
||||||
bang = "!";
|
bang = "!";
|
||||||
char *minus = "";
|
const char *minus = "";
|
||||||
if (is_up == 0)
|
if (is_up == 0)
|
||||||
minus = "-";
|
minus = "-";
|
||||||
|
|
||||||
@@ -587,7 +587,7 @@ char *Arm::disasm_pld(uint32_t insn, char *ptr)
|
|||||||
uint8_t is_up = (insn >> 23) & 0x1;
|
uint8_t is_up = (insn >> 23) & 0x1;
|
||||||
uint8_t rn = (insn >> 16) & 0xf;
|
uint8_t rn = (insn >> 16) & 0xf;
|
||||||
|
|
||||||
char *minus = "";
|
const char *minus = "";
|
||||||
if (is_up == 0)
|
if (is_up == 0)
|
||||||
minus = "-";
|
minus = "-";
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ class StackFrame {
|
|||||||
typedef SYM symbol_type;
|
typedef SYM symbol_type;
|
||||||
static const uint32_t kCausedException = 0x01;
|
static const uint32_t kCausedException = 0x01;
|
||||||
static const uint32_t kInterpreted = 0x02;
|
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
|
symbol_type *function; // the symbol for the function we entered
|
||||||
uint32_t addr; // return address when this function returns
|
uint32_t addr; // return address when this function returns
|
||||||
@@ -43,7 +45,8 @@ class StackFrame {
|
|||||||
|
|
||||||
template <class FRAME, class BASE = CallStackBase>
|
template <class FRAME, class BASE = CallStackBase>
|
||||||
class CallStack : public BASE {
|
class CallStack : public BASE {
|
||||||
public:
|
public:
|
||||||
|
typedef FRAME frame_type;
|
||||||
typedef typename FRAME::symbol_type symbol_type;
|
typedef typename FRAME::symbol_type symbol_type;
|
||||||
typedef typename FRAME::symbol_type::region_type region_type;
|
typedef typename FRAME::symbol_type::region_type region_type;
|
||||||
typedef BASE base_type;
|
typedef BASE base_type;
|
||||||
@@ -56,7 +59,7 @@ class CallStack : public BASE {
|
|||||||
void threadStart(uint64_t time);
|
void threadStart(uint64_t time);
|
||||||
void threadStop(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) {
|
void setNativeOnly(bool nativeOnly) {
|
||||||
mNativeOnly = nativeOnly;
|
mNativeOnly = nativeOnly;
|
||||||
}
|
}
|
||||||
@@ -64,38 +67,36 @@ class CallStack : public BASE {
|
|||||||
int getStackLevel() { return mTop; }
|
int getStackLevel() { return mTop; }
|
||||||
|
|
||||||
uint64_t getGlobalTime(uint64_t time) { return time + mSkippedTime; }
|
uint64_t getGlobalTime(uint64_t time) { return time + mSkippedTime; }
|
||||||
void showStack();
|
void showStack(FILE *stream);
|
||||||
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;
|
|
||||||
|
|
||||||
int mNumFrames;
|
int mNumFrames;
|
||||||
FRAME *mFrames;
|
FRAME *mFrames;
|
||||||
int mTop; // index of the next stack frame to write
|
int mTop; // index of the next stack frame to write
|
||||||
|
|
||||||
int mJavaTop;
|
private:
|
||||||
|
enum Action { NONE, PUSH, POP, NATIVE_PUSH };
|
||||||
|
|
||||||
int mSnapshotNumFrames;
|
Action getAction(BBEvent *event, symbol_type *function);
|
||||||
FRAME *mSnapshotFrames;
|
void doMethodAction(BBEvent *event, symbol_type *function);
|
||||||
int mSnapshotTop; // index of the next stack frame to write
|
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;
|
symbol_type *mPrevFunction;
|
||||||
BBEvent mPrevEvent;
|
BBEvent mPrevEvent;
|
||||||
@@ -124,10 +125,7 @@ CallStack<FRAME, BASE>::CallStack(int id, int numFrames, TraceReaderType *trace)
|
|||||||
mNumFrames = numFrames;
|
mNumFrames = numFrames;
|
||||||
mFrames = new FRAME[mNumFrames];
|
mFrames = new FRAME[mNumFrames];
|
||||||
mTop = 0;
|
mTop = 0;
|
||||||
|
mAllowNativeFrames = true;
|
||||||
mSnapshotNumFrames = numFrames;
|
|
||||||
mSnapshotFrames = new FRAME[mSnapshotNumFrames];
|
|
||||||
mSnapshotTop = 0;
|
|
||||||
|
|
||||||
memset(&mDummyFunction, 0, sizeof(symbol_type));
|
memset(&mDummyFunction, 0, sizeof(symbol_type));
|
||||||
memset(&mDummyRegion, 0, sizeof(region_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));
|
memset(&mUserEvent, 0, sizeof(BBEvent));
|
||||||
mSkippedTime = 0;
|
mSkippedTime = 0;
|
||||||
mLastRunTime = 0;
|
mLastRunTime = 0;
|
||||||
mJavaTop = 0;
|
|
||||||
|
|
||||||
// Read the first two methods from the trace if we haven't already read
|
// Read the first two methods from the trace if we haven't already read
|
||||||
// from the method trace yet.
|
// from the method trace yet.
|
||||||
@@ -168,11 +165,29 @@ CallStack<FRAME, BASE>::updateStack(BBEvent *event, symbol_type *function)
|
|||||||
// instead.
|
// instead.
|
||||||
if (function->vm_sym != NULL)
|
if (function->vm_sym != NULL)
|
||||||
function = function->vm_sym;
|
function = function->vm_sym;
|
||||||
|
} else {
|
||||||
|
doMethodAction(event, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
Action action = getAction(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.
|
// Pop off native functions before pushing or popping Java methods.
|
||||||
if (action == POP && mPrevFunction->vm_sym == NULL) {
|
if (action == POP && mPrevFunction->vm_sym == NULL) {
|
||||||
// Pop off the previous function first.
|
// Pop off the previous function first.
|
||||||
@@ -197,11 +212,16 @@ CallStack<FRAME, BASE>::updateStack(BBEvent *event, symbol_type *function)
|
|||||||
doPush(event, function);
|
doPush(event, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If the stack is now empty, then push the current function.
|
// If the stack is now empty, then push the current function.
|
||||||
if (mTop == 0) {
|
if (mTop == 0) {
|
||||||
uint64_t time = event->time - mSkippedTime;
|
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;
|
mPrevFunction = function;
|
||||||
@@ -366,8 +386,11 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
|
|||||||
|
|
||||||
// Check for stack overflow
|
// Check for stack overflow
|
||||||
if (mTop >= mNumFrames) {
|
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
|
#if 0
|
||||||
showStack();
|
showStack(stderr);
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "Error: stack overflow (%d frames)\n", mTop);
|
fprintf(stderr, "Error: stack overflow (%d frames)\n", mTop);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -391,17 +414,20 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// For debugging only. Show the stack before entering the kernel
|
||||||
|
// exception-handling code.
|
||||||
if (function->flags & symbol_type::kIsVectorStart) {
|
if (function->flags & symbol_type::kIsVectorStart) {
|
||||||
printf("stack before entering exception\n");
|
printf("stack before entering exception\n");
|
||||||
showStack();
|
showStack(stderr);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
// off before pushing on the new function. Also, change the
|
||||||
// return address for the new function to the return address
|
// return address for the new function to the return address
|
||||||
// from the vector table.
|
// 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;
|
retAddr = mFrames[mTop - 1].addr;
|
||||||
doSimplePop(time);
|
doSimplePop(time);
|
||||||
}
|
}
|
||||||
@@ -426,9 +452,10 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
|
|||||||
&& mTop > 0) {
|
&& mTop > 0) {
|
||||||
// We are switching from kernel mode to user mode.
|
// We are switching from kernel mode to user mode.
|
||||||
#if 0
|
#if 0
|
||||||
|
// For debugging.
|
||||||
printf(" doPush(): popping to user mode, bb_addr: 0x%08x\n",
|
printf(" doPush(): popping to user mode, bb_addr: 0x%08x\n",
|
||||||
event->bb_addr);
|
event->bb_addr);
|
||||||
showStack();
|
showStack(stderr);
|
||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
// Pop off the kernel frames until we reach the one that
|
// 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);
|
} while (mTop > 0);
|
||||||
#if 0
|
#if 0
|
||||||
|
// For debugging
|
||||||
printf(" doPush() popping to level %d, using retAddr 0x%08x\n",
|
printf(" doPush() popping to level %d, using retAddr 0x%08x\n",
|
||||||
mTop, retAddr);
|
mTop, retAddr);
|
||||||
#endif
|
#endif
|
||||||
@@ -456,44 +484,33 @@ void CallStack<FRAME, BASE>::doPush(BBEvent *event, symbol_type *function)
|
|||||||
if ((function->flags & symbol_type::kIsVectorStart) && mTop > 0)
|
if ((function->flags & symbol_type::kIsVectorStart) && mTop > 0)
|
||||||
mFrames[mTop - 1].flags |= FRAME::kCausedException;
|
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>
|
template<class FRAME, class BASE>
|
||||||
void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function,
|
void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function, uint32_t addr,
|
||||||
uint32_t addr, uint64_t time)
|
uint64_t time, int flags)
|
||||||
{
|
{
|
||||||
// Check for stack overflow
|
// Check for stack overflow
|
||||||
if (mTop >= mNumFrames) {
|
if (mTop >= mNumFrames) {
|
||||||
showStack();
|
showStack(stderr);
|
||||||
fprintf(stderr, "too many stack frames (%d)\n", mTop);
|
fprintf(stderr, "too many stack frames (%d)\n", mTop);
|
||||||
exit(1);
|
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].addr = addr;
|
||||||
mFrames[mTop].function = function;
|
mFrames[mTop].function = function;
|
||||||
mFrames[mTop].flags = 0;
|
mFrames[mTop].flags = flags;
|
||||||
mFrames[mTop].time = time;
|
mFrames[mTop].time = time;
|
||||||
mFrames[mTop].global_time = time + mSkippedTime;
|
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);
|
mFrames[mTop].push(mTop, time, this);
|
||||||
mTop += 1;
|
mTop += 1;
|
||||||
}
|
}
|
||||||
@@ -508,17 +525,25 @@ void CallStack<FRAME, BASE>::doSimplePop(uint64_t time)
|
|||||||
mTop -= 1;
|
mTop -= 1;
|
||||||
mFrames[mTop].pop(mTop, time, this);
|
mFrames[mTop].pop(mTop, time, this);
|
||||||
|
|
||||||
// Keep track of the number of Java methods we have on the stack.
|
if (mNativeOnly)
|
||||||
symbol_type *function = mFrames[mTop].function;
|
return;
|
||||||
if (!mNativeOnly && function->vm_sym != NULL) {
|
|
||||||
mJavaTop -= 1;
|
|
||||||
|
|
||||||
// When there are no more Java stack frames, then clean up
|
// If the stack is empty, then allow more native frames.
|
||||||
// the client's stack. We need to do this because the client
|
// Otherwise, if we are transitioning from Java to native, then allow
|
||||||
// doesn't see the changes to the native stack underlying the
|
// more native frames.
|
||||||
// fake Java stack until the last Java method is popped off.
|
// Otherwise, if we are transitioning from native to Java, then disallow
|
||||||
if (mJavaTop == 0) {
|
// more native frames.
|
||||||
transitionFromJava(time);
|
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.
|
// Compare the function with the one in the stack frame.
|
||||||
if (function == mFrames[stackLevel].function) {
|
if (function == mFrames[stackLevel].function) {
|
||||||
// We found a matching function. We want to pop up to but not
|
// 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;
|
stackLevel += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -604,9 +635,11 @@ void CallStack<FRAME, BASE>::doPop(BBEvent *event, symbol_type *function,
|
|||||||
stackLevel = 1;
|
stackLevel = 1;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// If we are popping off a large number of stack frames, then
|
||||||
|
// we might have a bug.
|
||||||
if (mTop - stackLevel > 7) {
|
if (mTop - stackLevel > 7) {
|
||||||
printf("popping thru level %d\n", stackLevel);
|
printf("popping thru level %d\n", stackLevel);
|
||||||
showStack();
|
showStack(stderr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -654,20 +687,45 @@ void CallStack<FRAME, BASE>::popAll(uint64_t time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class FRAME, class BASE>
|
template<class FRAME, class BASE>
|
||||||
typename CallStack<FRAME, BASE>::Action
|
void CallStack<FRAME, BASE>::doMethodPop(BBEvent *event, uint32_t addr,
|
||||||
CallStack<FRAME, BASE>::getMethodAction(BBEvent *event, symbol_type *function)
|
const uint32_t flags)
|
||||||
{
|
{
|
||||||
if (function->vm_sym == NULL && mPrevFunction->vm_sym == NULL) {
|
uint64_t time = event->time - mSkippedTime;
|
||||||
return NONE;
|
|
||||||
|
// 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;
|
// If we found a matching frame then pop the stack up to and including
|
||||||
uint32_t prevAddr = mPrevFunction->addr + mPrevFunction->region->base_addr;
|
// that frame.
|
||||||
uint32_t addr = function->addr + function->region->base_addr;
|
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
|
// 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
|
// 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) {
|
while (event->time >= sNextMethod.time) {
|
||||||
sCurrentMethod = sNextMethod;
|
sCurrentMethod = sNextMethod;
|
||||||
if (mTrace->ReadMethod(&sNextMethod)) {
|
if (mTrace->ReadMethod(&sNextMethod)) {
|
||||||
@@ -675,86 +733,43 @@ CallStack<FRAME, BASE>::getMethodAction(BBEvent *event, symbol_type *function)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->time >= sCurrentMethod.time) {
|
if (event->time >= sCurrentMethod.time && event->pid == sCurrentMethod.pid) {
|
||||||
if (addr == sCurrentMethod.addr || prevAddr == sCurrentMethod.addr) {
|
uint64_t time = event->time - mSkippedTime;
|
||||||
action = (sCurrentMethod.flags == 0) ? PUSH : POP;
|
int flags = sCurrentMethod.flags;
|
||||||
// We found a match, so read the next record.
|
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;
|
sCurrentMethod = sNextMethod;
|
||||||
if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
|
if (sNextMethod.time != ~0ull && mTrace->ReadMethod(&sNextMethod)) {
|
||||||
sNextMethod.time = ~0ull;
|
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>
|
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) {
|
for (int ii = 0; ii < mTop; ++ii) {
|
||||||
mSnapshotFrames[ii] = mFrames[ii];
|
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",
|
||||||
|
|
||||||
// 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",
|
|
||||||
ii, mFrames[ii].time, mFrames[ii].global_time,
|
ii, mFrames[ii].time, mFrames[ii].global_time,
|
||||||
mFrames[ii].flags,
|
mFrames[ii].flags,
|
||||||
mFrames[ii].addr, mFrames[ii].function->addr,
|
mFrames[ii].addr, addr,
|
||||||
mFrames[ii].function->name);
|
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 */
|
#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;
|
continue;
|
||||||
if (strcmp(psym->name, ".plt") == 0)
|
if (strcmp(psym->name, ".plt") == 0)
|
||||||
continue;
|
continue;
|
||||||
char *ksym = " ";
|
const char *ksym = " ";
|
||||||
if (psym->region->flags & region_type::kIsKernelRegion)
|
if (psym->region->flags & region_type::kIsKernelRegion)
|
||||||
ksym = "k";
|
ksym = "k";
|
||||||
printf("%s %s %s\n", ksym, psym->name, psym->region->path);
|
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;
|
typedef T value_type;
|
||||||
|
|
||||||
void Update(const char *key, T value);
|
void Update(const char *key, T value);
|
||||||
|
bool Remove(const char *key);
|
||||||
T Find(const char *key);
|
T Find(const char *key);
|
||||||
entry_type* GetFirst();
|
entry_type* GetFirst();
|
||||||
entry_type* GetNext();
|
entry_type* GetNext();
|
||||||
@@ -120,6 +121,31 @@ void HashTable<T>::Update(const char *key, T value)
|
|||||||
num_entries_ += 1;
|
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>
|
template<class T>
|
||||||
typename HashTable<T>::value_type HashTable<T>::Find(const char *key)
|
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;
|
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,
|
inline symbol_type *GetSymbol(TraceReaderType *trace, int pid, uint32_t addr,
|
||||||
uint64_t time)
|
uint64_t time)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ int main(int argc, char **argv) {
|
|||||||
double insn_per_sec = 0;
|
double insn_per_sec = 0;
|
||||||
if (elapsed_secs != 0)
|
if (elapsed_secs != 0)
|
||||||
insn_per_sec = num_dynamic_insn / elapsed_secs;
|
insn_per_sec = num_dynamic_insn / elapsed_secs;
|
||||||
char *suffix = "";
|
const char *suffix = "";
|
||||||
if (insn_per_sec >= 1000000) {
|
if (insn_per_sec >= 1000000) {
|
||||||
insn_per_sec /= 1000000.0;
|
insn_per_sec /= 1000000.0;
|
||||||
suffix = "M";
|
suffix = "M";
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ int main(int argc, char **argv) {
|
|||||||
sum_time += pstate->cpu_time;
|
sum_time += pstate->cpu_time;
|
||||||
double per = 100.0 * pstate->cpu_time / total_time;
|
double per = 100.0 * pstate->cpu_time / total_time;
|
||||||
double sum_per = 100.0 * sum_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)
|
if ((pstate->flags & ProcessState::kCalledExec) == 0)
|
||||||
print_flags = "T";
|
print_flags = "T";
|
||||||
if (pstate->name == NULL)
|
if (pstate->name == NULL)
|
||||||
@@ -84,10 +84,11 @@ int main(int argc, char **argv) {
|
|||||||
printf("%5d %5d %10llu %6.2f %6.2f %5s %s",
|
printf("%5d %5d %10llu %6.2f %6.2f %5s %s",
|
||||||
pstate->pid, pstate->parent_pid, pstate->cpu_time,
|
pstate->pid, pstate->parent_pid, pstate->cpu_time,
|
||||||
per, sum_per, print_flags, pstate->name);
|
per, sum_per, print_flags, pstate->name);
|
||||||
for (int ii = 1; ii < pstate->argc; ++ii) {
|
for (int jj = 1; jj < pstate->argc; ++jj) {
|
||||||
printf(" %s", pstate->argv[ii]);
|
printf(" %s", pstate->argv[jj]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
delete trace;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
|
|||||||
double per = 100.0 * sym->elapsed / total;
|
double per = 100.0 * sym->elapsed / total;
|
||||||
double sum_per = 100.0 * sum / total;
|
double sum_per = 100.0 * sum / total;
|
||||||
double secs = 1.0 * sym->elapsed / kMHz;
|
double secs = 1.0 * sym->elapsed / kMHz;
|
||||||
char *ksym = " ";
|
const char *ksym = " ";
|
||||||
if (sym->region->flags & region_type::kIsKernelRegion)
|
if (sym->region->flags & region_type::kIsKernelRegion)
|
||||||
ksym = "k";
|
ksym = "k";
|
||||||
printf("%12.2f %11lld %6.2f %6.2f %s %s\n",
|
printf("%12.2f %11lld %6.2f %6.2f %s %s\n",
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ int main(int argc, char **argv)
|
|||||||
if (pStack == NULL) {
|
if (pStack == NULL) {
|
||||||
pStack = new CallStackType(event.pid, kNumStackFrames, trace);
|
pStack = new CallStackType(event.pid, kNumStackFrames, trace);
|
||||||
stacks[event.pid] = pStack;
|
stacks[event.pid] = pStack;
|
||||||
char *name = trace->GetProcessName(event.pid);
|
const char *name = trace->GetProcessName(event.pid);
|
||||||
dmtrace->addThread(event.pid, name);
|
dmtrace->addThread(event.pid, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +267,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dmtrace->close();
|
dmtrace->close();
|
||||||
delete dmtrace;
|
delete dmtrace;
|
||||||
delete trace;
|
delete trace;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (trace->ReadAddr(&time, &addr, &flags))
|
if (trace->ReadAddr(&time, &addr, &flags))
|
||||||
break;
|
break;
|
||||||
char *op = "ld";
|
const char *op = "ld";
|
||||||
if (flags == 1)
|
if (flags == 1)
|
||||||
op = "st";
|
op = "st";
|
||||||
printf("%lld 0x%08x %s\n", time, addr, op);
|
printf("%lld 0x%08x %s\n", time, addr, op);
|
||||||
|
|||||||
@@ -9,6 +9,66 @@ typedef TraceReader<> TraceReaderType;
|
|||||||
|
|
||||||
#include "parse_options-inl.h"
|
#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)
|
void Usage(const char *program)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
|
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
|
||||||
@@ -34,9 +94,14 @@ int main(int argc, char **argv) {
|
|||||||
MethodRec method_record;
|
MethodRec method_record;
|
||||||
symbol_type *sym;
|
symbol_type *sym;
|
||||||
TraceReaderType::ProcessState *proc;
|
TraceReaderType::ProcessState *proc;
|
||||||
|
frame *pframe;
|
||||||
|
|
||||||
if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
|
if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!IsValidPid(proc->pid))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sym != NULL) {
|
if (sym != NULL) {
|
||||||
printf("%lld p %d 0x%x %d %s\n",
|
printf("%lld p %d 0x%x %d %s\n",
|
||||||
method_record.time, proc->pid, method_record.addr,
|
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.time, proc->pid, method_record.addr,
|
||||||
method_record.flags);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,40 @@ typedef TraceReader<> TraceReaderType;
|
|||||||
#include "parse_options-inl.h"
|
#include "parse_options-inl.h"
|
||||||
#include "callstack.h"
|
#include "callstack.h"
|
||||||
|
|
||||||
|
static uint64_t debugTime;
|
||||||
|
static uint64_t dumpTime = 0;
|
||||||
|
|
||||||
class MyFrame : public StackFrame<symbol_type> {
|
class MyFrame : public StackFrame<symbol_type> {
|
||||||
public:
|
public:
|
||||||
void push(int stackLevel, uint64_t time, CallStackBase *base);
|
void push(int stackLevel, uint64_t time, CallStackBase *base);
|
||||||
void pop(int stackLevel, uint64_t time, CallStackBase *base);
|
void pop(int stackLevel, uint64_t time, CallStackBase *base);
|
||||||
|
void getFrameType(char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CallStack<MyFrame> CallStackType;
|
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)
|
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)
|
for (int ii = 0; ii < stackLevel; ++ii)
|
||||||
printf(".");
|
printf(".");
|
||||||
printf(" 0x%08x %s\n", addr, function->name);
|
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)
|
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)
|
for (int ii = 0; ii < stackLevel; ++ii)
|
||||||
printf(".");
|
printf(".");
|
||||||
printf(" 0x%08x %s\n", addr, function->name);
|
printf(" 0x%08x %s\n", addr, function->name);
|
||||||
@@ -43,18 +72,36 @@ static const int kNumStackFrames = 500;
|
|||||||
static const int kMaxThreads = (32 * 1024);
|
static const int kMaxThreads = (32 * 1024);
|
||||||
CallStackType *stacks[kMaxThreads];
|
CallStackType *stacks[kMaxThreads];
|
||||||
|
|
||||||
static uint64_t debugTime;
|
|
||||||
|
|
||||||
void Usage(const char *program)
|
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);
|
program);
|
||||||
OptionsUsage();
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
ParseOptions(argc, argv);
|
ParseOptions(argc, argv);
|
||||||
|
localParseOptions(argc, argv);
|
||||||
if (argc - optind != 2) {
|
if (argc - optind != 2) {
|
||||||
Usage(argv[0]);
|
Usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -66,9 +113,6 @@ int main(int argc, char **argv)
|
|||||||
trace->Open(qemu_trace_file);
|
trace->Open(qemu_trace_file);
|
||||||
trace->ReadKernelSymbols(elf_file);
|
trace->ReadKernelSymbols(elf_file);
|
||||||
trace->SetRoot(root);
|
trace->SetRoot(root);
|
||||||
TraceHeader *qheader = trace->GetHeader();
|
|
||||||
uint64_t startTime = qheader->start_sec;
|
|
||||||
startTime = (startTime << 32) | qheader->start_usec;
|
|
||||||
|
|
||||||
BBEvent event;
|
BBEvent event;
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -93,6 +137,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
// Update the stack
|
// Update the stack
|
||||||
pStack->updateStack(&event, function);
|
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) {
|
for (int ii = 0; ii < kMaxThreads; ++ii) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ struct thumb_opcode
|
|||||||
{
|
{
|
||||||
unsigned short value, mask; /* recognise instruction if (op&mask)==value */
|
unsigned short value, mask; /* recognise instruction if (op&mask)==value */
|
||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
char * assembler; /* how to disassemble this instruction */
|
const char * assembler; /* how to disassemble this instruction */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* format of the assembler string :
|
/* format of the assembler string :
|
||||||
@@ -216,7 +216,7 @@ static struct thumb_opcode thumb_opcodes[] =
|
|||||||
#define BDISP23(x,y) ((((((x) & 0x07ff) << 11) | ((y) & 0x07ff)) \
|
#define BDISP23(x,y) ((((((x) & 0x07ff) << 11) | ((y) & 0x07ff)) \
|
||||||
^ 0x200000) - 0x200000) /* 23bit */
|
^ 0x200000) - 0x200000) /* 23bit */
|
||||||
|
|
||||||
static char * arm_conditional[] =
|
static const char * arm_conditional[] =
|
||||||
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
||||||
"hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
|
"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)
|
if ((insn1 & insn->mask) != insn->value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char * c = insn->assembler;
|
const char * c = insn->assembler;
|
||||||
|
|
||||||
/* Special processing for Thumb 2-instruction BL sequence: */
|
/* Special processing for Thumb 2-instruction BL sequence: */
|
||||||
if (!*c) { /* Check for empty (not NULL) assembler string. */
|
if (!*c) { /* Check for empty (not NULL) assembler string. */
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ BBReader::~BBReader()
|
|||||||
delete decoder_;
|
delete decoder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BBReader::Open(char *filename)
|
void BBReader::Open(const char *filename)
|
||||||
{
|
{
|
||||||
// Initialize the class variables
|
// Initialize the class variables
|
||||||
memset(&nextrec_, 0, sizeof(TimeRec));
|
memset(&nextrec_, 0, sizeof(TimeRec));
|
||||||
@@ -268,7 +268,7 @@ InsnReader::~InsnReader()
|
|||||||
delete decoder_;
|
delete decoder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsnReader::Open(char *filename)
|
void InsnReader::Open(const char *filename)
|
||||||
{
|
{
|
||||||
prev_time_ = 0;
|
prev_time_ = 0;
|
||||||
time_diff_ = 0;
|
time_diff_ = 0;
|
||||||
@@ -310,7 +310,7 @@ AddrReader::~AddrReader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if there is an error opening the file
|
// 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;
|
struct stat stat_buf;
|
||||||
|
|
||||||
@@ -367,7 +367,7 @@ ExcReader::~ExcReader()
|
|||||||
delete decoder_;
|
delete decoder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExcReader::Open(char *filename)
|
void ExcReader::Open(const char *filename)
|
||||||
{
|
{
|
||||||
prev_time_ = 0;
|
prev_time_ = 0;
|
||||||
prev_recnum_ = 0;
|
prev_recnum_ = 0;
|
||||||
@@ -421,7 +421,7 @@ PidReader::~PidReader()
|
|||||||
delete decoder_;
|
delete decoder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PidReader::Open(char *filename)
|
void PidReader::Open(const char *filename)
|
||||||
{
|
{
|
||||||
prev_time_ = 0;
|
prev_time_ = 0;
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ MethodReader::~MethodReader()
|
|||||||
delete decoder_;
|
delete decoder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MethodReader::Open(char *filename)
|
bool MethodReader::Open(const char *filename)
|
||||||
{
|
{
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
|
||||||
@@ -686,8 +686,8 @@ TraceReaderBase::~TraceReaderBase()
|
|||||||
delete[] static_filename_;
|
delete[] static_filename_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceReaderBase::ReadTraceHeader(FILE *fstream, char *filename,
|
void TraceReaderBase::ReadTraceHeader(FILE *fstream, const char *filename,
|
||||||
char *tracename, TraceHeader *header)
|
const char *tracename, TraceHeader *header)
|
||||||
{
|
{
|
||||||
int rval = fread(header, sizeof(TraceHeader), 1, fstream);
|
int rval = fread(header, sizeof(TraceHeader), 1, fstream);
|
||||||
if (rval != 1) {
|
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;
|
char *fname;
|
||||||
FILE *fstream;
|
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;
|
struct stat stat_buf;
|
||||||
static const int kBufSize = 4096;
|
static const int kBufSize = 4096;
|
||||||
|
|||||||
@@ -62,6 +62,19 @@ class TraceReader : public TraceReaderBase {
|
|||||||
return NULL;
|
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
|
int refs; // reference count
|
||||||
char *path;
|
char *path;
|
||||||
uint32_t vstart;
|
uint32_t vstart;
|
||||||
@@ -100,6 +113,11 @@ class TraceReader : public TraceReaderBase {
|
|||||||
static const int kHasKernelRegion = 0x08;
|
static const int kHasKernelRegion = 0x08;
|
||||||
static const int kHasFirstMmap = 0x10;
|
static const int kHasFirstMmap = 0x10;
|
||||||
|
|
||||||
|
struct methodFrame {
|
||||||
|
uint32_t addr;
|
||||||
|
bool isNative;
|
||||||
|
};
|
||||||
|
|
||||||
ProcessState() {
|
ProcessState() {
|
||||||
cpu_time = 0;
|
cpu_time = 0;
|
||||||
tgid = 0;
|
tgid = 0;
|
||||||
@@ -153,7 +171,7 @@ class TraceReader : public TraceReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dumps the stack contents to standard output. For debugging.
|
// Dumps the stack contents to standard output. For debugging.
|
||||||
void DumpStack();
|
void DumpStack(FILE *stream);
|
||||||
|
|
||||||
uint64_t cpu_time;
|
uint64_t cpu_time;
|
||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
@@ -165,7 +183,7 @@ class TraceReader : public TraceReaderBase {
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
char *name;
|
const char *name;
|
||||||
int nregions; // num regions in use
|
int nregions; // num regions in use
|
||||||
int max_regions; // max regions allocated
|
int max_regions; // max regions allocated
|
||||||
region_type **regions;
|
region_type **regions;
|
||||||
@@ -173,7 +191,7 @@ class TraceReader : public TraceReaderBase {
|
|||||||
ProcessState *addr_manager; // the address space manager process
|
ProcessState *addr_manager; // the address space manager process
|
||||||
ProcessState *next;
|
ProcessState *next;
|
||||||
int method_stack_top;
|
int method_stack_top;
|
||||||
uint32_t method_stack[kMaxMethodStackSize];
|
methodFrame method_stack[kMaxMethodStackSize];
|
||||||
symbol_type *current_method_sym;
|
symbol_type *current_method_sym;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -184,12 +202,13 @@ class TraceReader : public TraceReaderBase {
|
|||||||
void CopyKernelRegion(ProcessState *pstate);
|
void CopyKernelRegion(ProcessState *pstate);
|
||||||
void ClearRegions(ProcessState *pstate);
|
void ClearRegions(ProcessState *pstate);
|
||||||
void CopyRegions(ProcessState *parent, ProcessState *child);
|
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 *LookupFunction(int pid, uint32_t addr, uint64_t time);
|
||||||
symbol_type *GetSymbols(int *num_syms);
|
symbol_type *GetSymbols(int *num_syms);
|
||||||
ProcessState *GetCurrentProcess() { return current_; }
|
ProcessState *GetCurrentProcess() { return current_; }
|
||||||
ProcessState *GetProcesses(int *num_procs);
|
ProcessState *GetProcesses(int *num_procs);
|
||||||
ProcessState *GetNextProcess();
|
ProcessState *GetNextProcess();
|
||||||
char *GetProcessName(int pid);
|
const char *GetProcessName(int pid);
|
||||||
void SetRoot(const char *root) { root_ = root; }
|
void SetRoot(const char *root) { root_ = root; }
|
||||||
void SetDemangle(bool demangle) { demangle_ = demangle; }
|
void SetDemangle(bool demangle) { demangle_ = demangle; }
|
||||||
bool ReadMethodSymbol(MethodRec *method_record,
|
bool ReadMethodSymbol(MethodRec *method_record,
|
||||||
@@ -217,6 +236,10 @@ class TraceReader : public TraceReaderBase {
|
|||||||
void AddRegion(ProcessState *pstate, region_type *region);
|
void AddRegion(ProcessState *pstate, region_type *region);
|
||||||
region_type *FindRegion(uint32_t addr, int nregions,
|
region_type *FindRegion(uint32_t addr, int nregions,
|
||||||
region_type **regions);
|
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 *FindFunction(uint32_t addr, int nsyms,
|
||||||
symbol_type *symbols, bool exact_match);
|
symbol_type *symbols, bool exact_match);
|
||||||
symbol_type *FindCurrentMethod(int pid, uint64_t time);
|
symbol_type *FindCurrentMethod(int pid, uint64_t time);
|
||||||
@@ -276,11 +299,14 @@ TraceReader<T>::~TraceReader()
|
|||||||
hash_entry_type *ptr;
|
hash_entry_type *ptr;
|
||||||
for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
|
for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
|
||||||
region_type *region = ptr->value;
|
region_type *region = ptr->value;
|
||||||
|
// If the symbols are not shared with another region, then delete them.
|
||||||
|
if ((region->flags & region_type::kSharedSymbols) == 0) {
|
||||||
int nsymbols = region->nsymbols;
|
int nsymbols = region->nsymbols;
|
||||||
for (int ii = 0; ii < nsymbols; ii++) {
|
for (int ii = 0; ii < nsymbols; ii++) {
|
||||||
delete[] region->symbols[ii].name;
|
delete[] region->symbols[ii].name;
|
||||||
}
|
}
|
||||||
delete[] region->symbols;
|
delete[] region->symbols;
|
||||||
|
}
|
||||||
delete[] region->path;
|
delete[] region->path;
|
||||||
|
|
||||||
// Do not delete the region itself here. Each region
|
// Do not delete the region itself here. Each region
|
||||||
@@ -422,7 +448,7 @@ TraceReader<T>::GetNextProcess()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
char* TraceReader<T>::GetProcessName(int pid)
|
const char* TraceReader<T>::GetProcessName(int pid)
|
||||||
{
|
{
|
||||||
if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
|
if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
|
||||||
return "(unknown)";
|
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>);
|
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>
|
template<class T>
|
||||||
void TraceReader<T>::CopyRegions(ProcessState *parent, ProcessState *child)
|
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>
|
template<class T>
|
||||||
typename TraceReader<T>::region_type *
|
typename TraceReader<T>::region_type *
|
||||||
TraceReader<T>::FindRegion(uint32_t addr, int nregions, region_type **regions)
|
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];
|
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>
|
template<class T>
|
||||||
typename TraceReader<T>::symbol_type *
|
typename TraceReader<T>::symbol_type *
|
||||||
TraceReader<T>::FindFunction(uint32_t addr, int nsyms, symbol_type *symbols,
|
TraceReader<T>::FindFunction(uint32_t addr, int nsyms, symbol_type *symbols,
|
||||||
@@ -1004,16 +1125,13 @@ TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
|
|||||||
uint32_t sym_addr = addr - cached_func_->region->base_addr;
|
uint32_t sym_addr = addr - cached_func_->region->base_addr;
|
||||||
if (sym_addr >= cached_func_->addr
|
if (sym_addr >= cached_func_->addr
|
||||||
&& sym_addr < (cached_func_ + 1)->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
|
// Check if there is a Java method on the method trace.
|
||||||
// on the current time and pid.
|
|
||||||
if (cached_func_->flags & symbol_type::kIsInterpreter) {
|
|
||||||
symbol_type *sym = FindCurrentMethod(pid, time);
|
symbol_type *sym = FindCurrentMethod(pid, time);
|
||||||
if (sym != NULL) {
|
if (sym != NULL) {
|
||||||
sym->vm_sym = cached_func_;
|
sym->vm_sym = cached_func_;
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return cached_func_;
|
return cached_func_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1037,17 +1155,13 @@ TraceReader<T>::LookupFunction(int pid, uint32_t addr, uint64_t time)
|
|||||||
if (cached_func_ != NULL) {
|
if (cached_func_ != NULL) {
|
||||||
cached_func_->region = region;
|
cached_func_->region = region;
|
||||||
|
|
||||||
// If this function is the virtual machine interpreter, then
|
// Check if there is a Java method on the method trace.
|
||||||
// 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);
|
symbol_type *sym = FindCurrentMethod(pid, time);
|
||||||
if (sym != NULL) {
|
if (sym != NULL) {
|
||||||
sym->vm_sym = cached_func_;
|
sym->vm_sym = cached_func_;
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return cached_func_;
|
return cached_func_;
|
||||||
}
|
}
|
||||||
@@ -1139,11 +1253,17 @@ void TraceReader<T>::HandlePidEvent(PidEvent *event)
|
|||||||
current_->exit_val = event->pid;
|
current_->exit_val = event->pid;
|
||||||
current_->flags |= ProcessState::kCalledExit;
|
current_->flags |= ProcessState::kCalledExit;
|
||||||
break;
|
break;
|
||||||
|
case kPidMunmap:
|
||||||
|
FindAndRemoveRegion(current_, event->vstart, event->vend);
|
||||||
|
break;
|
||||||
case kPidMmap:
|
case kPidMmap:
|
||||||
{
|
{
|
||||||
region_type *region;
|
region_type *region;
|
||||||
region_type *existing_region = hash_->Find(event->path);
|
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'
|
// Create a new region and add it to the current process'
|
||||||
// address space.
|
// address space.
|
||||||
region = new region_type;
|
region = new region_type;
|
||||||
@@ -1165,8 +1285,6 @@ void TraceReader<T>::HandlePidEvent(PidEvent *event)
|
|||||||
} else {
|
} else {
|
||||||
region->nsymbols = existing_region->nsymbols;
|
region->nsymbols = existing_region->nsymbols;
|
||||||
region->symbols = existing_region->symbols;
|
region->symbols = existing_region->symbols;
|
||||||
region->path = existing_region->path;
|
|
||||||
delete[] event->path;
|
|
||||||
region->flags |= region_type::kSharedSymbols;
|
region->flags |= region_type::kSharedSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,10 +1381,12 @@ int TraceReader<T>::FindCurrentPid(uint64_t time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
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++) {
|
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;
|
uint32_t addr;
|
||||||
int top = pstate->method_stack_top;
|
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
|
// Push this method on the stack
|
||||||
if (top >= pstate->kMaxMethodStackSize) {
|
if (top >= pstate->kMaxMethodStackSize) {
|
||||||
fprintf(stderr, "Stack overflow at time %llu\n", method_rec->time);
|
fprintf(stderr, "Stack overflow at time %llu\n", method_rec->time);
|
||||||
exit(1);
|
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;
|
pstate->method_stack_top = top + 1;
|
||||||
addr = method_rec->addr;
|
addr = method_rec->addr;
|
||||||
} else {
|
} else {
|
||||||
@@ -1292,14 +1416,27 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
top -= 1;
|
top -= 1;
|
||||||
addr = pstate->method_stack[top];
|
addr = pstate->method_stack[top].addr;
|
||||||
if (addr != method_rec->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,
|
fprintf(stderr,
|
||||||
"Stack method (0x%x) at index %d does not match trace record (0x%x) at time %llu\n",
|
"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);
|
addr, top, method_rec->addr, method_rec->time);
|
||||||
for (int ii = 0; ii <= top; ii++) {
|
pstate->DumpStack(stderr);
|
||||||
fprintf(stderr, " %d: 0x%x\n", ii, pstate->method_stack[ii]);
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,8 +1446,17 @@ void TraceReader<T>::HandleMethodRecord(ProcessState *pstate,
|
|||||||
pstate->current_method_sym = NULL;
|
pstate->current_method_sym = NULL;
|
||||||
return;
|
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;
|
ProcessState *manager = pstate->addr_manager;
|
||||||
region_type *region = FindRegion(addr, manager->nregions, manager->regions);
|
region_type *region = FindRegion(addr, manager->nregions, manager->regions);
|
||||||
uint32_t sym_addr = addr - region->base_addr;
|
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>
|
template <class T>
|
||||||
typename TraceReader<T>::symbol_type*
|
typename TraceReader<T>::symbol_type*
|
||||||
TraceReader<T>::FindCurrentMethod(int pid, uint64_t time)
|
TraceReader<T>::FindCurrentMethod(int pid, uint64_t time)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class TraceReaderBase {
|
|||||||
|
|
||||||
friend class BBReader;
|
friend class BBReader;
|
||||||
|
|
||||||
void Open(char *filename);
|
void Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
void WriteHeader(TraceHeader *header);
|
void WriteHeader(TraceHeader *header);
|
||||||
inline bool ReadBB(BBEvent *event);
|
inline bool ReadBB(BBEvent *event);
|
||||||
@@ -120,10 +120,10 @@ class TraceReaderBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
|
int FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
|
||||||
void ReadTraceHeader(FILE *fstream, char *filename,
|
void ReadTraceHeader(FILE *fstream, const char *filename,
|
||||||
char *tracename, TraceHeader *header);
|
const char *tracename, TraceHeader *header);
|
||||||
PidEvent *FindMmapDexFileEvent();
|
PidEvent *FindMmapDexFileEvent();
|
||||||
void ParseDexList(char *filename);
|
void ParseDexList(const char *filename);
|
||||||
|
|
||||||
char *static_filename_;
|
char *static_filename_;
|
||||||
FILE *static_fstream_;
|
FILE *static_fstream_;
|
||||||
@@ -159,7 +159,7 @@ class BBReader {
|
|||||||
public:
|
public:
|
||||||
explicit BBReader(TraceReaderBase *trace);
|
explicit BBReader(TraceReaderBase *trace);
|
||||||
~BBReader();
|
~BBReader();
|
||||||
void Open(char *filename);
|
void Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
bool ReadBB(BBEvent *event);
|
bool ReadBB(BBEvent *event);
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ class InsnReader {
|
|||||||
InsnReader();
|
InsnReader();
|
||||||
~InsnReader();
|
~InsnReader();
|
||||||
|
|
||||||
void Open(char *filename);
|
void Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
uint64_t ReadInsnTime(uint64_t min_time);
|
uint64_t ReadInsnTime(uint64_t min_time);
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ class AddrReader {
|
|||||||
AddrReader();
|
AddrReader();
|
||||||
~AddrReader();
|
~AddrReader();
|
||||||
|
|
||||||
bool Open(char *filename, char *suffix);
|
bool Open(const char *filename, const char *suffix);
|
||||||
void Close();
|
void Close();
|
||||||
bool ReadAddr(uint64_t *time, uint32_t *addr);
|
bool ReadAddr(uint64_t *time, uint32_t *addr);
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ class ExcReader {
|
|||||||
ExcReader();
|
ExcReader();
|
||||||
~ExcReader();
|
~ExcReader();
|
||||||
|
|
||||||
void Open(char *filename);
|
void Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
bool ReadExc(uint64_t *time, uint32_t *current_pc,
|
bool ReadExc(uint64_t *time, uint32_t *current_pc,
|
||||||
uint64_t *recnum, uint32_t *target_pc,
|
uint64_t *recnum, uint32_t *target_pc,
|
||||||
@@ -243,7 +243,7 @@ class PidReader {
|
|||||||
PidReader();
|
PidReader();
|
||||||
~PidReader();
|
~PidReader();
|
||||||
|
|
||||||
void Open(char *filename);
|
void Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
bool ReadPidEvent(struct PidEvent *event);
|
bool ReadPidEvent(struct PidEvent *event);
|
||||||
void Dispose(struct PidEvent *event);
|
void Dispose(struct PidEvent *event);
|
||||||
@@ -258,7 +258,7 @@ class MethodReader {
|
|||||||
MethodReader();
|
MethodReader();
|
||||||
~MethodReader();
|
~MethodReader();
|
||||||
|
|
||||||
bool Open(char *filename);
|
bool Open(const char *filename);
|
||||||
void Close();
|
void Close();
|
||||||
bool ReadMethod(MethodRec *method_record);
|
bool ReadMethod(MethodRec *method_record);
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cutils/log.h>
|
#include <cutils/log.h>
|
||||||
|
#include <cutils/native_handle.h>
|
||||||
#include <cutils/sockets.h>
|
#include <cutils/sockets.h>
|
||||||
#include <hardware/sensors.h>
|
#include <hardware/sensors.h>
|
||||||
|
|
||||||
@@ -123,16 +124,19 @@ typedef struct SensorControl {
|
|||||||
/* this must return a file descriptor that will be used to read
|
/* this must return a file descriptor that will be used to read
|
||||||
* the sensors data (it is passed to data__data_open() below
|
* 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)
|
control__open_data_source(struct sensors_control_device_t *dev)
|
||||||
{
|
{
|
||||||
SensorControl* ctl = (void*)dev;
|
SensorControl* ctl = (void*)dev;
|
||||||
|
native_handle_t* handle;
|
||||||
|
|
||||||
if (ctl->fd < 0) {
|
if (ctl->fd < 0) {
|
||||||
ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
|
ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
D("%s: fd=%d", __FUNCTION__, ctl->fd);
|
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
|
static int
|
||||||
@@ -244,7 +248,7 @@ data__now_ns(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
SensorData* data = (void*)dev;
|
||||||
int i;
|
int i;
|
||||||
@@ -258,7 +262,9 @@ data__data_open(struct sensors_data_device_t *dev, int fd)
|
|||||||
data->timeStart = 0;
|
data->timeStart = 0;
|
||||||
data->timeOffset = 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;
|
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/pm/src"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/cmds/svc/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/java"/>
|
||||||
|
<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
|
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/im/java"/>
|
<classpathentry kind="src" path="frameworks/base/im/java"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/location/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/services/java"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/telephony/java"/>
|
<classpathentry kind="src" path="frameworks/base/telephony/java"/>
|
||||||
<classpathentry kind="src" path="frameworks/base/test-runner"/>
|
<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/base/wifi/java"/>
|
||||||
<classpathentry kind="src" path="frameworks/policies/base/phone"/>
|
<classpathentry kind="src" path="frameworks/policies/base/phone"/>
|
||||||
<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
|
<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/SkeletonApp/tests/src"/>
|
||||||
<classpathentry kind="src" path="development/samples/Snake/src"/>
|
<classpathentry kind="src" path="development/samples/Snake/src"/>
|
||||||
<classpathentry kind="src" path="development/samples/Snake/tests/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/annotation/src/main/java"/>
|
||||||
<classpathentry kind="src" path="dalvik/libcore/archive/src/main/java"/>
|
<classpathentry kind="src" path="dalvik/libcore/archive/src/main/java"/>
|
||||||
<classpathentry kind="src" path="dalvik/libcore/auth/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/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/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/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/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java"/>
|
||||||
<classpathentry kind="src" path="out/target/common/R"/>
|
<classpathentry kind="src" path="out/target/common/R"/>
|
||||||
<classpathentry kind="src" path="external/tagsoup/src"/>
|
<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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package com.example.twolibs;
|
||||||
package com.example.android.platform_library.client;
|
|
||||||
|
|
||||||
import com.example.android.platform_library.PlatformLibrary;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
/**
|
public class TwoLibs extends Activity
|
||||||
* Use a custom platform library.
|
{
|
||||||
*/
|
/** Called when the activity is first created. */
|
||||||
public class Client extends Activity {
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
super.onCreate(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);
|
TextView tv = new TextView(this);
|
||||||
tv.setText("Got from lib: " + res);
|
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);
|
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