Merge "Tuning parameters for mobile RSSI." into ics-mr1
diff --git a/api/current.txt b/api/current.txt
index c94d485..e186dfb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3245,6 +3245,7 @@
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
+ method public boolean isStartDeferred();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -3280,6 +3281,7 @@
method public void setInitialSavedState(android.app.Fragment.SavedState);
method public void setMenuVisibility(boolean);
method public void setRetainInstance(boolean);
+ method public void setStartDeferred(boolean);
method public void setTargetFragment(android.app.Fragment, int);
method public void startActivity(android.content.Intent);
method public void startActivityForResult(android.content.Intent, int);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index d423d98..9b01b7f 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -339,6 +339,7 @@
private static final HashMap<String, Class<?>> sClassMap =
new HashMap<String, Class<?>>();
+ static final int INVALID_STATE = -1; // Invalid state used as a null value.
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
@@ -403,7 +404,7 @@
// The fragment manager we are associated with. Set as soon as the
// fragment is used in a transaction; cleared after it has been removed
// from all transactions.
- FragmentManager mFragmentManager;
+ FragmentManagerImpl mFragmentManager;
// Activity this fragment is attached to.
Activity mActivity;
@@ -453,6 +454,10 @@
// The View generated for this fragment.
View mView;
+ // Whether this fragment should defer starting until after other fragments
+ // have been started and their loaders are finished.
+ boolean mDeferStart;
+
LoaderManagerImpl mLoaderManager;
boolean mLoadersStarted;
boolean mCheckedForLoaderManager;
@@ -910,6 +915,34 @@
}
/**
+ * Set whether this fragment should enter the started state as normal or if
+ * start should be deferred until a system-determined convenient time, such
+ * as after any loaders have completed their work.
+ *
+ * <p>This option is not sticky across fragment starts; after a deferred start
+ * completes this option will be set to false.</p>
+ *
+ * @param deferResume true if this fragment can defer its resume until after others
+ */
+ public void setStartDeferred(boolean deferResume) {
+ if (mDeferStart && !deferResume) {
+ mFragmentManager.performPendingDeferredStart(this);
+ }
+ mDeferStart = deferResume;
+ }
+
+ /**
+ * Returns true if this fragment's move to the started state has been deferred.
+ * If this returns true it will be started once other fragments' loaders
+ * have finished running.
+ *
+ * @return true if this fragment's start has been deferred.
+ */
+ public boolean isStartDeferred() {
+ return mDeferStart;
+ }
+
+ /**
* Return the LoaderManager for this fragment, creating it if needed.
*/
public LoaderManager getLoaderManager() {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 3da4f29..58cd27c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -709,6 +709,13 @@
return AnimatorInflater.loadAnimator(mActivity, anim);
}
+ public void performPendingDeferredStart(Fragment f) {
+ if (f.mDeferStart) {
+ f.mDeferStart = false;
+ moveToState(f, mCurState, 0, 0);
+ }
+ }
+
void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
// Fragments that are not currently added will sit in the onCreate() state.
if (!f.mAdded && newState > Fragment.CREATED) {
@@ -718,7 +725,10 @@
// While removing a fragment, we can't change it to a higher state.
newState = f.mState;
}
-
+ // Defer start if requested; don't allow it to move to STARTED or higher.
+ if (f.mDeferStart && newState > Fragment.STOPPED) {
+ newState = Fragment.STOPPED;
+ }
if (f.mState < newState) {
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
@@ -992,13 +1002,21 @@
mCurState = newState;
if (mActive != null) {
+ boolean loadersRunning = false;
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.get(i);
if (f != null) {
moveToState(f, newState, transit, transitStyle);
+ if (f.mLoaderManager != null) {
+ loadersRunning |= f.mLoaderManager.hasRunningLoaders();
+ }
}
}
+ if (!loadersRunning) {
+ startPendingDeferredFragments();
+ }
+
if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
mActivity.invalidateOptionsMenu();
mNeedMenuInvalidate = false;
@@ -1006,6 +1024,15 @@
}
}
+ void startPendingDeferredFragments() {
+ for (int i=0; i<mActive.size(); i++) {
+ Fragment f = mActive.get(i);
+ if (f != null) {
+ performPendingDeferredStart(f);
+ }
+ }
+ }
+
void makeActive(Fragment f) {
if (f.mIndex >= 0) {
return;
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 89e9ddd..aef0c6f 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -418,6 +418,10 @@
info.destroy();
mInactiveLoaders.remove(mId);
}
+
+ if (!hasRunningLoaders() && mActivity != null) {
+ mActivity.mFragments.startPendingDeferredFragments();
+ }
}
void callOnLoadFinished(Loader<Object> loader, Object data) {
@@ -820,4 +824,14 @@
}
}
}
+
+ public boolean hasRunningLoaders() {
+ boolean loadersRunning = false;
+ final int count = mLoaders.size();
+ for (int i = 0; i < count; i++) {
+ final LoaderInfo li = mLoaders.valueAt(i);
+ loadersRunning |= li.mStarted && !li.mDeliveredData;
+ }
+ return loadersRunning;
+ }
}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 9c93324..31e6f02c 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -468,7 +468,7 @@
}
acquireReference();
try {
- nativeCopyStringToBuffer(mWindowPtr, row, column, buffer);
+ nativeCopyStringToBuffer(mWindowPtr, row - mStartPos, column, buffer);
} finally {
releaseReference();
}
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index 5808919..04c3377 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -16,10 +16,10 @@
package android.speech.tts;
import android.media.AudioFormat;
+import android.os.FileUtils;
import android.util.Log;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
@@ -63,7 +63,7 @@
* Must be called while holding the monitor on {@link #mStateLock}.
*/
private void cleanUp() {
- closeFile();
+ closeFileAndWidenPermissions();
if (mFile != null) {
mFileName.delete();
}
@@ -72,7 +72,7 @@
/**
* Must be called while holding the monitor on {@link #mStateLock}.
*/
- private void closeFile() {
+ private void closeFileAndWidenPermissions() {
try {
if (mFile != null) {
mFile.close();
@@ -81,6 +81,18 @@
} catch (IOException ex) {
Log.e(TAG, "Failed to close " + mFileName + ": " + ex);
}
+
+ try {
+ // Make the written file readable and writeable by everyone.
+ // This allows the app that requested synthesis to read the file.
+ //
+ // Note that the directory this file was written must have already
+ // been world writeable in order it to have been
+ // written to in the first place.
+ FileUtils.setPermissions(mFileName.getAbsolutePath(), 0666, -1, -1); //-rw-rw-rw
+ } catch (SecurityException se) {
+ Log.e(TAG, "Security exception setting rw permissions on : " + mFileName);
+ }
}
@Override
@@ -168,7 +180,7 @@
int dataLength = (int) (mFile.length() - WAV_HEADER_LENGTH);
mFile.write(
makeWavHeader(mSampleRateInHz, mAudioFormat, mChannelCount, dataLength));
- closeFile();
+ closeFileAndWidenPermissions();
mDone = true;
return TextToSpeech.SUCCESS;
} catch (IOException ex) {
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index 18a4794..6f24eba 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -168,6 +168,8 @@
/* The time display consists of two tones. That's why we have two overlapping text views. */
mTimeDisplayBackground = (TextView) findViewById(R.id.timeDisplayBackground);
mTimeDisplayBackground.setTypeface(sBackgroundFont);
+ mTimeDisplayBackground.setVisibility(View.INVISIBLE);
+
mTimeDisplayForeground = (TextView) findViewById(R.id.timeDisplayForeground);
mTimeDisplayForeground.setTypeface(sForegroundFont);
mAmPm = new AmPm(this, null);
diff --git a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..f28fe38
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..728fc67
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..99e742f
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..c7da024
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..75e4783
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..534c10b
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
index d32cd0c..23b2fcb 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
@@ -57,11 +57,27 @@
android:drawablePadding="4dip"
/>
- <com.android.internal.widget.WaveView
+ <com.android.internal.widget.multiwaveview.MultiWaveView
android:id="@+id/unlock_widget"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="true"
android:layout_gravity="center"
+
+ android:targetDrawables="@array/lockscreen_targets_with_camera"
+ android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
+ android:directionDescriptions="@array/lockscreen_direction_descriptions"
+ android:handleDrawable="@drawable/ic_lockscreen_handle"
+ android:waveDrawable="@drawable/ic_lockscreen_outerring"
+ android:outerRadius="@dimen/multiwaveview_target_placement_radius"
+ android:snapMargin="@dimen/multiwaveview_snap_margin"
+ android:hitRadius="@dimen/multiwaveview_hit_radius"
+ android:rightChevronDrawable="@drawable/ic_lockscreen_chevron_right"
+ android:horizontalOffset="0dip"
+ android:verticalOffset="60dip"
+ android:feedbackCount="3"
+ android:vibrationDuration="20"
/>
<!-- emergency call button shown when sim is PUKd and tab_selector is hidden -->
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index dd29164..66223f2 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -61,13 +61,27 @@
android:layout_alignParentTop="true"
android:drawablePadding="4dip"/>
- <com.android.internal.widget.WaveView
+ <com.android.internal.widget.multiwaveview.MultiWaveView
android:id="@+id/unlock_widget"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_rowSpan="7"
android:layout_gravity="center_vertical|center_horizontal"
- android:layout_marginRight="0dip"
- android:layout_weight="1.0"/>
+
+ android:targetDrawables="@array/lockscreen_targets_with_camera"
+ android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
+ android:directionDescriptions="@array/lockscreen_direction_descriptions"
+ android:handleDrawable="@drawable/ic_lockscreen_handle"
+ android:waveDrawable="@drawable/ic_lockscreen_outerring"
+ android:outerRadius="@dimen/multiwaveview_target_placement_radius"
+ android:snapMargin="@dimen/multiwaveview_snap_margin"
+ android:hitRadius="@dimen/multiwaveview_hit_radius"
+ android:rightChevronDrawable="@drawable/ic_lockscreen_chevron_right"
+ android:feedbackCount="3"
+ android:vibrationDuration="20"
+ android:horizontalOffset="0dip"
+ android:verticalOffset="0dip"
+ />
<!-- emergency call button shown when sim is PUKd and tab_selector is hidden -->
<Button
diff --git a/core/res/res/values-mcc208-mnc10/config.xml b/core/res/res/values-mcc208-mnc10/config.xml
new file mode 100755
index 0000000..99cc599
--- /dev/null
+++ b/core/res/res/values-mcc208-mnc10/config.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
+ <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
+ <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
+ <integer-array translatable="false" name="config_tether_upstream_types">
+ <item>1</item>
+ <item>4</item>
+ </integer-array>
+
+ <!-- String containing the apn value for tethering. May be overriden by secure settings
+ TETHER_DUN_APN. Value is a comma separated series of strings:
+ "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+ note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
+ <string translatable="false" name="config_tether_apndata">SFR Option Modem,websfr,,,,,,,,,208,10,,DUN"</string>
+
+</resources>
diff --git a/core/res/res/values-sw600dp-land/arrays.xml b/core/res/res/values-sw600dp-land/arrays.xml
new file mode 100644
index 0000000..6304bc0
--- /dev/null
+++ b/core/res/res/values-sw600dp-land/arrays.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Resources for MultiWaveView in LockScreen -->
+ <array name="lockscreen_targets_when_silent">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_silent">
+ <item>@string/description_target_unlock</item>
+ <item>@null</item>
+ <item>@string/description_target_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_direction_descriptions">
+ <item>@string/description_direction_right</item>
+ <item>@null</item>
+ <item>@string/description_direction_left</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_when_soundon">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_soundon">
+ <item>@string/description_target_unlock</item>
+ <item>@null</item>
+ <item>@string/description_target_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_with_camera">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_with_camera">
+ <item>@string/description_target_unlock</item>
+ <item>@null</item>
+ <item>@string/description_target_camera</item>
+ <item>@null</item>
+ </array>
+
+</resources>
diff --git a/core/res/res/values-sw600dp/colors.xml b/core/res/res/values-sw600dp/colors.xml
index edd2712..f59b1f2 100644
--- a/core/res/res/values-sw600dp/colors.xml
+++ b/core/res/res/values-sw600dp/colors.xml
@@ -19,8 +19,8 @@
-->
<resources>
<!-- keyguard clock -->
- <color name="lockscreen_clock_background">#b3ffffff</color>
- <color name="lockscreen_clock_foreground">#7affffff</color>
+ <color name="lockscreen_clock_background">#ffffffff</color>
+ <color name="lockscreen_clock_foreground">#ffffffff</color>
<color name="lockscreen_clock_am_pm">#ffffffff</color>
<color name="lockscreen_owner_info">#ff9a9a9a</color>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index c37871b..b1a4b42 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -107,9 +107,9 @@
<color name="keyguard_text_color_decline">#fe0a5a</color>
<!-- keyguard clock -->
- <color name="lockscreen_clock_background">#e5ffffff</color>
- <color name="lockscreen_clock_foreground">#e5ffffff</color>
- <color name="lockscreen_clock_am_pm">#ff9a9a9a</color>
+ <color name="lockscreen_clock_background">#ffffffff</color>
+ <color name="lockscreen_clock_foreground">#ffffffff</color>
+ <color name="lockscreen_clock_am_pm">#ffffffff</color>
<color name="lockscreen_owner_info">#ff9a9a9a</color>
<!-- FaceLock -->
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
index b1546b6..6d32fba 100644
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
index bf1fc1b..fc2da4c 100644
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index b204303..ce2e072 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
index 51cf896..465dfc1 100644
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index cad89c2..2ccc927 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -1910,7 +1910,6 @@
<li>Search</li>
<li>Settings</li>
<li>Speech Recorder</li>
-<li>Speech Recorder</li>
<li>Widget Preview</li>
</ul>
</td>
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index e98d55c..08835fb 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -209,7 +209,6 @@
status_t prepareAsync_l();
status_t getDuration_l(int *msec);
status_t attachNewPlayer(const sp<IMediaPlayer>& player);
- void disconnectNativeWindow();
status_t reset_l();
sp<IMediaPlayer> mPlayer;
@@ -233,8 +232,6 @@
int mVideoHeight;
int mAudioSessionId;
float mSendLevel;
- sp<ANativeWindow> mConnectedWindow;
- sp<IBinder> mConnectedWindowBinder;
};
}; // namespace android
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 37a82e9..f72300b 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -86,8 +86,6 @@
if (p != 0) {
p->disconnect();
}
-
- disconnectNativeWindow();
}
// always call with lock held
@@ -221,63 +219,12 @@
return mPlayer->getMetadata(update_only, apply_filter, metadata);
}
-void MediaPlayer::disconnectNativeWindow() {
- if (mConnectedWindow != NULL) {
- status_t err = native_window_api_disconnect(mConnectedWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
-
- if (err != OK) {
- LOGW("native_window_api_disconnect returned an error: %s (%d)",
- strerror(-err), err);
- }
- }
- mConnectedWindow.clear();
-}
-
status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
{
LOGV("setVideoSurface");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
-
- sp<IBinder> binder(surface == NULL ? NULL : surface->asBinder());
- if (mConnectedWindowBinder == binder) {
- return OK;
- }
-
- if (surface != NULL) {
- status_t err = native_window_api_connect(surface.get(),
- NATIVE_WINDOW_API_MEDIA);
-
- if (err != OK) {
- LOGE("setVideoSurface failed: %d", err);
- // Note that we must do the reset before disconnecting from the ANW.
- // Otherwise queue/dequeue calls could be made on the disconnected
- // ANW, which may result in errors.
- reset_l();
-
- disconnectNativeWindow();
-
- return err;
- }
- }
-
- // Note that we must set the player's new surface before disconnecting the
- // old one. Otherwise queue/dequeue calls could be made on the disconnected
- // ANW, which may result in errors.
- status_t err = mPlayer->setVideoSurface(surface);
-
- disconnectNativeWindow();
-
- mConnectedWindow = surface;
-
- if (err == OK) {
- mConnectedWindowBinder = binder;
- } else {
- disconnectNativeWindow();
- }
-
- return err;
+ return mPlayer->setVideoSurface(surface);
}
status_t MediaPlayer::setVideoSurfaceTexture(
@@ -286,48 +233,7 @@
LOGV("setVideoSurfaceTexture");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
-
- sp<IBinder> binder(surfaceTexture == NULL ? NULL :
- surfaceTexture->asBinder());
- if (mConnectedWindowBinder == binder) {
- return OK;
- }
-
- sp<ANativeWindow> anw;
- if (surfaceTexture != NULL) {
- anw = new SurfaceTextureClient(surfaceTexture);
- status_t err = native_window_api_connect(anw.get(),
- NATIVE_WINDOW_API_MEDIA);
-
- if (err != OK) {
- LOGE("setVideoSurfaceTexture failed: %d", err);
- // Note that we must do the reset before disconnecting from the ANW.
- // Otherwise queue/dequeue calls could be made on the disconnected
- // ANW, which may result in errors.
- reset_l();
-
- disconnectNativeWindow();
-
- return err;
- }
- }
-
- // Note that we must set the player's new SurfaceTexture before
- // disconnecting the old one. Otherwise queue/dequeue calls could be made
- // on the disconnected ANW, which may result in errors.
- status_t err = mPlayer->setVideoSurfaceTexture(surfaceTexture);
-
- disconnectNativeWindow();
-
- mConnectedWindow = anw;
-
- if (err == OK) {
- mConnectedWindowBinder = binder;
- } else {
- disconnectNativeWindow();
- }
-
- return err;
+ return mPlayer->setVideoSurfaceTexture(surfaceTexture);
}
// must call with lock held
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 2ea2af9..b655358 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -40,6 +40,7 @@
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
+#include <gui/SurfaceTextureClient.h>
#include <utils/Errors.h> // for status_t
#include <utils/String8.h>
#include <utils/SystemClock.h>
@@ -528,6 +529,8 @@
p->reset();
}
+ disconnectNativeWindow();
+
IPCThreadState::self()->flushCommands();
}
@@ -793,13 +796,67 @@
return p->setVideoSurface(surface);
}
+void MediaPlayerService::Client::disconnectNativeWindow() {
+ if (mConnectedWindow != NULL) {
+ status_t err = native_window_api_disconnect(mConnectedWindow.get(),
+ NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ LOGW("native_window_api_disconnect returned an error: %s (%d)",
+ strerror(-err), err);
+ }
+ }
+ mConnectedWindow.clear();
+}
+
status_t MediaPlayerService::Client::setVideoSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture)
{
LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
- return p->setVideoSurfaceTexture(surfaceTexture);
+
+ sp<IBinder> binder(surfaceTexture == NULL ? NULL :
+ surfaceTexture->asBinder());
+ if (mConnectedWindowBinder == binder) {
+ return OK;
+ }
+
+ sp<ANativeWindow> anw;
+ if (surfaceTexture != NULL) {
+ anw = new SurfaceTextureClient(surfaceTexture);
+ status_t err = native_window_api_connect(anw.get(),
+ NATIVE_WINDOW_API_MEDIA);
+
+ if (err != OK) {
+ LOGE("setVideoSurfaceTexture failed: %d", err);
+ // Note that we must do the reset before disconnecting from the ANW.
+ // Otherwise queue/dequeue calls could be made on the disconnected
+ // ANW, which may result in errors.
+ reset();
+
+ disconnectNativeWindow();
+
+ return err;
+ }
+ }
+
+ // Note that we must set the player's new SurfaceTexture before
+ // disconnecting the old one. Otherwise queue/dequeue calls could be made
+ // on the disconnected ANW, which may result in errors.
+ status_t err = p->setVideoSurfaceTexture(surfaceTexture);
+
+ disconnectNativeWindow();
+
+ mConnectedWindow = anw;
+
+ if (err == OK) {
+ mConnectedWindowBinder = binder;
+ } else {
+ disconnectNativeWindow();
+ }
+
+ return err;
}
status_t MediaPlayerService::Client::invoke(const Parcel& request,
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 53e625a..62214ba 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -318,6 +318,9 @@
// @param type Of the metadata to be recorded.
void addNewMetadataUpdate(media::Metadata::Type type);
+ // Disconnect from the currently connected ANativeWindow.
+ void disconnectNativeWindow();
+
mutable Mutex mLock;
sp<MediaPlayerBase> mPlayer;
sp<MediaPlayerService> mService;
@@ -329,6 +332,8 @@
int32_t mConnId;
int mAudioSessionId;
uid_t mUID;
+ sp<ANativeWindow> mConnectedWindow;
+ sp<IBinder> mConnectedWindowBinder;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 4c710b4..7cdb76c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -796,7 +796,7 @@
return;
}
- driver->sendEvent(msg, ext1, ext2);
+ driver->notifyListener(msg, ext1, ext2);
}
void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index b1e917d..452ba99 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -35,6 +35,7 @@
mNumFramesDropped(0),
mLooper(new ALooper),
mState(UNINITIALIZED),
+ mAtEOS(false),
mStartupSeekTimeUs(-1) {
mLooper->setName("NuPlayerDriver Looper");
@@ -106,7 +107,7 @@
}
status_t NuPlayerDriver::prepareAsync() {
- sendEvent(MEDIA_PREPARED);
+ notifyListener(MEDIA_PREPARED);
return OK;
}
@@ -117,6 +118,7 @@
return INVALID_OPERATION;
case STOPPED:
{
+ mAtEOS = false;
mPlayer->start();
if (mStartupSeekTimeUs >= 0) {
@@ -173,7 +175,7 @@
}
bool NuPlayerDriver::isPlaying() {
- return mState == PLAYING;
+ return mState == PLAYING && !mAtEOS;
}
status_t NuPlayerDriver::seekTo(int msec) {
@@ -190,6 +192,7 @@
case PLAYING:
case PAUSED:
{
+ mAtEOS = false;
mPlayer->seekToAsync(seekTimeUs);
break;
}
@@ -291,7 +294,7 @@
}
void NuPlayerDriver::notifySeekComplete() {
- sendEvent(MEDIA_SEEK_COMPLETE);
+ notifyListener(MEDIA_SEEK_COMPLETE);
}
void NuPlayerDriver::notifyFrameStats(
@@ -320,4 +323,12 @@
return OK;
}
+void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
+ if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
+ mAtEOS = true;
+ }
+
+ sendEvent(msg, ext1, ext2);
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 181c37d..aaa3de0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -67,6 +67,7 @@
void notifyPosition(int64_t positionUs);
void notifySeekComplete();
void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped);
+ void notifyListener(int msg, int ext1 = 0, int ext2 = 0);
protected:
virtual ~NuPlayerDriver();
@@ -95,6 +96,7 @@
};
State mState;
+ bool mAtEOS;
int64_t mStartupSeekTimeUs;
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 79fcec0..8fba86a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -57,7 +57,7 @@
<dimen name="status_bar_icon_drawing_size">18dip</dimen>
<!-- opacity at which Notification icons will be drawn in the status bar -->
- <item type="dimen" name="status_bar_icon_drawing_alpha">50%</item>
+ <item type="dimen" name="status_bar_icon_drawing_alpha">55%</item>
<!-- gap on either side of status bar notification icons -->
<dimen name="status_bar_icon_padding">0dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 9bee5df..5f18b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -82,7 +82,7 @@
private boolean mVolumeVisible;
// bluetooth device status
- private boolean mBluetoothEnabled;
+ private boolean mBluetoothEnabled = false;
// wifi
private static final int[][] sWifiSignalImages = {
@@ -139,6 +139,18 @@
mContext = context;
mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
+ // listen for broadcasts
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_ALARM_CHANGED);
+ filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
+ mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+
// storage
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(
@@ -153,13 +165,15 @@
mService.setIconVisibility("cdma_eri", false);
// bluetooth status
- mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0, null);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ int bluetoothIcon = R.drawable.stat_sys_data_bluetooth;
if (adapter != null) {
- mBluetoothEnabled = adapter.isEnabled();
- } else {
- mBluetoothEnabled = false;
+ mBluetoothEnabled = (adapter.getState() == BluetoothAdapter.STATE_ON);
+ if (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) {
+ bluetoothIcon = R.drawable.stat_sys_data_bluetooth_connected;
+ }
}
+ mService.setIcon("bluetooth", bluetoothIcon, 0, null);
mService.setIconVisibility("bluetooth", mBluetoothEnabled);
// Alarm clock
@@ -176,19 +190,6 @@
mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
mService.setIconVisibility("volume", false);
updateVolume();
-
- IntentFilter filter = new IntentFilter();
-
- // Register for Intent broadcasts for...
- filter.addAction(Intent.ACTION_ALARM_CHANGED);
- filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
- filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
- filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
- mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
}
private final void updateAlarm(Intent intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 3a06068..5e5bc1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -45,6 +45,7 @@
private static final String TAG = "StatusBar.KeyButtonView";
final float GLOW_MAX_SCALE_FACTOR = 1.8f;
+ final float BUTTON_QUIESCENT_ALPHA = 0.6f;
IWindowManager mWindowManager;
long mDownTime;
@@ -86,7 +87,7 @@
mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
if (mGlowBG != null) {
- mDrawingAlpha = 0.5f;
+ mDrawingAlpha = BUTTON_QUIESCENT_ALPHA;
}
a.recycle();
@@ -175,8 +176,10 @@
if (pressed != isPressed()) {
AnimatorSet as = new AnimatorSet();
if (pressed) {
- if (mGlowScale < 1.7f) mGlowScale = 1.7f;
- if (mGlowAlpha < 0.5f) mGlowAlpha = 0.5f;
+ if (mGlowScale < GLOW_MAX_SCALE_FACTOR)
+ mGlowScale = GLOW_MAX_SCALE_FACTOR;
+ if (mGlowAlpha < BUTTON_QUIESCENT_ALPHA)
+ mGlowAlpha = BUTTON_QUIESCENT_ALPHA;
setDrawingAlpha(1f);
as.playTogether(
ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
@@ -187,7 +190,7 @@
as.playTogether(
ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
ObjectAnimator.ofFloat(this, "glowScale", 1f),
- ObjectAnimator.ofFloat(this, "drawingAlpha", 0.5f)
+ ObjectAnimator.ofFloat(this, "drawingAlpha", BUTTON_QUIESCENT_ALPHA)
);
as.setDuration(500);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java
index 0121211..f98caa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HoloClock.java
@@ -53,9 +53,9 @@
private SimpleDateFormat mClockFormat;
private static final String FONT_DIR = "/system/fonts/";
- private static final String CLOCK_FONT = FONT_DIR + "AndroidClock_Solid.ttf";
- private static final String CLOCK_FG_FONT = FONT_DIR + "AndroidClock.ttf";
- private static final String CLOCK_BG_FONT = FONT_DIR + "AndroidClock_Highlight.ttf";
+ private static final String CLOCK_FONT = FONT_DIR + "AndroidClock_Solid.ttf";
+ private static final String CLOCK_FG_FONT = FONT_DIR + "AndroidClock.ttf";
+ private static final String CLOCK_BG_FONT = FONT_DIR + "AndroidClock_Highlight.ttf";
private static Typeface sBackgroundType, sForegroundType, sSolidType;
private TextView mSolidText, mBgText, mFgText;
@@ -84,7 +84,9 @@
mBgText = (TextView) findViewById(R.id.time_bg);
if (mBgText != null) {
mBgText.setTypeface(sBackgroundType);
+ mBgText.setVisibility(View.INVISIBLE);
}
+
mFgText = (TextView) findViewById(R.id.time_fg);
if (mFgText != null) {
mFgText.setTypeface(sForegroundType);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 6614d79..dafbdcf 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -635,11 +635,13 @@
* @return
*/
private static CharSequence makeCarierString(CharSequence plmn, CharSequence spn) {
- if (plmn != null && spn == null) {
- return plmn;
- } else if (plmn != null && spn != null) {
+ final boolean plmnValid = !TextUtils.isEmpty(plmn);
+ final boolean spnValid = !TextUtils.isEmpty(spn);
+ if (plmnValid && spnValid) {
return plmn + "|" + spn;
- } else if (plmn == null && spn != null) {
+ } else if (plmnValid) {
+ return plmn;
+ } else if (spnValid) {
return spn;
} else {
return "";
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 498bdfc..851cb33 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -2450,6 +2450,12 @@
int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
+ // Short term disabling of Tethering if DUN is required.
+ // TODO - fix multi-connection tethering using policy-base routing
+ int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes();
+ for (int i : upstreamConnTypes) {
+ if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false;
+ }
return tetherEnabledInSettings && mTetheringConfigValid;
}
diff --git a/telephony/java/com/android/internal/telephony/IntRangeManager.java b/telephony/java/com/android/internal/telephony/IntRangeManager.java
index 970bc44..cc7774d 100644
--- a/telephony/java/com/android/internal/telephony/IntRangeManager.java
+++ b/telephony/java/com/android/internal/telephony/IntRangeManager.java
@@ -543,6 +543,14 @@
}
/**
+ * Returns whether the list of ranges is completely empty.
+ * @return true if there are no enabled ranges
+ */
+ public boolean isEmpty() {
+ return mRanges.isEmpty();
+ }
+
+ /**
* Called when the list of enabled ranges has changed. This will be
* followed by zero or more calls to {@link #addRange} followed by
* a call to {@link #finishUpdate}.
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index e8d85de..9f93fb8 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1956,7 +1956,7 @@
if (RILJ_LOGD) {
riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " with " + numOfConfig + "configs : ");
+ + " with " + numOfConfig + " configs : ");
for (int i = 0; i < numOfConfig; i++) {
riljLog(config[i].toString());
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
index 8d0e5d3..92bf390 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
@@ -246,6 +246,8 @@
log("Added cell broadcast subscription for MID range " + startMessageId
+ " to " + endMessageId + " from client " + client);
+ setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
+
return true;
}
@@ -271,6 +273,8 @@
log("Removed cell broadcast subscription for MID range " + startMessageId
+ " to " + endMessageId + " from client " + client);
+ setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
+
return true;
}
@@ -301,14 +305,15 @@
/**
* Called to indicate the end of a range update started by the
* previous call to {@link #startUpdate}.
+ * @return true if successful, false otherwise
*/
protected boolean finishUpdate() {
if (mConfigList.isEmpty()) {
- return setCellBroadcastActivation(false);
+ return true;
} else {
SmsBroadcastConfigInfo[] configs =
mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
- return setCellBroadcastConfig(configs) && setCellBroadcastActivation(true);
+ return setCellBroadcastConfig(configs);
}
}
}
diff --git a/tests/FrameworkPerf/Android.mk b/tests/FrameworkPerf/Android.mk
new file mode 100644
index 0000000..03893d6
--- /dev/null
+++ b/tests/FrameworkPerf/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := FrameworkPerf
+
+LOCAL_AAPT_FLAGS = -c 120dpi,240dpi,160dpi,161dpi,320dpi,nodpi
+
+include $(BUILD_PACKAGE)
diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml
new file mode 100644
index 0000000..f69d550
--- /dev/null
+++ b/tests/FrameworkPerf/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworkperf">
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-sdk android:minSdkVersion="5" />
+
+ <application>
+ <activity android:name="FrameworkPerfActivity" android:label="Framework Perf">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <service android:name="SchedulerService">
+ </service>
+ </application>
+</manifest>
diff --git a/tests/FrameworkPerf/res/drawable-161dpi/stat_sample_scale.png b/tests/FrameworkPerf/res/drawable-161dpi/stat_sample_scale.png
new file mode 100755
index 0000000..6c9ba0a
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-161dpi/stat_sample_scale.png
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg b/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg
new file mode 100644
index 0000000..2271091
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-hdpi/stat_happy.png b/tests/FrameworkPerf/res/drawable-hdpi/stat_happy.png
new file mode 100755
index 0000000..27f5bb7
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-hdpi/stat_happy.png
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-mdpi/stat_happy.png b/tests/FrameworkPerf/res/drawable-mdpi/stat_happy.png
new file mode 100644
index 0000000..3a8791b
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-mdpi/stat_happy.png
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-nodpi/stat_sample.png b/tests/FrameworkPerf/res/drawable-nodpi/stat_sample.png
new file mode 100755
index 0000000..6c9ba0a
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-nodpi/stat_sample.png
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg b/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg
new file mode 100644
index 0000000..2271091
--- /dev/null
+++ b/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg
Binary files differ
diff --git a/tests/FrameworkPerf/res/layout/large_layout.xml b/tests/FrameworkPerf/res/layout/large_layout.xml
new file mode 100644
index 0000000..b6ac88c
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/large_layout.xml
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<!-- All ids in this layout must be in wifi_dialog.xml -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- UI components that should be shown appropriately -->
+ <FrameLayout
+ android:id="@+id/eap_not_supported"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="360dip"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:lineSpacingExtra="12dip"
+ android:text="Foo"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </FrameLayout>
+ <!-- In "add network" flow, we have security type field (@id/security below) below
+ this View, so need a bit different layout than the other flow, in which we'll use
+ @id/eap_not_supported. -->
+ <FrameLayout
+ android:id="@+id/eap_not_supported_for_add_network"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:lineSpacingExtra="12dip"
+ android:text="Bar"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </FrameLayout>
+ <LinearLayout
+ android:id="@+id/wps_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:layout_width="match_parent"
+ android:minWidth="128dip"
+ android:layout_height="wrap_content"
+ android:text="Blah"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp"
+ android:gravity="bottom" />
+
+ <EditText
+ android:id="@+id/wps_pin"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textPassword"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </LinearLayout>
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dip">
+ <!-- To accomodate @id/type into TableLayout, we splitted the layout into two:
+ @id/type_ssid and @id/type_security. -->
+ <TableRow
+ android:id="@+id/type_ssid"
+ android:minHeight="56dip"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/ssid_text"
+ android:layout_width="wrap_content"
+ android:minWidth="128dip"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:paddingRight="16dip"
+ android:layout_alignParentLeft="true"
+ android:text="Whatever"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp"
+ android:gravity="left|center_vertical" />
+
+ <FrameLayout
+ android:id="@+id/ssid_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@id/ssid_text"
+ android:layout_toRightOf="@id/ssid_text">
+ <EditText
+ android:id="@+id/ssid"
+ android:layout_width="368dip"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </FrameLayout>
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/security_fields"
+ android:minHeight="56dip"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/password_text"
+ android:layout_width="wrap_content"
+ android:minWidth="128dip"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:text="Whenever"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp"
+ android:gravity="left|center_vertical" />
+
+ <LinearLayout
+ android:id="@+id/password_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="bottom">
+ <EditText
+ android:id="@+id/password"
+ android:layout_width="368dip"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:singleLine="true"
+ android:password="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </LinearLayout>
+
+ <!-- It looks CheckBox isn't aligned well with TableRow -->
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <CheckBox
+ android:id="@+id/show_password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:text="However"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp" />
+ </FrameLayout>
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/type_security"
+ android:minHeight="56dip"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/security_text"
+ android:layout_width="wrap_content"
+ android:minWidth="128dip"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:text="Whoever"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp"
+ android:gravity="bottom"/>
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="bottom">
+ <Spinner
+ android:id="@+id/security"
+ android:layout_width="368dip"
+ android:layout_height="wrap_content"
+ android:minHeight="56dip"
+ android:paddingLeft="4dip"/>
+ </FrameLayout>
+ </TableRow>
+ </TableLayout>
+
+ <!-- All the views below are "gone".
+ We want them as data storage, not as UI components. -->
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone">
+
+ <LinearLayout android:id="@+id/info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"/>
+
+ <LinearLayout android:id="@+id/setup_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="On the top" />
+
+ <Spinner android:id="@+id/network_setup"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+ <!-- android:id="@+id/security_fields" -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <LinearLayout android:id="@+id/eap"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="On the bottom" />
+
+ <Spinner android:id="@+id/method"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="On the side" />
+
+ <Spinner android:id="@+id/phase2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="SRH" />
+
+ <Spinner android:id="@+id/ca_cert"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Enjoyable" />
+
+ <Spinner android:id="@+id/user_cert"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Fantastic" />
+
+ <EditText android:id="@+id/identity"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Superb" />
+
+ <EditText android:id="@+id/anonymous"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+ </LinearLayout> <!-- android:id="@+id/eap" -->
+
+ <!-- <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/wifi_password" />
+
+ <EditText android:id="@+id/password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:password="true" />
+
+ <CheckBox android:id="@+id/show_password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/wifi_show_password" /> -->
+ </LinearLayout> <!-- android:id="@+id/security_fields" -->
+
+ <LinearLayout android:id="@+id/proxy_settings_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <TextView android:id="@+id/proxy_settings_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Heavenly" />
+
+ <Spinner android:id="@+id/proxy_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/proxy_warning_limited_support"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <!-- Dummy to enable right-justification of warning -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Orgasmic" />
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/proxy_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Really" />
+
+ <EditText android:id="@+id/proxy_hostname"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Really really" />
+
+ <EditText android:id="@+id/proxy_port"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Really really with cherries on top" />
+
+ <EditText android:id="@+id/proxy_exclusionlist"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/ip_fields"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Mmmmm... cherries" />
+
+ <Spinner android:id="@+id/ip_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/staticip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="I mean Mmmmm.. cherries" />
+
+ <EditText android:id="@+id/ipaddress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Shorter" />
+
+ <EditText android:id="@+id/gateway"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="is" />
+
+ <EditText android:id="@+id/network_prefix_length"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="better" />
+
+ <EditText android:id="@+id/dns1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="always" />
+
+ <EditText android:id="@+id/dns2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkPerf/res/layout/main.xml b/tests/FrameworkPerf/res/layout/main.xml
new file mode 100644
index 0000000..2e9c500
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/main.xml
@@ -0,0 +1,54 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <Button android:id="@+id/start"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start"
+ />
+ <Button android:id="@+id/stop"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/stop"
+ />
+ </LinearLayout>
+
+ <ScrollView android:id="@+id/scroll"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ >
+ <TextView android:id="@+id/log"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="25dp"
+ android:textSize="12sp"
+ android:textColor="#ffffffff"
+ />
+ </ScrollView>
+
+</LinearLayout>
diff --git a/tests/FrameworkPerf/res/layout/small_layout.xml b/tests/FrameworkPerf/res/layout/small_layout.xml
new file mode 100644
index 0000000..9fcbb26
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/small_layout.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+
+ <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
+
+ <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
+ <TextView android:text="Foo" android:layout_width="wrap_content" android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
+ <TextView android:id="@+id/config_list" android:layout_width="wrap_content" android:layout_height="wrap_content" />
+ </LinearLayout>
+ </LinearLayout>
+
+</ScrollView>
+
diff --git a/tests/FrameworkPerf/res/values/attrs.xml b/tests/FrameworkPerf/res/values/attrs.xml
new file mode 100644
index 0000000..5823537
--- /dev/null
+++ b/tests/FrameworkPerf/res/values/attrs.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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>
+ <!-- Base attributes that are available to all Item objects. -->
+ <declare-styleable name="MenuItem">
+
+ <!-- The ID of the item. -->
+ <attr name="android:id" />
+
+ <!-- The category applied to the item.
+ (This will be or'ed with the orderInCategory attribute.) -->
+ <attr name="android:menuCategory" />
+
+ <!-- The order within the category applied to the item.
+ (This will be or'ed with the category attribute.) -->
+ <attr name="android:orderInCategory" />
+
+ <!-- The title associated with the item. -->
+ <attr name="android:title" />
+
+ <!-- The condensed title associated with the item. This is used in situations where the
+ normal title may be too long to be displayed. -->
+ <attr name="android:titleCondensed" />
+
+ <!-- The icon associated with this item. This icon will not always be shown, so
+ the title should be sufficient in describing this item. -->
+ <attr name="android:icon" />
+
+ <!-- The alphabetic shortcut key. This is the shortcut when using a keyboard
+ with alphabetic keys. -->
+ <attr name="android:alphabeticShortcut" />
+
+ <!-- The numeric shortcut key. This is the shortcut when using a numeric (e.g., 12-key)
+ keyboard. -->
+ <attr name="android:numericShortcut" />
+
+ <!-- Whether the item is capable of displaying a check mark. -->
+ <attr name="android:checkable" />
+
+ <!-- Whether the item is checked. Note that you must first have enabled checking with
+ the checkable attribute or else the check mark will not appear. -->
+ <attr name="android:checked" />
+
+ <!-- Whether the item is shown/visible. -->
+ <attr name="android:visible" />
+
+ <!-- Whether the item is enabled. -->
+ <attr name="android:enabled" />
+ </declare-styleable>
+</resources>
diff --git a/tests/FrameworkPerf/res/values/strings.xml b/tests/FrameworkPerf/res/values/strings.xml
new file mode 100644
index 0000000..82fd713
--- /dev/null
+++ b/tests/FrameworkPerf/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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>
+ <string name="start">Start</string>
+ <string name="stop">Stop</string>
+ <string name="data_usage_menu_roaming">Data roaming</string>
+ <string name="data_usage_menu_restrict_background">Restrict background data</string>
+ <string name="data_usage_menu_split_4g">Separate 4G usage</string>
+ <string name="data_usage_menu_show_wifi">Show Wi-Fi usage</string>
+ <string name="data_usage_menu_show_ethernet">Show Ethernet usage</string>
+</resources>
diff --git a/tests/FrameworkPerf/res/xml/simple.xml b/tests/FrameworkPerf/res/xml/simple.xml
new file mode 100644
index 0000000..4e938aa
--- /dev/null
+++ b/tests/FrameworkPerf/res/xml/simple.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+</menu>
diff --git a/tests/FrameworkPerf/res/xml/simple_large.xml b/tests/FrameworkPerf/res/xml/simple_large.xml
new file mode 100644
index 0000000..812cec9
--- /dev/null
+++ b/tests/FrameworkPerf/res/xml/simple_large.xml
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_roaming"
+ android:title="@string/data_usage_menu_roaming"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_restrict_background"
+ android:title="@string/data_usage_menu_restrict_background"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_split_4g"
+ android:title="@string/data_usage_menu_split_4g"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_wifi"
+ android:title="@string/data_usage_menu_show_wifi"
+ android:checkable="true" />
+ <item
+ android:id="@+id/data_usage_menu_show_ethernet"
+ android:title="@string/data_usage_menu_show_ethernet"
+ android:checkable="true" />
+</menu>
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
new file mode 100644
index 0000000..9f05a55
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -0,0 +1,694 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * So you thought sync used up your battery life.
+ */
+public class FrameworkPerfActivity extends Activity {
+ final Handler mHandler = new Handler();
+
+ TextView mLog;
+ PowerManager.WakeLock mPartialWakeLock;
+
+ long mMaxRunTime = 5000;
+ boolean mStarted;
+
+ final TestRunner mRunner = new TestRunner();
+
+ final Op[] mOpPairs = new Op[] {
+ new MethodCallOp(), new NoOp(),
+ new MethodCallOp(), new CpuOp(),
+ new MethodCallOp(), new SchedulerOp(),
+ new MethodCallOp(), new GcOp(),
+ new SchedulerOp(), new SchedulerOp(),
+ new GcOp(), new NoOp(),
+ new IpcOp(), new NoOp(),
+ new IpcOp(), new CpuOp(),
+ new IpcOp(), new SchedulerOp(),
+ new IpcOp(), new GcOp(),
+ new ParseXmlResOp(), new NoOp(),
+ new ParseLargeXmlResOp(), new NoOp(),
+ new LayoutInflaterOp(), new NoOp(),
+ new LayoutInflaterLargeOp(), new NoOp(),
+ new LoadSmallBitmapOp(), new NoOp(),
+ new LoadLargeBitmapOp(), new NoOp(),
+ new LoadSmallScaledBitmapOp(), new NoOp(),
+ new LoadLargeScaledBitmapOp(), new NoOp(),
+ };
+
+ final Op[] mAvailOps = new Op[] {
+ new NoOp(),
+ new CpuOp(),
+ new SchedulerOp(),
+ new MethodCallOp(),
+ new IpcOp(),
+ new ParseXmlResOp(),
+ new ParseLargeXmlResOp(),
+ new LoadSmallBitmapOp(),
+ new LoadLargeBitmapOp(),
+ new LoadSmallScaledBitmapOp(),
+ new LoadLargeScaledBitmapOp(),
+ };
+
+ int mCurOpIndex = 0;
+
+ class RunResult {
+ final String name;
+ final String fgLongName;
+ final String bgLongName;
+ final long fgTime;
+ final long fgOps;
+ final long bgTime;
+ final long bgOps;
+
+ RunResult(TestRunner op) {
+ name = op.getName();
+ fgLongName = op.getForegroundLongName();
+ bgLongName = op.getBackgroundLongName();
+ fgTime = op.getForegroundTime();
+ fgOps = op.getForegroundOps();
+ bgTime = op.getBackgroundTime();
+ bgOps = op.getBackgroundOps();
+ }
+
+ float getFgMsPerOp() {
+ return fgOps != 0 ? (fgTime / (float)fgOps) : 0;
+ }
+
+ float getBgMsPerOp() {
+ return bgOps != 0 ? (bgTime / (float)bgOps) : 0;
+ }
+ }
+
+ final ArrayList<RunResult> mResults = new ArrayList<RunResult>();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the layout for this activity. You can find it
+ // in res/layout/hello_activity.xml
+ setContentView(R.layout.main);
+
+ findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ startRunning();
+ }
+ });
+ findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ stopRunning();
+ }
+ });
+ mLog = (TextView)findViewById(R.id.log);
+
+ PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
+ mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Scheduler");
+ mPartialWakeLock.setReferenceCounted(false);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ stopRunning();
+ if (mPartialWakeLock.isHeld()) {
+ mPartialWakeLock.release();
+ }
+ }
+
+ void startCurOp() {
+ mRunner.run(mHandler, mOpPairs[mCurOpIndex], mOpPairs[mCurOpIndex+1], new Runnable() {
+ @Override public void run() {
+ RunResult result = new RunResult(mRunner);
+ log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)",
+ result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime,
+ result.bgOps, result.getBgMsPerOp(), result.bgTime));
+ mResults.add(result);
+ if (!mStarted) {
+ log("Stop");
+ stopRunning();
+ return;
+ }
+ mCurOpIndex+=2;
+ if (mCurOpIndex >= mOpPairs.length) {
+ log("Finished");
+ stopRunning();
+ return;
+ }
+ startCurOp();
+ }
+ });
+ }
+
+ void startRunning() {
+ if (!mStarted) {
+ log("Start");
+ mStarted = true;
+ updateWakeLock();
+ startService(new Intent(this, SchedulerService.class));
+ mCurOpIndex = 0;
+ mResults.clear();
+ startCurOp();
+ }
+ }
+
+ void stopRunning() {
+ if (mStarted) {
+ mStarted = false;
+ updateWakeLock();
+ stopService(new Intent(this, SchedulerService.class));
+ for (int i=0; i<mResults.size(); i++) {
+ RunResult result = mResults.get(i);
+ float fgMsPerOp = result.getFgMsPerOp();
+ float bgMsPerOp = result.getBgMsPerOp();
+ String fgMsPerOpStr = fgMsPerOp != 0 ? Float.toString(fgMsPerOp) : "";
+ String bgMsPerOpStr = bgMsPerOp != 0 ? Float.toString(bgMsPerOp) : "";
+ Log.i("Perf", "\t" + result.name + "\t" + result.fgOps
+ + "\t" + result.getFgMsPerOp() + "\t" + result.fgTime
+ + "\t" + result.fgLongName + "\t" + result.bgOps
+ + "\t" + result.getBgMsPerOp() + "\t" + result.bgTime
+ + "\t" + result.bgLongName);
+ }
+ }
+ }
+
+ void updateWakeLock() {
+ if (mStarted) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ if (!mPartialWakeLock.isHeld()) {
+ mPartialWakeLock.acquire();
+ }
+ } else {
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ if (mPartialWakeLock.isHeld()) {
+ mPartialWakeLock.release();
+ }
+ }
+ }
+
+ void log(String s) {
+ mLog.setText(mLog.getText() + "\n" + s);
+ Log.i("Perf", s);
+ }
+
+ enum BackgroundMode {
+ NOTHING,
+ CPU,
+ SCHEDULER
+ };
+
+ public class TestRunner {
+ Handler mHandler;
+ Op mForegroundOp;
+ Op mBackgroundOp;
+ Runnable mDoneCallback;
+
+ RunnerThread mBackgroundThread;
+ RunnerThread mForegroundThread;
+ long mStartTime;
+
+ boolean mBackgroundRunning;
+ boolean mForegroundRunning;
+
+ long mBackgroundEndTime;
+ long mBackgroundOps;
+ long mForegroundEndTime;
+ long mForegroundOps;
+
+ public TestRunner() {
+ }
+
+ public String getForegroundName() {
+ return mForegroundOp.getName();
+ }
+
+ public String getBackgroundName() {
+ return mBackgroundOp.getName();
+ }
+
+ public String getName() {
+ String fgName = mForegroundOp.getName();
+ String bgName = mBackgroundOp.getName();
+ StringBuilder res = new StringBuilder();
+ if (fgName != null) {
+ res.append(fgName);
+ res.append("Fg");
+ }
+ if (bgName != null) {
+ res.append(bgName);
+ res.append("Bg");
+ }
+ return res.toString();
+ }
+
+ public String getForegroundLongName() {
+ return mForegroundOp.getLongName();
+ }
+
+ public String getBackgroundLongName() {
+ return mBackgroundOp.getLongName();
+ }
+
+ public void run(Handler handler, Op foreground, Op background, Runnable doneCallback) {
+ mHandler = handler;
+ mForegroundOp = foreground;
+ mBackgroundOp = background;
+ mDoneCallback = doneCallback;
+ mBackgroundThread = new RunnerThread("background", new Runnable() {
+ @Override public void run() {
+ boolean running;
+ int ops = 0;
+ do {
+ running = mBackgroundOp.onRun();
+ ops++;
+ } while (evalRepeat(running, true) && running);
+ mBackgroundEndTime = SystemClock.uptimeMillis();
+ mBackgroundOps = ops * mBackgroundOp.getOpsPerRun();
+ threadFinished(false);
+ }
+ }, Process.THREAD_PRIORITY_BACKGROUND);
+ mForegroundThread = new RunnerThread("background", new Runnable() {
+ @Override public void run() {
+ boolean running;
+ int ops = 0;
+ do {
+ running = mForegroundOp.onRun();
+ ops++;
+ } while (evalRepeat(true, running) && running);
+ mForegroundEndTime = SystemClock.uptimeMillis();
+ mForegroundOps = ops * mForegroundOp.getOpsPerRun();
+ threadFinished(true);
+ }
+ }, Process.THREAD_PRIORITY_FOREGROUND);
+
+ mForegroundOp.onInit(FrameworkPerfActivity.this);
+ mBackgroundOp.onInit(FrameworkPerfActivity.this);
+
+ synchronized (this) {
+ mStartTime = SystemClock.uptimeMillis();
+ mBackgroundRunning = true;
+ mForegroundRunning = true;
+ }
+
+ mBackgroundThread.start();
+ mForegroundThread.start();
+ }
+
+ public long getForegroundTime() {
+ return mForegroundEndTime-mStartTime;
+ }
+
+ public long getForegroundOps() {
+ return mForegroundOps;
+ }
+
+ public long getBackgroundTime() {
+ return mBackgroundEndTime-mStartTime;
+ }
+
+ public long getBackgroundOps() {
+ return mBackgroundOps;
+ }
+
+ private boolean evalRepeat(boolean bgRunning, boolean fgRunning) {
+ synchronized (this) {
+ if (!bgRunning) {
+ mBackgroundRunning = false;
+ }
+ if (!fgRunning) {
+ mForegroundRunning = false;
+ }
+ if (!mBackgroundRunning && !mForegroundRunning) {
+ return false;
+ }
+ long now = SystemClock.uptimeMillis();
+ if (now > (mStartTime+mMaxRunTime)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ private void threadFinished(boolean foreground) {
+ synchronized (this) {
+ if (foreground) {
+ mForegroundRunning = false;
+ } else {
+ mBackgroundRunning = false;
+ }
+ if (!mBackgroundRunning && !mForegroundRunning) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ if (mDoneCallback != null) {
+ mDoneCallback.run();
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+
+ class RunnerThread extends Thread {
+ private final Runnable mOp;
+ private final int mPriority;
+
+ RunnerThread(String name, Runnable op, int priority) {
+ super(name);
+ mOp = op;
+ mPriority = priority;
+ }
+
+ public void run() {
+ Process.setThreadPriority(mPriority);
+ mOp.run();
+ }
+ }
+
+ static public abstract class Op {
+ final String mName;
+ final String mLongName;
+
+ public Op(String name, String longName) {
+ mName = name;
+ mLongName = longName;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getLongName() {
+ return mLongName;
+ }
+
+ void onInit(Context context) {
+ }
+
+ abstract boolean onRun();
+
+ int getOpsPerRun() {
+ return 1;
+ }
+ }
+
+ static class NoOp extends Op {
+ NoOp() {
+ super(null, "Nothing");
+ }
+
+ boolean onRun() {
+ return false;
+ }
+
+ int getOpsPerRun() {
+ return 0;
+ }
+ }
+
+ static class CpuOp extends Op {
+ CpuOp() {
+ super("CPU", "Consume CPU");
+ }
+
+ boolean onRun() {
+ return true;
+ }
+ }
+
+ static class SchedulerOp extends Op {
+ SchedulerOp() {
+ super("Sched", "Change scheduler group");
+ }
+
+ boolean onRun() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ return true;
+ }
+ }
+
+ static class GcOp extends Op {
+ GcOp() {
+ super("Gc", "Run garbage collector");
+ }
+
+ boolean onRun() {
+ byte[] stuff = new byte[1024*1024];
+ return true;
+ }
+ }
+
+ static class MethodCallOp extends Op {
+ MethodCallOp() {
+ super("MethodCall", "Method call");
+ }
+
+ boolean onRun() {
+ final int N = getOpsPerRun();
+ for (int i=0; i<N; i++) {
+ someFunc(i);
+ }
+ return true;
+ }
+
+ int someFunc(int foo) {
+ return 0;
+ }
+
+ int getOpsPerRun() {
+ return 500;
+ }
+ }
+
+ static class IpcOp extends Op {
+ PackageManager mPm;
+ String mProcessName;
+
+ IpcOp() {
+ super("Ipc", "IPC to system process");
+ }
+
+ void onInit(Context context) {
+ mPm = context.getPackageManager();
+ mProcessName = context.getApplicationInfo().processName;
+ }
+
+ boolean onRun() {
+ final int N = getOpsPerRun();
+ for (int i=0; i<N; i++) {
+ mPm.queryContentProviders(mProcessName, Process.myUid(), 0);
+ }
+ return true;
+ }
+
+ int getOpsPerRun() {
+ return 100;
+ }
+ }
+
+ static class ParseXmlResOp extends Op {
+ Context mContext;
+
+ ParseXmlResOp() {
+ super("ParseXmlRes", "Parse compiled XML resource");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ SimpleInflater inf = new SimpleInflater(mContext);
+ inf.inflate(R.xml.simple);
+ return true;
+ }
+ }
+
+ static class ParseLargeXmlResOp extends Op {
+ Context mContext;
+
+ ParseLargeXmlResOp() {
+ super("ParseLargeXmlRes", "Parse large XML resource");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ SimpleInflater inf = new SimpleInflater(mContext);
+ inf.inflate(R.xml.simple_large);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterOp extends Op {
+ Context mContext;
+
+ LayoutInflaterOp() {
+ super("LayoutInflaterOp", "Inflate layout resource");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.small_layout, null);
+ return true;
+ }
+ }
+
+ static class LayoutInflaterLargeOp extends Op {
+ Context mContext;
+
+ LayoutInflaterLargeOp() {
+ super("LayoutInflaterLargeOp", "Inflate large layout resource");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inf.inflate(R.layout.large_layout, null);
+ return true;
+ }
+ }
+
+ static class LoadSmallBitmapOp extends Op {
+ Context mContext;
+
+ LoadSmallBitmapOp() {
+ super("LoadSmallBitmap", "Load small raw bitmap");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.stat_sample, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadLargeBitmapOp extends Op {
+ Context mContext;
+
+ LoadLargeBitmapOp() {
+ super("LoadLargeBitmap", "Load large raw bitmap");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.wallpaper_goldengate, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadSmallScaledBitmapOp extends Op {
+ Context mContext;
+
+ LoadSmallScaledBitmapOp() {
+ super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.stat_sample_scale, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+
+ static class LoadLargeScaledBitmapOp extends Op {
+ Context mContext;
+
+ LoadLargeScaledBitmapOp() {
+ super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density");
+ }
+
+ void onInit(Context context) {
+ mContext = context;
+ }
+
+ boolean onRun() {
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+ Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.wallpaper_goldengate_scale, opts);
+ bm.recycle();
+ return true;
+ }
+ }
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java
new file mode 100644
index 0000000..7691e64
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class SchedulerService extends Service {
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Notification status = new Notification(R.drawable.stat_happy, null,
+ System.currentTimeMillis());
+ status.flags |= Notification.FLAG_ONGOING_EVENT;
+ status.setLatestEventInfo(this, "Scheduler Test running",
+ "Scheduler Test running", PendingIntent.getActivity(this, 0,
+ new Intent(this, FrameworkPerfActivity.class)
+ .setAction(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0));
+ startForeground(1, status);
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/SimpleInflater.java b/tests/FrameworkPerf/src/com/android/frameworkperf/SimpleInflater.java
new file mode 100644
index 0000000..5cbb12a
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/SimpleInflater.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import java.io.IOException;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.InflateException;
+
+public class SimpleInflater {
+ /** Menu tag name in XML. */
+ private static final String XML_MENU = "menu";
+
+ /** Group tag name in XML. */
+ private static final String XML_GROUP = "group";
+
+ /** Item tag name in XML. */
+ private static final String XML_ITEM = "item";
+
+ private Context mContext;
+
+ public SimpleInflater(Context context) {
+ mContext = context;
+ }
+
+ public void inflate(int menuRes) {
+ XmlResourceParser parser = null;
+ try {
+ parser = mContext.getResources().getLayout(menuRes);
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ parseMenu(parser, attrs);
+ } catch (XmlPullParserException e) {
+ throw new InflateException("Error inflating menu XML", e);
+ } catch (IOException e) {
+ throw new InflateException("Error inflating menu XML", e);
+ } finally {
+ if (parser != null) parser.close();
+ }
+ }
+
+ private void parseMenu(XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ int eventType = parser.getEventType();
+ String tagName;
+ boolean lookingForEndOfUnknownTag = false;
+ String unknownTagName = null;
+
+ // This loop will skip to the menu start tag
+ do {
+ if (eventType == XmlPullParser.START_TAG) {
+ tagName = parser.getName();
+ if (tagName.equals(XML_MENU)) {
+ // Go to next tag
+ eventType = parser.next();
+ break;
+ }
+
+ throw new RuntimeException("Expecting menu, got " + tagName);
+ }
+ eventType = parser.next();
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ boolean reachedEndOfMenu = false;
+ while (!reachedEndOfMenu) {
+ switch (eventType) {
+ case XmlPullParser.START_TAG:
+ if (lookingForEndOfUnknownTag) {
+ break;
+ }
+
+ tagName = parser.getName();
+ if (tagName.equals(XML_ITEM)) {
+ readItem(attrs);
+ } else if (tagName.equals(XML_MENU)) {
+ parseMenu(parser, attrs);
+ } else {
+ lookingForEndOfUnknownTag = true;
+ unknownTagName = tagName;
+ }
+ break;
+
+ case XmlPullParser.END_TAG:
+ tagName = parser.getName();
+ if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) {
+ lookingForEndOfUnknownTag = false;
+ unknownTagName = null;
+ } else if (tagName.equals(XML_ITEM)) {
+ } else if (tagName.equals(XML_MENU)) {
+ reachedEndOfMenu = true;
+ }
+ break;
+
+ case XmlPullParser.END_DOCUMENT:
+ throw new RuntimeException("Unexpected end of document");
+ }
+
+ eventType = parser.next();
+ }
+ }
+
+ public void readItem(AttributeSet attrs) {
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.MenuItem);
+
+ // Inherit attributes from the group as default value
+ int itemId = a.getResourceId(R.styleable.MenuItem_android_id, 0);
+ final int category = a.getInt(R.styleable.MenuItem_android_menuCategory, 0);
+ final int order = a.getInt(R.styleable.MenuItem_android_orderInCategory, 0);
+ CharSequence itemTitle = a.getText(R.styleable.MenuItem_android_title);
+ CharSequence itemTitleCondensed = a.getText(R.styleable.MenuItem_android_titleCondensed);
+ int itemIconResId = a.getResourceId(R.styleable.MenuItem_android_icon, 0);
+ String itemAlphabeticShortcut = a.getString(R.styleable.MenuItem_android_alphabeticShortcut);
+ String itemNumericShortcut = a.getString(R.styleable.MenuItem_android_numericShortcut);
+ int itemCheckable = 0;
+ if (a.hasValue(R.styleable.MenuItem_android_checkable)) {
+ // Item has attribute checkable, use it
+ itemCheckable = a.getBoolean(R.styleable.MenuItem_android_checkable, false) ? 1 : 0;
+ }
+ boolean itemChecked = a.getBoolean(R.styleable.MenuItem_android_checked, false);
+ boolean itemVisible = a.getBoolean(R.styleable.MenuItem_android_visible, false);
+ boolean itemEnabled = a.getBoolean(R.styleable.MenuItem_android_enabled, false);
+
+ a.recycle();
+ }
+}