Merge "More performance work:" into ics-mr1
This commit is contained in:
committed by
Android (Google) Code Review
commit
17bd9a22ec
@ -293,7 +293,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
/**
|
||||
* Historical data of past broadcasts, for debugging.
|
||||
*/
|
||||
static final int MAX_BROADCAST_HISTORY = 100;
|
||||
static final int MAX_BROADCAST_HISTORY = 25;
|
||||
final BroadcastRecord[] mBroadcastHistory
|
||||
= new BroadcastRecord[MAX_BROADCAST_HISTORY];
|
||||
|
||||
@ -13898,7 +13898,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
|
||||
// For these apps we will also finish their activities
|
||||
// to help them free memory.
|
||||
mMainStack.destroyActivitiesLocked(app, false);
|
||||
mMainStack.destroyActivitiesLocked(app, false, "trim");
|
||||
}
|
||||
}
|
||||
app.trimMemoryLevel = curLevel;
|
||||
@ -13962,7 +13962,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
if (mAlwaysFinishActivities) {
|
||||
mMainStack.destroyActivitiesLocked(null, false);
|
||||
mMainStack.destroyActivitiesLocked(null, false, "always-finish");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -947,7 +947,7 @@ final class ActivityStack {
|
||||
r.state = ActivityState.STOPPED;
|
||||
if (!r.finishing) {
|
||||
if (r.configDestroy) {
|
||||
destroyActivityLocked(r, true, false);
|
||||
destroyActivityLocked(r, true, false, "stop-config");
|
||||
resumeTopActivityLocked(null);
|
||||
}
|
||||
}
|
||||
@ -976,7 +976,7 @@ final class ActivityStack {
|
||||
// instance right now, we need to first completely stop
|
||||
// the current instance before starting the new one.
|
||||
if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
|
||||
destroyActivityLocked(prev, true, false);
|
||||
destroyActivityLocked(prev, true, false, "pause-config");
|
||||
} else {
|
||||
mStoppingActivities.add(prev);
|
||||
if (mStoppingActivities.size() > 3) {
|
||||
@ -1364,7 +1364,8 @@ final class ActivityStack {
|
||||
}
|
||||
}
|
||||
|
||||
if (!prev.finishing && prev.app != null && prev.app != next.app) {
|
||||
if (!prev.finishing && prev.app != null && prev.app != next.app
|
||||
&& prev.app != mService.mHomeProcess) {
|
||||
// We are switching to a new activity that is in a different
|
||||
// process than the previous one. Note the previous process,
|
||||
// so we can try to keep it around.
|
||||
@ -3113,7 +3114,7 @@ final class ActivityStack {
|
||||
if (DEBUG_STATES) Slog.v(TAG, "Stop failed; moving to STOPPED: " + r);
|
||||
r.state = ActivityState.STOPPED;
|
||||
if (r.configDestroy) {
|
||||
destroyActivityLocked(r, true, false);
|
||||
destroyActivityLocked(r, true, false, "stop-except");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3288,7 +3289,7 @@ final class ActivityStack {
|
||||
for (i=0; i<NF; i++) {
|
||||
ActivityRecord r = (ActivityRecord)finishes.get(i);
|
||||
synchronized (mService) {
|
||||
destroyActivityLocked(r, true, false);
|
||||
destroyActivityLocked(r, true, false, "finish-idle");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3487,7 +3488,7 @@ final class ActivityStack {
|
||||
|| prevState == ActivityState.INITIALIZING) {
|
||||
// If this activity is already stopped, we can just finish
|
||||
// it right now.
|
||||
return destroyActivityLocked(r, true, true) ? null : r;
|
||||
return destroyActivityLocked(r, true, true, "finish-imm") ? null : r;
|
||||
} else {
|
||||
// Need to go through the full pause cycle to get this
|
||||
// activity into the stopped state and then finish it.
|
||||
@ -3593,7 +3594,7 @@ final class ActivityStack {
|
||||
}
|
||||
}
|
||||
|
||||
final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj) {
|
||||
final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
|
||||
for (int i=mHistory.size()-1; i>=0; i--) {
|
||||
ActivityRecord r = mHistory.get(i);
|
||||
if (owner != null && r.app != owner) {
|
||||
@ -3604,7 +3605,7 @@ final class ActivityStack {
|
||||
if (r.app != null && r.haveState && !r.visible && r.stopped && !r.finishing
|
||||
&& r.state != ActivityState.DESTROYING
|
||||
&& r.state != ActivityState.DESTROYED) {
|
||||
destroyActivityLocked(r, true, oomAdj);
|
||||
destroyActivityLocked(r, true, oomAdj, "trim");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3616,13 +3617,13 @@ final class ActivityStack {
|
||||
* but then create a new client-side object for this same HistoryRecord.
|
||||
*/
|
||||
final boolean destroyActivityLocked(ActivityRecord r,
|
||||
boolean removeFromApp, boolean oomAdj) {
|
||||
boolean removeFromApp, boolean oomAdj, String reason) {
|
||||
if (DEBUG_SWITCH) Slog.v(
|
||||
TAG, "Removing activity: token=" + r
|
||||
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
|
||||
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
|
||||
System.identityHashCode(r),
|
||||
r.task.taskId, r.shortComponentName);
|
||||
r.task.taskId, r.shortComponentName, reason);
|
||||
|
||||
boolean removedFromHistory = false;
|
||||
|
||||
@ -4109,7 +4110,7 @@ final class ActivityStack {
|
||||
if (r.app == null || r.app.thread == null) {
|
||||
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
|
||||
"Switch is destroying non-running " + r);
|
||||
destroyActivityLocked(r, true, false);
|
||||
destroyActivityLocked(r, true, false, "config");
|
||||
} else if (r.state == ActivityState.PAUSING) {
|
||||
// A little annoying: we are waiting for this activity to
|
||||
// finish pausing. Let's not do anything now, but just
|
||||
|
@ -48,7 +48,7 @@ option java_package com.android.server.am
|
||||
# Reporting to applications that memory is low
|
||||
30017 am_low_memory (Num Processes|1|1)
|
||||
# An activity is being destroyed:
|
||||
30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
|
||||
30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
|
||||
# An activity has been relaunched, resumed, and is now in the foreground:
|
||||
30019 am_relaunch_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
|
||||
# An activity has been relaunched:
|
||||
|
119
tests/FrameworkPerf/res/layout/button_layout.xml
Normal file
119
tests/FrameworkPerf/res/layout/button_layout.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="FooBarYou" />
|
||||
</LinearLayout>
|
119
tests/FrameworkPerf/res/layout/image_button_layout.xml
Normal file
119
tests/FrameworkPerf/res/layout/image_button_layout.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:src="@drawable/stat_happy"/>
|
||||
</LinearLayout>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
<!-- 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||
<!-- 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.
|
||||
|
69
tests/FrameworkPerf/res/layout/view_layout.xml
Normal file
69
tests/FrameworkPerf/res/layout/view_layout.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<?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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<View android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
@ -20,6 +20,8 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
@ -29,13 +31,16 @@ import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -46,6 +51,9 @@ import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
/**
|
||||
* So you thought sync used up your battery life.
|
||||
*/
|
||||
@ -57,8 +65,10 @@ public class FrameworkPerfActivity extends Activity
|
||||
|
||||
Spinner mFgSpinner;
|
||||
Spinner mBgSpinner;
|
||||
TextView mLog;
|
||||
TextView mTestTime;
|
||||
Button mStartButton;
|
||||
Button mStopButton;
|
||||
TextView mLog;
|
||||
PowerManager.WakeLock mPartialWakeLock;
|
||||
|
||||
long mMaxRunTime = 5000;
|
||||
@ -100,12 +110,21 @@ public class FrameworkPerfActivity extends Activity
|
||||
new WriteFileOp(), new ReadFileOp(),
|
||||
new ReadFileOp(), new WriteFileOp(),
|
||||
new ReadFileOp(), new ReadFileOp(),
|
||||
new OpenXmlResOp(), new NoOp(),
|
||||
new ReadXmlAttrsOp(), new NoOp(),
|
||||
new ParseXmlResOp(), new NoOp(),
|
||||
new ParseLargeXmlResOp(), new NoOp(),
|
||||
new LayoutInflaterOp(), new NoOp(),
|
||||
new LayoutInflaterLargeOp(), new NoOp(),
|
||||
new LayoutInflaterViewOp(), new NoOp(),
|
||||
new LayoutInflaterButtonOp(), new NoOp(),
|
||||
new LayoutInflaterImageButtonOp(), new NoOp(),
|
||||
new CreateBitmapOp(), new NoOp(),
|
||||
new CreateRecycleBitmapOp(), new NoOp(),
|
||||
new LoadSmallBitmapOp(), new NoOp(),
|
||||
new LoadRecycleSmallBitmapOp(), new NoOp(),
|
||||
new LoadLargeBitmapOp(), new NoOp(),
|
||||
new LoadRecycleLargeBitmapOp(), new NoOp(),
|
||||
new LoadSmallScaledBitmapOp(), new NoOp(),
|
||||
new LoadLargeScaledBitmapOp(), new NoOp(),
|
||||
};
|
||||
@ -122,12 +141,21 @@ public class FrameworkPerfActivity extends Activity
|
||||
new CreateWriteSyncFileOp(),
|
||||
new WriteFileOp(),
|
||||
new ReadFileOp(),
|
||||
new OpenXmlResOp(),
|
||||
new ReadXmlAttrsOp(),
|
||||
new ParseXmlResOp(),
|
||||
new ParseLargeXmlResOp(),
|
||||
new LayoutInflaterOp(),
|
||||
new LayoutInflaterLargeOp(),
|
||||
new LayoutInflaterViewOp(),
|
||||
new LayoutInflaterButtonOp(),
|
||||
new LayoutInflaterImageButtonOp(),
|
||||
new CreateBitmapOp(),
|
||||
new CreateRecycleBitmapOp(),
|
||||
new LoadSmallBitmapOp(),
|
||||
new LoadRecycleSmallBitmapOp(),
|
||||
new LoadLargeBitmapOp(),
|
||||
new LoadRecycleLargeBitmapOp(),
|
||||
new LoadSmallScaledBitmapOp(),
|
||||
new LoadLargeScaledBitmapOp(),
|
||||
};
|
||||
@ -208,17 +236,22 @@ public class FrameworkPerfActivity extends Activity
|
||||
mBgSpinner.setAdapter(adapter);
|
||||
mBgSpinner.setOnItemSelectedListener(this);
|
||||
|
||||
findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
|
||||
mTestTime = (TextView)findViewById(R.id.testtime);
|
||||
|
||||
mStartButton = (Button)findViewById(R.id.start);
|
||||
mStartButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
startRunning();
|
||||
}
|
||||
});
|
||||
findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() {
|
||||
mStopButton = (Button)findViewById(R.id.stop);
|
||||
mStopButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
stopRunning();
|
||||
}
|
||||
});
|
||||
mTestTime = (TextView)findViewById(R.id.testtime);
|
||||
mStopButton.setEnabled(false);
|
||||
|
||||
mLog = (TextView)findViewById(R.id.log);
|
||||
|
||||
PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
|
||||
@ -267,9 +300,17 @@ public class FrameworkPerfActivity extends Activity
|
||||
fgOp = mFgTest;
|
||||
bgOp = mBgTest;
|
||||
} else if (mFgTest != null) {
|
||||
// Skip null test.
|
||||
if (mCurOpIndex == 0) {
|
||||
mCurOpIndex = 1;
|
||||
}
|
||||
fgOp = mFgTest;
|
||||
bgOp = mAvailOps[mCurOpIndex];
|
||||
} else {
|
||||
// Skip null test.
|
||||
if (mCurOpIndex == 0) {
|
||||
mCurOpIndex = 1;
|
||||
}
|
||||
fgOp = mAvailOps[mCurOpIndex];
|
||||
bgOp = mBgTest;
|
||||
}
|
||||
@ -297,13 +338,14 @@ public class FrameworkPerfActivity extends Activity
|
||||
stopRunning();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mCurOpIndex++;
|
||||
if (mCurOpIndex >= mAvailOps.length) {
|
||||
log("Finished");
|
||||
stopRunning();
|
||||
return;
|
||||
}
|
||||
}
|
||||
startCurOp();
|
||||
}
|
||||
});
|
||||
@ -313,6 +355,11 @@ public class FrameworkPerfActivity extends Activity
|
||||
if (!mStarted) {
|
||||
log("Start");
|
||||
mStarted = true;
|
||||
mStartButton.setEnabled(false);
|
||||
mStopButton.setEnabled(true);
|
||||
mTestTime.setEnabled(false);
|
||||
mFgSpinner.setEnabled(false);
|
||||
mBgSpinner.setEnabled(false);
|
||||
updateWakeLock();
|
||||
startService(new Intent(this, SchedulerService.class));
|
||||
mCurOpIndex = 0;
|
||||
@ -325,6 +372,11 @@ public class FrameworkPerfActivity extends Activity
|
||||
void stopRunning() {
|
||||
if (mStarted) {
|
||||
mStarted = false;
|
||||
mStartButton.setEnabled(true);
|
||||
mStopButton.setEnabled(false);
|
||||
mTestTime.setEnabled(true);
|
||||
mFgSpinner.setEnabled(true);
|
||||
mBgSpinner.setEnabled(true);
|
||||
updateWakeLock();
|
||||
stopService(new Intent(this, SchedulerService.class));
|
||||
for (int i=0; i<mResults.size(); i++) {
|
||||
@ -333,7 +385,7 @@ public class FrameworkPerfActivity extends Activity
|
||||
float bgMsPerOp = result.getBgMsPerOp();
|
||||
String fgMsPerOpStr = fgMsPerOp != 0 ? Float.toString(fgMsPerOp) : "";
|
||||
String bgMsPerOpStr = bgMsPerOp != 0 ? Float.toString(bgMsPerOp) : "";
|
||||
Log.i(TAG, "\t" + result.name + "\t" + result.fgOps
|
||||
Log.i("PerfRes", "\t" + result.name + "\t" + result.fgOps
|
||||
+ "\t" + result.getFgMsPerOp() + "\t" + result.fgTime
|
||||
+ "\t" + result.fgLongName + "\t" + result.bgOps
|
||||
+ "\t" + result.getBgMsPerOp() + "\t" + result.bgTime
|
||||
@ -662,6 +714,71 @@ public class FrameworkPerfActivity extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
static class OpenXmlResOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
OpenXmlResOp() {
|
||||
super("OpenXmlRes", "Open (and close) an XML resource");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
|
||||
parser.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class ReadXmlAttrsOp extends Op {
|
||||
Context mContext;
|
||||
XmlResourceParser mParser;
|
||||
AttributeSet mAttrs;
|
||||
|
||||
ReadXmlAttrsOp() {
|
||||
super("ReadXmlAttrs", "Read attributes from an XML tag");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
mParser = mContext.getResources().getLayout(R.xml.simple);
|
||||
mAttrs = Xml.asAttributeSet(mParser);
|
||||
|
||||
int eventType;
|
||||
try {
|
||||
// Find the first <item> tag.
|
||||
eventType = mParser.getEventType();
|
||||
String tagName;
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
tagName = mParser.getName();
|
||||
if (tagName.equals("item")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventType = mParser.next();
|
||||
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new RuntimeException("I died", e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("I died", e);
|
||||
}
|
||||
}
|
||||
|
||||
void onTerm(Context context) {
|
||||
mParser.close();
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
TypedArray a = mContext.obtainStyledAttributes(mAttrs,
|
||||
com.android.internal.R.styleable.MenuItem);
|
||||
a.recycle();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class ParseXmlResOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
@ -702,7 +819,7 @@ public class FrameworkPerfActivity extends Activity
|
||||
Context mContext;
|
||||
|
||||
LayoutInflaterOp() {
|
||||
super("LayoutInflaterOp", "Inflate layout resource");
|
||||
super("LayoutInflater", "Inflate layout resource");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
@ -724,7 +841,7 @@ public class FrameworkPerfActivity extends Activity
|
||||
Context mContext;
|
||||
|
||||
LayoutInflaterLargeOp() {
|
||||
super("LayoutInflaterLargeOp", "Inflate large layout resource");
|
||||
super("LayoutInflaterLarge", "Inflate large layout resource");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
@ -742,6 +859,111 @@ public class FrameworkPerfActivity extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
static class LayoutInflaterViewOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
LayoutInflaterViewOp() {
|
||||
super("LayoutInflaterView", "Inflate layout with 50 View objects");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
inf.inflate(R.layout.view_layout, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class LayoutInflaterButtonOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
LayoutInflaterButtonOp() {
|
||||
super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
inf.inflate(R.layout.button_layout, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class LayoutInflaterImageButtonOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
LayoutInflaterImageButtonOp() {
|
||||
super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
inf.inflate(R.layout.image_button_layout, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class CreateBitmapOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
CreateBitmapOp() {
|
||||
super("CreateBitmap", "Create a Bitmap");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class CreateRecycleBitmapOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
CreateRecycleBitmapOp() {
|
||||
super("CreateRecycleBitmap", "Create and recycle a Bitmap");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
|
||||
bm.recycle();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadSmallBitmapOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
@ -753,6 +975,26 @@ public class FrameworkPerfActivity extends Activity
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadRecycleSmallBitmapOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
LoadRecycleSmallBitmapOp() {
|
||||
super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
@ -774,6 +1016,26 @@ public class FrameworkPerfActivity extends Activity
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadRecycleLargeBitmapOp extends Op {
|
||||
Context mContext;
|
||||
|
||||
LoadRecycleLargeBitmapOp() {
|
||||
super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
|
||||
}
|
||||
|
||||
void onInit(Context context, boolean foreground) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
boolean onRun() {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
@ -800,7 +1062,6 @@ public class FrameworkPerfActivity extends Activity
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
|
||||
R.drawable.stat_sample_scale, opts);
|
||||
bm.recycle();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -821,7 +1082,6 @@ public class FrameworkPerfActivity extends Activity
|
||||
opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
|
||||
Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
|
||||
R.drawable.wallpaper_goldengate_scale, opts);
|
||||
bm.recycle();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user