summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/app_process/Android.mk17
-rw-r--r--cmds/app_process/sigchain_proxy.cpp17
-rw-r--r--core/java/android/os/Debug.java8
-rw-r--r--core/java/android/widget/DatePickerCalendarDelegate.java56
-rwxr-xr-xcore/res/res/values/config.xml3
-rw-r--r--core/res/res/values/dimens_material.xml5
-rw-r--r--core/res/res/values/styles_material.xml2
-rwxr-xr-xcore/res/res/values/symbols.xml1
-rw-r--r--docs/html/distribute/googleplay/wear.jd2
-rw-r--r--docs/html/jd_collections.js2
-rw-r--r--docs/html/tools/studio/index.jd5
-rw-r--r--docs/html/tools/tools_toc.cs10
-rw-r--r--docs/html/training/basics/actionbar/adding-buttons.jd2
-rw-r--r--docs/html/training/basics/actionbar/index.jd1
-rw-r--r--docs/html/training/basics/actionbar/overlaying.jd2
-rw-r--r--docs/html/training/basics/actionbar/setting-up.jd2
-rw-r--r--docs/html/training/basics/actionbar/styling.jd2
-rw-r--r--docs/html/training/basics/data-storage/databases.jd4
-rw-r--r--docs/html/training/basics/data-storage/files.jd2
-rw-r--r--docs/html/training/basics/data-storage/index.jd1
-rw-r--r--docs/html/training/basics/data-storage/shared-preferences.jd2
-rw-r--r--docs/html/training/notify-user/build-notification.jd6
-rw-r--r--docs/html/training/notify-user/display-progress.jd6
-rw-r--r--docs/html/training/notify-user/expanded.jd6
-rw-r--r--docs/html/training/notify-user/index.jd1
-rw-r--r--docs/html/training/notify-user/managing.jd6
-rw-r--r--docs/html/training/notify-user/navigation.jd6
-rw-r--r--docs/html/training/tv/discovery/in-app-search.jd3
-rw-r--r--docs/html/training/tv/discovery/index.jd3
-rw-r--r--docs/html/training/tv/discovery/recommendations.jd3
-rw-r--r--docs/html/training/tv/games/index.jd3
-rw-r--r--docs/html/training/tv/playback/browse.jd3
-rw-r--r--docs/html/training/tv/playback/details.jd3
-rw-r--r--docs/html/training/tv/playback/index.jd3
-rw-r--r--docs/html/training/tv/playback/now-playing.jd3
-rw-r--r--docs/html/training/tv/start/hardware.jd3
-rw-r--r--docs/html/training/tv/start/index.jd3
-rw-r--r--docs/html/training/tv/start/layouts.jd3
-rw-r--r--docs/html/training/tv/start/navigation.jd3
-rw-r--r--docs/html/training/tv/start/start.jd3
-rw-r--r--docs/html/training/tv/tif/index.jd3
-rw-r--r--docs/html/training/wearables/apps/bt-debugging.jd2
-rw-r--r--docs/html/training/wearables/apps/creating.jd2
-rw-r--r--docs/html/training/wearables/apps/index.jd3
-rw-r--r--docs/html/training/wearables/apps/layouts.jd2
-rw-r--r--docs/html/training/wearables/apps/packaging.jd2
-rw-r--r--docs/html/training/wearables/apps/voice.jd3
-rw-r--r--docs/html/training/wearables/notifications/creating.jd4
-rw-r--r--docs/html/training/wearables/notifications/index.jd4
-rw-r--r--docs/html/training/wearables/notifications/pages.jd2
-rw-r--r--docs/html/training/wearables/notifications/stacks.jd2
-rw-r--r--docs/html/training/wearables/notifications/voice-input.jd2
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java9
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java2
-rw-r--r--include/androidfw/AttributeFinder.h11
-rw-r--r--libs/androidfw/tests/AttributeFinder_test.cpp17
-rw-r--r--libs/hwui/AmbientShadow.cpp1
-rw-r--r--libs/hwui/AssetAtlas.cpp35
-rw-r--r--libs/hwui/AssetAtlas.h14
-rw-r--r--libs/hwui/Caches.cpp2
-rw-r--r--libs/hwui/Caches.h2
-rw-r--r--libs/hwui/DisplayList.h12
-rw-r--r--libs/hwui/DisplayListOp.h58
-rwxr-xr-xlibs/hwui/OpenGLRenderer.cpp11
-rwxr-xr-xlibs/hwui/OpenGLRenderer.h9
-rw-r--r--libs/hwui/RenderState.cpp2
-rw-r--r--libs/hwui/RenderState.h4
-rw-r--r--libs/hwui/TextureCache.cpp16
-rw-r--r--libs/hwui/TextureCache.h6
-rw-r--r--libs/hwui/renderthread/EglManager.cpp3
-rw-r--r--packages/SystemUI/AndroidManifest.xml12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/Recents.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java217
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java5
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java31
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java32
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java14
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java1
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java45
-rw-r--r--services/core/java/com/android/server/wm/KeyguardDisableHandler.java45
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java34
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl21
85 files changed, 744 insertions, 311 deletions
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 1ca14a6..397a7d1 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -2,15 +2,10 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-# TODO: Trying to link libsigchain as a static library prevents
-# static linker from exporting necessary symbols. So as a workaround
-# we use sigchain.o
LOCAL_SRC_FILES:= \
- app_main.cpp \
- sigchain_proxy.cpp
+ app_main.cpp
LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
LOCAL_SHARED_LIBRARIES := \
libdl \
@@ -20,6 +15,8 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libandroid_runtime
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
+
LOCAL_MODULE:= app_process
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := app_process32
@@ -36,10 +33,8 @@ ifeq ($(TARGET_ARCH),arm)
include $(CLEAR_VARS)
-# see comment above (~l5)
LOCAL_SRC_FILES:= \
- app_main.cpp \
- sigchain_proxy.cpp
+ app_main.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
@@ -48,8 +43,10 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libandroid_runtime
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
+
LOCAL_LDFLAGS := -ldl -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
+LOCAL_CPPFLAGS := -std=c++11
LOCAL_MODULE := app_process__asan
LOCAL_MODULE_TAGS := eng
diff --git a/cmds/app_process/sigchain_proxy.cpp b/cmds/app_process/sigchain_proxy.cpp
deleted file mode 100644
index bb7a678..0000000
--- a/cmds/app_process/sigchain_proxy.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#include "sigchainlib/sigchain.cc"
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a9deaf3..b8178b4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -296,7 +296,7 @@ public final class Debug
case 1: return "Stack";
case 2: return "Cursor";
case 3: return "Ashmem";
- case 4: return "Gfx driver";
+ case 4: return "Gfx dev";
case 5: return "Other dev";
case 6: return ".so mmap";
case 7: return ".jar mmap";
@@ -306,9 +306,9 @@ public final class Debug
case 11: return ".oat mmap";
case 12: return ".art mmap";
case 13: return "Other mmap";
- case 14: return "Graphics";
- case 15: return "GL";
- case 16: return "Memtrack";
+ case 14: return "EGL mtrack";
+ case 15: return "GL mtrack";
+ case 16: return "Other mtrack";
case 17: return ".Heap";
case 18: return ".LOS";
case 19: return ".LinearAlloc";
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 820bf78..54c4505 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -329,7 +329,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
mAnimator.announceForAccessibility(fullDateText);
}
- updatePickers();
}
private void setCurrentView(final int viewIndex) {
@@ -369,11 +368,14 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
@Override
public void init(int year, int monthOfYear, int dayOfMonth,
DatePicker.OnDateChangedListener callBack) {
- mDateChangedListener = callBack;
mCurrentDate.set(Calendar.YEAR, year);
mCurrentDate.set(Calendar.MONTH, monthOfYear);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- updateDisplay(false);
+
+ onDateChanged(false);
+
+ // Set the listener last so that we don't call it.
+ mDateChangedListener = callBack;
}
@Override
@@ -381,10 +383,29 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
mCurrentDate.set(Calendar.YEAR, year);
mCurrentDate.set(Calendar.MONTH, month);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ onDateChanged(false);
+ }
+
+ private void onDateChanged(boolean fromUser) {
if (mDateChangedListener != null) {
- mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
+ final int year = mCurrentDate.get(Calendar.YEAR);
+ final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
+ final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
+ mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
+ }
+
+ for (OnDateChangedListener listener : mListeners) {
+ listener.onDateChanged();
+ }
+
+ mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
+
+ updateDisplay(fromUser);
+
+ if (fromUser) {
+ tryVibrate();
}
- updateDisplay(false);
}
@Override
@@ -411,8 +432,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
if (mCurrentDate.before(mTempDate)) {
mCurrentDate.setTimeInMillis(minDate);
- updatePickers();
- updateDisplay(false);
+ onDateChanged(false);
}
mMinDate.setTimeInMillis(minDate);
mDayPickerView.setMinDate(minDate);
@@ -433,8 +453,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
if (mCurrentDate.after(mTempDate)) {
mCurrentDate.setTimeInMillis(maxDate);
- updatePickers();
- updateDisplay(false);
+ onDateChanged(false);
}
mMaxDate.setTimeInMillis(maxDate);
mDayPickerView.setMaxDate(maxDate);
@@ -573,9 +592,10 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
public void onYearSelected(int year) {
adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
mCurrentDate.set(Calendar.YEAR, year);
- updatePickers();
+ onDateChanged(true);
+
+ // Auto-advance to month and day view.
setCurrentView(MONTH_AND_DAY_VIEW);
- updateDisplay(true);
}
// If the newly selected month / year does not contain the currently selected day number,
@@ -612,14 +632,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
}
- private void updatePickers() {
- for (OnDateChangedListener listener : mListeners) {
- listener.onDateChanged();
- }
-
- mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
- }
-
@Override
public void registerOnDateChangedListener(OnDateChangedListener listener) {
mListeners.add(listener);
@@ -653,11 +665,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
@Override
public void onDaySelected(DayPickerView view, Calendar day) {
mCurrentDate.setTimeInMillis(day.getTimeInMillis());
-
- updatePickers();
- updateDisplay(true);
-
- tryVibrate();
+ onDateChanged(true);
}
};
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6769c85..ecc8d9d 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -425,6 +425,9 @@
<!-- Integer indicating minimum blacklisting delay of a wofo configuration due to connectin or auth errors -->
<integer translatable="false" name="config_wifi_framework_network_black_list_min_time_milli">120000</integer>
+ <!-- Integer indicating RSSI boost given to current network -->
+ <integer translatable="false" name="config_wifi_framework_current_network_boost">25</integer>
+
<!-- Boolean indicating associated scan are allowed -->
<bool translatable="false" name="config_wifi_framework_enable_associated_autojoin_scan">true</bool>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index bdb0324..e1e1ffe 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -56,6 +56,7 @@
<dimen name="action_bar_overflow_padding_start_material">6dp</dimen>
<!-- Padding to add to the end of the overflow action button. -->
<dimen name="action_bar_overflow_padding_end_material">10dp</dimen>
+ <dimen name="action_bar_elevation_material">4dp</dimen>
<dimen name="action_button_min_width_overflow_material">36dp</dimen>
<dimen name="action_button_min_width_material">48dp</dimen>
@@ -87,9 +88,9 @@
<dimen name="floating_window_margin_bottom">32dp</dimen>
<!-- Elevation when button is pressed -->
- <dimen name="button_elevation_material">4dp</dimen>
+ <dimen name="button_elevation_material">2dp</dimen>
<!-- Z translation to apply when button is pressed -->
- <dimen name="button_pressed_z_material">2dp</dimen>
+ <dimen name="button_pressed_z_material">4dp</dimen>
<!-- Default insets (outer padding) around buttons -->
<dimen name="button_inset_vertical_material">6dp</dimen>
<dimen name="button_inset_horizontal_material">@dimen/control_inset_material</dimen>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index d3d6d70..6220a1b 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -917,7 +917,7 @@ please see styles_device_defaults.xml.
<item name="gravity">center_vertical</item>
<item name="contentInsetStart">@dimen/action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/action_bar_content_inset_material</item>
- <item name="elevation">8dp</item>
+ <item name="elevation">@dimen/action_bar_elevation_material</item>
<item name="popupTheme">?attr/actionBarPopupTheme</item>
</style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4f2ed22..d8c5f2c 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -338,6 +338,7 @@
<java-symbol type="integer" name="config_wifi_framework_max_connection_errors_to_blacklist" />
<java-symbol type="integer" name="config_wifi_framework_max_auth_errors_to_blacklist" />
<java-symbol type="integer" name="config_wifi_framework_network_black_list_min_time_milli" />
+ <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
<java-symbol type="integer" name="config_bluetooth_max_advertisers" />
<java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
<java-symbol type="integer" name="config_cursorWindowSize" />
diff --git a/docs/html/distribute/googleplay/wear.jd b/docs/html/distribute/googleplay/wear.jd
index b6fc6b6..c0a0017 100644
--- a/docs/html/distribute/googleplay/wear.jd
+++ b/docs/html/distribute/googleplay/wear.jd
@@ -210,7 +210,7 @@ describe how to start building a great app experience for Wear.
and the opt-in checkbox.
</li>
- <li>Click the checkbox next to <em>Distribute your app to Android Wear</em>.
+ <li>Click the checkbox next to <em>Distribute your app on Android Wear</em>.
</li>
<li>Click <strong>Save</strong> to save your Pricing and Distribution changes.
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 1b7cfc9..ab5a655 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -4,7 +4,7 @@ var RESOURCE_COLLECTIONS = {
"resources": [
"training/building-wearables.html",
"training/material/index.html",
- "sdk/installing/studio.html"
+ "sdk/index.html"
]
},
"index/primary/zhcn": {
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index d1888fa..258fedb 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -114,8 +114,9 @@ specification and the files under {@code src/androidTest} directory for test cas
<p> <img src="{@docRoot}images/tools/studio-project-layout.png" alt="" /></p>
<p> <class="img-caption"><strong>Figure 3.</strong> Android Studio project structure</p>
-<p>For more information, see <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project +Organization"class="external-link">IntelliJ project organization</a> and
-<a href="{@docRoot}tools/workflow/project/index.html">Managing Projects</a>.</p>
+<p>For more information, see
+<a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project+Organization"class="external-link">IntelliJ project organization</a> and
+<a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.</p>
<h3>Creating new files</h3>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index cb6a1de..9437c1b 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -122,7 +122,7 @@
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects.html"><span class="en">From Eclipse with ADT</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/debugging/debugging-studio.html"><span class="en">From Android Studio</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects-cmdline.html"><span class="en">From Other IDEs</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/ddms.html"><span class="en">Using DDMS</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-log.html"><span class="en">Reading and Writing Logs</span></a></li>
@@ -145,14 +145,6 @@
</ul>
</li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/support-library/index.html"><span
-class="en">Support Library</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/support-library/features.html">Features</a></li>
- <li><a href="<?cs var:toroot ?>tools/support-library/setup.html">Setup</a></li>
- </ul>
- </li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span
diff --git a/docs/html/training/basics/actionbar/adding-buttons.jd b/docs/html/training/basics/actionbar/adding-buttons.jd
index 26c9d0e..40d0bd1 100644
--- a/docs/html/training/basics/actionbar/adding-buttons.jd
+++ b/docs/html/training/basics/actionbar/adding-buttons.jd
@@ -1,4 +1,6 @@
page.title=Adding Action Buttons
+page.tags=actionbar
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/actionbar/index.jd b/docs/html/training/basics/actionbar/index.jd
index 0303043..6a8eaff 100644
--- a/docs/html/training/basics/actionbar/index.jd
+++ b/docs/html/training/basics/actionbar/index.jd
@@ -1,5 +1,6 @@
page.title=Adding the Action Bar
page.tags=actionbar
+helpoutsWidget=true
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/basics/actionbar/overlaying.jd b/docs/html/training/basics/actionbar/overlaying.jd
index 800cd44..634534e 100644
--- a/docs/html/training/basics/actionbar/overlaying.jd
+++ b/docs/html/training/basics/actionbar/overlaying.jd
@@ -1,4 +1,6 @@
page.title=Overlaying the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/actionbar/setting-up.jd b/docs/html/training/basics/actionbar/setting-up.jd
index 158ce92..bccbd04 100644
--- a/docs/html/training/basics/actionbar/setting-up.jd
+++ b/docs/html/training/basics/actionbar/setting-up.jd
@@ -1,4 +1,6 @@
page.title=Setting Up the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/actionbar/styling.jd b/docs/html/training/basics/actionbar/styling.jd
index 4128a97..7c63952 100644
--- a/docs/html/training/basics/actionbar/styling.jd
+++ b/docs/html/training/basics/actionbar/styling.jd
@@ -1,4 +1,6 @@
page.title=Styling the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/data-storage/databases.jd b/docs/html/training/basics/data-storage/databases.jd
index 6ea2140..4a91d0d 100644
--- a/docs/html/training/basics/data-storage/databases.jd
+++ b/docs/html/training/basics/data-storage/databases.jd
@@ -1,8 +1,8 @@
page.title=Saving Data in SQL Databases
+page.tags=data storage
+helpoutsWidget=true
trainingnavtop=true
-previous.title=Saving Data in Files
-previous.link=files.html
@jd:body
diff --git a/docs/html/training/basics/data-storage/files.jd b/docs/html/training/basics/data-storage/files.jd
index 52bea4c..49a9169 100644
--- a/docs/html/training/basics/data-storage/files.jd
+++ b/docs/html/training/basics/data-storage/files.jd
@@ -1,4 +1,6 @@
page.title=Saving Files
+page.tags=data storage
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/data-storage/index.jd b/docs/html/training/basics/data-storage/index.jd
index fc0c8b5..aa223f6 100644
--- a/docs/html/training/basics/data-storage/index.jd
+++ b/docs/html/training/basics/data-storage/index.jd
@@ -1,5 +1,6 @@
page.title=Saving Data
page.tags=data storage,files,sql,database,preferences
+helpoutsWidget=true
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/basics/data-storage/shared-preferences.jd b/docs/html/training/basics/data-storage/shared-preferences.jd
index a6717c4..debb17d 100644
--- a/docs/html/training/basics/data-storage/shared-preferences.jd
+++ b/docs/html/training/basics/data-storage/shared-preferences.jd
@@ -1,4 +1,6 @@
page.title=Saving Key-Value Sets
+page.tags=data storage
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/notify-user/build-notification.jd b/docs/html/training/notify-user/build-notification.jd
index 80f2cd5..d24a496 100644
--- a/docs/html/training/notify-user/build-notification.jd
+++ b/docs/html/training/notify-user/build-notification.jd
@@ -1,10 +1,8 @@
page.title=Building a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
-next.title=Preserving Navigation when Starting an Activity
-next.link=navigation.html
@jd:body
diff --git a/docs/html/training/notify-user/display-progress.jd b/docs/html/training/notify-user/display-progress.jd
index c00576c..3439571 100644
--- a/docs/html/training/notify-user/display-progress.jd
+++ b/docs/html/training/notify-user/display-progress.jd
@@ -1,10 +1,8 @@
page.title=Displaying Progress in a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
-previous.title=Using Expanded Notification Styles
-previous.link=expanded.html
@jd:body
diff --git a/docs/html/training/notify-user/expanded.jd b/docs/html/training/notify-user/expanded.jd
index a3cc6ad..b657426 100644
--- a/docs/html/training/notify-user/expanded.jd
+++ b/docs/html/training/notify-user/expanded.jd
@@ -1,10 +1,8 @@
page.title=Using Big View Styles
-Styles parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
-next.title=Displaying Progress in a Notification
-next.link=display-progress.html
@jd:body
diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd
index f7d0f87..616e767 100644
--- a/docs/html/training/notify-user/index.jd
+++ b/docs/html/training/notify-user/index.jd
@@ -1,5 +1,6 @@
page.title=Notifying the User
page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/notify-user/managing.jd b/docs/html/training/notify-user/managing.jd
index 4782734..fc12cfb 100644
--- a/docs/html/training/notify-user/managing.jd
+++ b/docs/html/training/notify-user/managing.jd
@@ -1,10 +1,8 @@
page.title=Updating Notifications
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
-next.title=Creating Expanded Notifications
-next.link=expanded.html
@jd:body
diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd
index fc95013..b7051ab 100644
--- a/docs/html/training/notify-user/navigation.jd
+++ b/docs/html/training/notify-user/navigation.jd
@@ -1,10 +1,8 @@
page.title=Preserving Navigation when Starting an Activity
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
trainingnavtop=true
-next.title=Updating Notifications
-next.link=managing.html
@jd:body
diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd
index 28c7a35..fb7c097 100644
--- a/docs/html/training/tv/discovery/in-app-search.jd
+++ b/docs/html/training/tv/discovery/in-app-search.jd
@@ -1,5 +1,6 @@
page.title=Searching within TV Apps
-page.tags="leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
index 5849149..f22ca67 100644
--- a/docs/html/training/tv/discovery/index.jd
+++ b/docs/html/training/tv/discovery/index.jd
@@ -1,5 +1,6 @@
page.title=Helping Users Find Your Content on TV
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
startpage=true
diff --git a/docs/html/training/tv/discovery/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
index a6eb152..0f6d256 100644
--- a/docs/html/training/tv/discovery/recommendations.jd
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -1,5 +1,6 @@
page.title=Recommending TV Content
-page.tags="recommendation","recommend"
+page.tags=tv, recommendations
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
index 5276d7f..371e9e9 100644
--- a/docs/html/training/tv/games/index.jd
+++ b/docs/html/training/tv/games/index.jd
@@ -1,5 +1,6 @@
page.title=Building TV Games
-page.tags="tv", "games", "controller"
+page.tags=tv, games, controller
+helpoutsWidget=true
page.image=images/games/game-controller-buttons_2x_crop.png
page.metaDescription=How to bring your games to Android TV, including recommendations and examples.
page.article=true
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
index 9b25166..9c81597 100644
--- a/docs/html/training/tv/playback/browse.jd
+++ b/docs/html/training/tv/playback/browse.jd
@@ -1,5 +1,6 @@
page.title=Creating a Catalog Browser
-page.tags="browsefragment","presenter","backgroundmanager"
+page.tags=tv, browsefragment, presenter, backgroundmanager
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/tv/playback/details.jd b/docs/html/training/tv/playback/details.jd
index 6391a49..bd6d67a 100644
--- a/docs/html/training/tv/playback/details.jd
+++ b/docs/html/training/tv/playback/details.jd
@@ -1,5 +1,6 @@
page.title=Building a Details View
-page.tags="detailsfragment"
+page.tags=tv, detailsfragment
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 09c3f24..31c7524 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -1,5 +1,6 @@
page.title=Building TV Playback Apps
-page.tags="tv","leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
startpage=true
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
index b64beb0..e158697 100644
--- a/docs/html/training/tv/playback/now-playing.jd
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -1,5 +1,6 @@
page.title=Displaying a Now Playing Card
-page.tags="nowplaying","mediasession"
+page.tags=tv, mediasession
+helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd
index fc52602..b25a0dd 100644
--- a/docs/html/training/tv/start/hardware.jd
+++ b/docs/html/training/tv/start/hardware.jd
@@ -1,5 +1,6 @@
page.title=Handling TV Hardware
-page.tags="unsupported"
+page.tags=tv
+helpoutsWidget=true
trainingnavtop=true
@jd:body
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
index fb478a8..54ff2d9 100644
--- a/docs/html/training/tv/start/index.jd
+++ b/docs/html/training/tv/start/index.jd
@@ -1,5 +1,6 @@
page.title=Building TV Apps
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
startpage=true
@jd:body
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index d2abe1d..a390702 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -1,4 +1,7 @@
page.title=Building Layouts for TV
+page.tags=tv
+helpoutsWidget=true
+
trainingnavtop=true
@jd:body
diff --git a/docs/html/training/tv/start/navigation.jd b/docs/html/training/tv/start/navigation.jd
index 1c9faca..a94e3ae 100644
--- a/docs/html/training/tv/start/navigation.jd
+++ b/docs/html/training/tv/start/navigation.jd
@@ -1,5 +1,6 @@
page.title=Creating TV Navigation
-page.tags="focus","selection","d-pad"
+page.tags=tv, d-pad, focus
+helpoutsWidget=true
trainingnavtop=true
@jd:body
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
index aab1a39..e3b92c6 100644
--- a/docs/html/training/tv/start/start.jd
+++ b/docs/html/training/tv/start/start.jd
@@ -1,5 +1,6 @@
page.title=Get Started with TV Apps
-page.tags="leanback","recyclerview","launcher"
+page.tags=tv, leanback, recyclerview
+helpoutsWidget=true
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
index cde8ba7..9c10850 100644
--- a/docs/html/training/tv/tif/index.jd
+++ b/docs/html/training/tv/tif/index.jd
@@ -1,5 +1,6 @@
page.title=Building Live TV Apps
-page.tags="tv", "tif"
+page.tags=tv, tif
+helpoutsWidget=true
page.article=true
@jd:body
diff --git a/docs/html/training/wearables/apps/bt-debugging.jd b/docs/html/training/wearables/apps/bt-debugging.jd
index 7569e7e..beded9e 100644
--- a/docs/html/training/wearables/apps/bt-debugging.jd
+++ b/docs/html/training/wearables/apps/bt-debugging.jd
@@ -1,4 +1,6 @@
page.title=Debugging over Bluetooth
+page.tags=wear
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd
index 683dd31..c12ffa7 100644
--- a/docs/html/training/wearables/apps/creating.jd
+++ b/docs/html/training/wearables/apps/creating.jd
@@ -1,4 +1,6 @@
page.title=Creating and Running a Wearable App
+page.tags=wear
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/apps/index.jd b/docs/html/training/wearables/apps/index.jd
index 4bdd6bf..812f893 100644
--- a/docs/html/training/wearables/apps/index.jd
+++ b/docs/html/training/wearables/apps/index.jd
@@ -1,5 +1,6 @@
page.title=Creating Wearable Apps
-page.tags="wear","wearable","app"
+page.tags=wear
+helpoutsWidget=true
page.image=wear/images/01_create.png
@jd:body
diff --git a/docs/html/training/wearables/apps/layouts.jd b/docs/html/training/wearables/apps/layouts.jd
index 4eeb281..69e57ca 100644
--- a/docs/html/training/wearables/apps/layouts.jd
+++ b/docs/html/training/wearables/apps/layouts.jd
@@ -1,4 +1,6 @@
page.title=Creating Custom Layouts
+page.tags=wear
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/apps/packaging.jd b/docs/html/training/wearables/apps/packaging.jd
index 180f730..9c42978 100644
--- a/docs/html/training/wearables/apps/packaging.jd
+++ b/docs/html/training/wearables/apps/packaging.jd
@@ -1,4 +1,6 @@
page.title=Packaging Wearable Apps
+page.tags=wear
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/apps/voice.jd b/docs/html/training/wearables/apps/voice.jd
index 4aa8031..6d49319 100644
--- a/docs/html/training/wearables/apps/voice.jd
+++ b/docs/html/training/wearables/apps/voice.jd
@@ -1,4 +1,7 @@
page.title=Adding Voice Capabilities
+page.tags=wear
+helpoutsWidget=true
+
@jd:body
<div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/creating.jd b/docs/html/training/wearables/notifications/creating.jd
index 57ac36e..542664b 100644
--- a/docs/html/training/wearables/notifications/creating.jd
+++ b/docs/html/training/wearables/notifications/creating.jd
@@ -1,4 +1,6 @@
-page.title=Creating a Notification
+page.title=Creating a Notification for Wearables
+page.tags=notifications
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/notifications/index.jd b/docs/html/training/wearables/notifications/index.jd
index 2833dfa..6be945c 100644
--- a/docs/html/training/wearables/notifications/index.jd
+++ b/docs/html/training/wearables/notifications/index.jd
@@ -1,6 +1,8 @@
page.title=Adding Wearable Features to Notifications
-page.tags="wear","notifications","wearables"
+page.tags=notifications, wear
page.image=wear/images/01_notifications.png
+helpoutsWidget=true
+
@jd:body
<div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/pages.jd b/docs/html/training/wearables/notifications/pages.jd
index 6315037..41a3d7e 100644
--- a/docs/html/training/wearables/notifications/pages.jd
+++ b/docs/html/training/wearables/notifications/pages.jd
@@ -1,4 +1,6 @@
page.title=Adding Pages to a Notification
+page.tags=notifications
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/notifications/stacks.jd b/docs/html/training/wearables/notifications/stacks.jd
index 9e70e1b..8056fc8 100644
--- a/docs/html/training/wearables/notifications/stacks.jd
+++ b/docs/html/training/wearables/notifications/stacks.jd
@@ -1,4 +1,6 @@
page.title=Stacking Notifications
+page.tags=notifications
+helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/wearables/notifications/voice-input.jd b/docs/html/training/wearables/notifications/voice-input.jd
index 5a49343..73936f9 100644
--- a/docs/html/training/wearables/notifications/voice-input.jd
+++ b/docs/html/training/wearables/notifications/voice-input.jd
@@ -1,4 +1,6 @@
page.title=Receiving Voice Input in a Notification
+page.tags=notifications
+helpoutsWidget=true
@jd:body
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1e360d3..3fe408a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -714,10 +714,17 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
}
+ // Create futures for drawables with constant states. If a
+ // drawable doesn't have a constant state, then we can't clone
+ // it and we'll have to reference the original.
final int N = mNumChildren;
for (int i = 0; i < N; i++) {
if (origDr[i] != null) {
- mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+ if (origDr[i].getConstantState() != null) {
+ mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+ } else {
+ mDrawables[i] = origDr[i];
+ }
}
}
} else {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 94c7026..cb42397 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1795,5 +1795,7 @@ public class GradientDrawable extends Drawable {
mStrokePaint.setPathEffect(e);
}
}
+
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
}
}
diff --git a/include/androidfw/AttributeFinder.h b/include/androidfw/AttributeFinder.h
index a0ffeb3..acf7056 100644
--- a/include/androidfw/AttributeFinder.h
+++ b/include/androidfw/AttributeFinder.h
@@ -64,6 +64,7 @@ private:
void jumpToClosestAttribute(uint32_t packageId);
void markCurrentPackageId(uint32_t packageId);
+ bool mFirstTime;
Iterator mBegin;
Iterator mEnd;
Iterator mCurrent;
@@ -81,7 +82,8 @@ private:
template <typename Derived, typename Iterator> inline
BackTrackingAttributeFinder<Derived, Iterator>::BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end)
- : mBegin(begin)
+ : mFirstTime(true)
+ , mBegin(begin)
, mEnd(end)
, mCurrent(begin)
, mLargest(begin)
@@ -145,8 +147,11 @@ Iterator BackTrackingAttributeFinder<Derived, Iterator>::find(uint32_t attr) {
return mEnd;
}
- if (mCurrentAttr == 0) {
- // One-time initialization.
+ if (mFirstTime) {
+ // One-time initialization. We do this here instead of the constructor
+ // because the derived class we access in getAttribute() may not be
+ // fully constructed.
+ mFirstTime = false;
mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mBegin);
mLastPackageId = getPackage(mCurrentAttr);
markCurrentPackageId(mLastPackageId);
diff --git a/libs/androidfw/tests/AttributeFinder_test.cpp b/libs/androidfw/tests/AttributeFinder_test.cpp
index 664709c..5054624 100644
--- a/libs/androidfw/tests/AttributeFinder_test.cpp
+++ b/libs/androidfw/tests/AttributeFinder_test.cpp
@@ -50,6 +50,10 @@ static const uint32_t packageUnsortedAttributes[] = {
0x01010002, 0x01010004, 0x7f010001
};
+static const uint32_t singlePackageAttributes[] = {
+ 0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000
+};
+
TEST(AttributeFinderTest, IteratesSequentially) {
const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
MockAttributeFinder finder(sortedAttributes, end);
@@ -109,3 +113,16 @@ TEST(AttributeFinderTest, FindAttributesInPackageUnsortedAttributeList) {
EXPECT_EQ(1, finder.find(0x02010010));
EXPECT_EQ(6, finder.find(0x7f010001));
}
+
+TEST(AttributeFinderTest, FindAttributesInSinglePackageAttributeList) {
+ const int end = sizeof(singlePackageAttributes) / sizeof(*singlePackageAttributes);
+ MockAttributeFinder finder(singlePackageAttributes, end);
+
+ EXPECT_EQ(end, finder.find(0x010100f4));
+ EXPECT_EQ(end, finder.find(0x010100f5));
+ EXPECT_EQ(end, finder.find(0x010100f6));
+ EXPECT_EQ(end, finder.find(0x010100f7));
+ EXPECT_EQ(end, finder.find(0x010100f8));
+ EXPECT_EQ(end, finder.find(0x010100fa));
+ EXPECT_EQ(0, finder.find(0x7f010007));
+}
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 21c869b..b2dba00 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -325,6 +325,7 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque,
// At the end, update the real index and vertex buffer size.
shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
shadowVertexBuffer.updateIndexCount(indexBufferIndex);
+ shadowVertexBuffer.computeBounds<AlphaVertex>();
ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Ambient Vertex Buffer");
ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Ambient Index Buffer");
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index e5a93bd..c6de535 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -36,39 +36,37 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) {
ATRACE_NAME("AssetAtlas::init");
mImage = new Image(buffer);
-
if (mImage->getTexture()) {
- Caches& caches = Caches::getInstance();
-
- mTexture = new Texture(caches);
- mTexture->id = mImage->getTexture();
- mTexture->width = buffer->getWidth();
- mTexture->height = buffer->getHeight();
-
- createEntries(caches, map, count);
+ if (!mTexture) {
+ Caches& caches = Caches::getInstance();
+ mTexture = new Texture(caches);
+ mTexture->width = buffer->getWidth();
+ mTexture->height = buffer->getHeight();
+ createEntries(caches, map, count);
+ }
} else {
ALOGW("Could not create atlas image");
-
delete mImage;
mImage = NULL;
- mTexture = NULL;
}
- mGenerationId++;
+ updateTextureId();
}
void AssetAtlas::terminate() {
if (mImage) {
delete mImage;
mImage = NULL;
+ updateTextureId();
+ }
+}
- delete mTexture;
- mTexture = NULL;
- for (size_t i = 0; i < mEntries.size(); i++) {
- delete mEntries.valueAt(i);
- }
- mEntries.clear();
+void AssetAtlas::updateTextureId() {
+ mTexture->id = mImage ? mImage->getTexture() : 0;
+ for (size_t i = 0; i < mEntries.size(); i++) {
+ AssetAtlas::Entry* entry = mEntries.valueAt(i);
+ entry->texture->id = mTexture->id;
}
}
@@ -133,7 +131,6 @@ void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
y / height, (y + bitmap->height()) / height);
Texture* texture = new DelegateTexture(caches, mTexture);
- texture->id = mTexture->id;
texture->blend = !bitmap->isOpaque();
texture->width = bitmap->width();
texture->height = bitmap->height();
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 2ec556e..fffd740 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -106,7 +106,7 @@ public:
friend class AssetAtlas;
};
- AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+ AssetAtlas(): mTexture(NULL), mImage(NULL),
mBlendKey(true), mOpaqueKey(false) { }
~AssetAtlas() { terminate(); }
@@ -130,7 +130,7 @@ public:
* After calling this method, the width, height
* and texture are set to 0.
*/
- ANDROID_API void terminate();
+ void terminate();
/**
* Returns the width of this atlas in pixels.
@@ -168,21 +168,13 @@ public:
*/
Texture* getEntryTexture(const SkBitmap* bitmap) const;
- /**
- * Returns the current generation id of the atlas.
- */
- uint32_t getGenerationId() const {
- return mGenerationId;
- }
-
private:
void createEntries(Caches& caches, int64_t* map, int count);
+ void updateTextureId();
Texture* mTexture;
Image* mImage;
- uint32_t mGenerationId;
-
const bool mBlendKey;
const bool mOpaqueKey;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 6453206..4bbe6ed 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -237,8 +237,6 @@ void Caches::terminate() {
programCache.clear();
currentProgram = NULL;
- assetAtlas.terminate();
-
patchCache.clear();
clearGarbage();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e338686..2e179af 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -348,8 +348,6 @@ public:
Dither dither;
Stencil stencil;
- AssetAtlas assetAtlas;
-
bool gpuPixelBuffersEnabled;
// Debug methods
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index cb8a8d1..7a43a2a 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -77,18 +77,14 @@ public:
OpenGLRenderer& mRenderer;
const int mReplayFlags;
- // Allocator with the lifetime of a single frame.
- // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator
+ // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
+ // while defer shares the DeferredDisplayList's Allocator
+ // TODO: move this allocator to be owned by object with clear frame lifecycle
LinearAllocator * const mAllocator;
SkPath* allocPathForFrame() {
- mTempPaths.push_back();
- return &mTempPaths.back();
+ return mRenderer.allocPathForFrame();
}
-
-private:
- // Paths kept alive for the duration of the frame
- std::vector<SkPath> mTempPaths;
};
class DeferStateStruct : public PlaybackStateStruct {
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 96e76d0..8a5e21d 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -32,6 +32,7 @@
#include "AssetAtlas.h"
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
+#include "RenderState.h"
#include "UvMapper.h"
#include "utils/LinearAllocator.h"
@@ -647,24 +648,17 @@ public:
DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
: DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
, mBitmap(bitmap)
- , mAtlas(Caches::getInstance().assetAtlas) {
- mEntry = mAtlas.getEntry(bitmap);
- if (mEntry) {
- mEntryGenerationId = mAtlas.getGenerationId();
- mUvMapper = mEntry->uvMapper;
- }
+ , mEntryValid(false), mEntry(NULL) {
}
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
return renderer.drawBitmap(mBitmap, getPaint(renderer));
}
- AssetAtlas::Entry* getAtlasEntry() {
- // The atlas entry is stale, let's get a new one
- if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
- mEntryGenerationId = mAtlas.getGenerationId();
- mEntry = mAtlas.getEntry(mBitmap);
- mUvMapper = mEntry->uvMapper;
+ AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+ if (!mEntryValid) {
+ mEntryValid = true;
+ mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
}
return mEntry;
}
@@ -700,7 +694,7 @@ public:
pureTranslate &= state.mMatrix.isPureTranslate();
Rect texCoords(0, 0, 1, 1);
- ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
+ ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords);
SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
@@ -729,7 +723,7 @@ public:
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
- deferInfo.mergeId = getAtlasEntry() ?
+ deferInfo.mergeId = getAtlasEntry(renderer) ?
(mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
// Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
@@ -742,13 +736,17 @@ public:
(mBitmap->colorType() != kAlpha_8_SkColorType);
}
+ void uvMap(OpenGLRenderer& renderer, Rect& texCoords) {
+ if (getAtlasEntry(renderer)) {
+ mEntry->uvMapper.map(texCoords);
+ }
+ }
+
const SkBitmap* bitmap() { return mBitmap; }
protected:
const SkBitmap* mBitmap;
- const AssetAtlas& mAtlas;
- uint32_t mEntryGenerationId;
+ bool mEntryValid;
AssetAtlas::Entry* mEntry;
- UvMapper mUvMapper;
};
class DrawBitmapRectOp : public DrawBoundedOp {
@@ -841,18 +839,13 @@ public:
float left, float top, float right, float bottom, const SkPaint* paint)
: DrawBoundedOp(left, top, right, bottom, paint),
mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
- mAtlas(Caches::getInstance().assetAtlas) {
- mEntry = mAtlas.getEntry(bitmap);
- if (mEntry) {
- mEntryGenerationId = mAtlas.getGenerationId();
- }
+ mEntryValid(false), mEntry(NULL) {
};
- AssetAtlas::Entry* getAtlasEntry() {
- // The atlas entry is stale, let's get a new one
- if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
- mEntryGenerationId = mAtlas.getGenerationId();
- mEntry = mAtlas.getEntry(mBitmap);
+ AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+ if (!mEntryValid) {
+ mEntryValid = true;
+ mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
}
return mEntry;
}
@@ -860,7 +853,7 @@ public:
const Patch* getMesh(OpenGLRenderer& renderer) {
if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
PatchCache& cache = renderer.getCaches().patchCache;
- mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
+ mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(),
mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
mGenerationId = cache.getGenerationId();
}
@@ -942,14 +935,14 @@ public:
indexCount += opMesh->indexCount;
}
- return renderer.drawPatches(mBitmap, getAtlasEntry(),
+ return renderer.drawPatches(mBitmap, getAtlasEntry(renderer),
&vertices[0], indexCount, getPaint(renderer));
}
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
// We're not calling the public variant of drawPatch() here
// This method won't perform the quickReject() since we've already done it at this point
- return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+ return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer),
mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
getPaint(renderer));
}
@@ -964,7 +957,7 @@ public:
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
- deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+ deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
@@ -977,8 +970,7 @@ private:
uint32_t mGenerationId;
const Patch* mMesh;
- const AssetAtlas& mAtlas;
- uint32_t mEntryGenerationId;
+ bool mEntryValid;
AssetAtlas::Entry* mEntry;
};
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 075f2c5..7285496 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -311,6 +311,11 @@ void OpenGLRenderer::finish() {
renderOverdraw();
endTiling();
+ for (size_t i = 0; i < mTempPaths.size(); i++) {
+ delete mTempPaths[i];
+ }
+ mTempPaths.clear();
+
// When finish() is invoked on FBO 0 we've reached the end
// of the current frame
if (getTargetFbo() == 0) {
@@ -2049,7 +2054,7 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i
}
mCaches.activeTexture(0);
- Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+ Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
const UvMapper& mapper(getMapper(texture));
for (int32_t y = 0; y < meshHeight; y++) {
@@ -2232,7 +2237,7 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch*
return DrawGlInfo::kStatusDone;
}
- AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
+ AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap);
const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
right - left, bottom - top, patch);
@@ -3028,7 +3033,7 @@ const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
///////////////////////////////////////////////////////////////////////////////
Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
- Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+ Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
if (!texture) {
return mCaches.textureCache.get(bitmap);
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e1c3d10..5eee2e2 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -342,6 +342,12 @@ public:
uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
+ SkPath* allocPathForFrame() {
+ SkPath* path = new SkPath();
+ mTempPaths.push_back(path);
+ return path;
+ }
+
protected:
/**
* Perform the setup specific to a frame. This method does not
@@ -1014,6 +1020,9 @@ private:
uint8_t mAmbientShadowAlpha;
uint8_t mSpotShadowAlpha;
+ // Paths kept alive for the duration of the frame
+ std::vector<SkPath*> mTempPaths;
+
friend class Layer;
friend class TextSetupFunctor;
friend class DrawBitmapOp;
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index a8cf26f..d1f5f4e 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -38,6 +38,7 @@ void RenderState::onGLContextCreated() {
mCaches = &Caches::getInstance();
mCaches->init();
mCaches->setRenderState(this);
+ mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
}
void RenderState::onGLContextDestroyed() {
@@ -72,6 +73,7 @@ void RenderState::onGLContextDestroyed() {
LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
}
*/
+ mAssetAtlas.terminate();
}
void RenderState::setViewport(GLsizei width, GLsizei height) {
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index afeef95..1ecfb1c 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -23,6 +23,7 @@
#include <private/hwui/DrawGlInfo.h>
+#include "AssetAtlas.h"
#include "Caches.h"
#include "utils/Macros.h"
@@ -73,6 +74,8 @@ public:
// more thinking...
void postDecStrong(VirtualLightRefBase* object);
+ AssetAtlas& assetAtlas() { return mAssetAtlas; }
+
private:
friend class renderthread::RenderThread;
friend class Caches;
@@ -86,6 +89,7 @@ private:
renderthread::RenderThread& mRenderThread;
Caches* mCaches;
+ AssetAtlas mAssetAtlas;
std::set<const Layer*> mActiveLayers;
std::set<renderthread::CanvasContext*> mRegisteredContexts;
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 5bad2fc..63454d8 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
#include <utils/Mutex.h>
+#include "AssetAtlas.h"
#include "Caches.h"
#include "TextureCache.h"
#include "Properties.h"
@@ -39,7 +40,7 @@ namespace uirenderer {
TextureCache::TextureCache():
mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
- mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
+ mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(0) {
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
INIT_LOGD(" Setting texture cache size to %sMB", property);
@@ -62,7 +63,7 @@ TextureCache::TextureCache():
TextureCache::TextureCache(uint32_t maxByteSize):
mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(maxByteSize) {
+ mSize(0), mMaxSize(maxByteSize), mAssetAtlas(0) {
init();
}
@@ -124,6 +125,10 @@ void TextureCache::operator()(uint32_t&, Texture*& texture) {
// Caching
///////////////////////////////////////////////////////////////////////////////
+void TextureCache::setAssetAtlas(AssetAtlas* assetAtlas) {
+ mAssetAtlas = assetAtlas;
+}
+
void TextureCache::resetMarkInUse() {
LruCache<uint32_t, Texture*>::Iterator iter(mCache);
while (iter.next()) {
@@ -143,6 +148,13 @@ bool TextureCache::canMakeTextureFromBitmap(const SkBitmap* bitmap) {
// Returns a prepared Texture* that either is already in the cache or can fit
// in the cache (and is thus added to the cache)
Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) {
+ if (CC_LIKELY(mAssetAtlas)) {
+ AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap);
+ if (CC_UNLIKELY(entry)) {
+ return entry->texture;
+ }
+ }
+
Texture* texture = mCache.get(bitmap->pixelRef()->getStableID());
if (!texture) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 3e94d1f..cf8d134 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -44,6 +44,8 @@ namespace uirenderer {
// Classes
///////////////////////////////////////////////////////////////////////////////
+class AssetAtlas;
+
/**
* A simple LRU texture cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
@@ -123,6 +125,8 @@ public:
*/
void setFlushRate(float flushRate);
+ void setAssetAtlas(AssetAtlas* assetAtlas);
+
private:
bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
@@ -155,6 +159,8 @@ private:
Vector<uint32_t> mGarbage;
mutable Mutex mLock;
+
+ AssetAtlas* mAssetAtlas;
}; // class TextureCache
}; // namespace uirenderer
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 378cf61..8fb1b10 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -175,7 +175,8 @@ void EglManager::setTextureAtlas(const sp<GraphicBuffer>& buffer,
void EglManager::initAtlas() {
if (mAtlasBuffer.get()) {
- Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize);
+ mRenderThread.renderState().assetAtlas().init(mAtlasBuffer,
+ mAtlasMap, mAtlasMapSize);
}
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0e69f74..b606a6f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -197,6 +197,7 @@
<!-- Alternate Recents -->
<activity android:name=".recents.RecentsActivity"
android:label="@string/accessibility_desc_recent_apps"
+ android:exported="false"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:stateNotNeeded="true"
@@ -207,6 +208,17 @@
</intent-filter>
</activity>
+ <receiver android:name=".recents.RecentsUserEventProxyReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER" />
+ <action android:name="com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER" />
+ <action android:name="com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER" />
+ <action android:name="com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER" />
+ <action android:name="com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER" />
+ </intent-filter>
+ </receiver>
+
<!-- started from UsbDeviceSettingsManager -->
<activity android:name=".usb.UsbConfirmActivity"
android:exported="true"
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index 9a55590..e9f3cf9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -18,6 +18,7 @@ package com.android.systemui.recent;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
+import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -44,16 +45,29 @@ public class Recents extends SystemUI implements RecentsComponent {
// Which recents to use
boolean mUseAlternateRecents = true;
- AlternateRecentsComponent mAlternateRecents;
boolean mBootCompleted = false;
+ static AlternateRecentsComponent sAlternateRecents;
+
+ /** Returns the Recents component, creating a new one in-process if necessary. */
+ public static AlternateRecentsComponent getRecentsComponent(Context context,
+ boolean forceInitialize) {
+ if (sAlternateRecents == null) {
+ sAlternateRecents = new AlternateRecentsComponent(context);
+ if (forceInitialize) {
+ sAlternateRecents.onStart();
+ sAlternateRecents.onBootCompleted();
+ }
+ }
+ return sAlternateRecents;
+ }
@Override
public void start() {
if (mUseAlternateRecents) {
- if (mAlternateRecents == null) {
- mAlternateRecents = new AlternateRecentsComponent(mContext);
+ if (sAlternateRecents == null) {
+ sAlternateRecents = getRecentsComponent(mContext, false);
}
- mAlternateRecents.onStart();
+ sAlternateRecents.onStart();
}
putComponent(RecentsComponent.class, this);
@@ -62,8 +76,8 @@ public class Recents extends SystemUI implements RecentsComponent {
@Override
protected void onBootCompleted() {
if (mUseAlternateRecents) {
- if (mAlternateRecents != null) {
- mAlternateRecents.onBootCompleted();
+ if (sAlternateRecents != null) {
+ sAlternateRecents.onBootCompleted();
}
}
mBootCompleted = true;
@@ -72,14 +86,14 @@ public class Recents extends SystemUI implements RecentsComponent {
@Override
public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
if (mUseAlternateRecents) {
- mAlternateRecents.onShowRecents(triggeredFromAltTab, statusBarView);
+ sAlternateRecents.onShowRecents(triggeredFromAltTab);
}
}
@Override
public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
if (mUseAlternateRecents) {
- mAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
+ sAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
} else {
Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
intent.setPackage("com.android.systemui");
@@ -93,7 +107,7 @@ public class Recents extends SystemUI implements RecentsComponent {
public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
if (mUseAlternateRecents) {
// Launch the alternate recents if required
- mAlternateRecents.onToggleRecents(statusBarView);
+ sAlternateRecents.onToggleRecents();
return;
}
@@ -241,14 +255,14 @@ public class Recents extends SystemUI implements RecentsComponent {
@Override
protected void onConfigurationChanged(Configuration newConfig) {
if (mUseAlternateRecents) {
- mAlternateRecents.onConfigurationChanged(newConfig);
+ sAlternateRecents.onConfigurationChanged(newConfig);
}
}
@Override
public void preloadRecents() {
if (mUseAlternateRecents) {
- mAlternateRecents.onPreloadRecents();
+ sAlternateRecents.onPreloadRecents();
} else {
Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
intent.setClassName("com.android.systemui",
@@ -262,7 +276,7 @@ public class Recents extends SystemUI implements RecentsComponent {
@Override
public void cancelPreloadingRecents() {
if (mUseAlternateRecents) {
- mAlternateRecents.onCancelPreloadingRecents();
+ sAlternateRecents.onCancelPreloadingRecents();
} else {
Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
intent.setClassName("com.android.systemui",
@@ -276,21 +290,21 @@ public class Recents extends SystemUI implements RecentsComponent {
@Override
public void showNextAffiliatedTask() {
if (mUseAlternateRecents) {
- mAlternateRecents.onShowNextAffiliatedTask();
+ sAlternateRecents.onShowNextAffiliatedTask();
}
}
@Override
public void showPrevAffiliatedTask() {
if (mUseAlternateRecents) {
- mAlternateRecents.onShowPrevAffiliatedTask();
+ sAlternateRecents.onShowPrevAffiliatedTask();
}
}
@Override
public void setCallback(Callbacks cb) {
if (mUseAlternateRecents) {
- mAlternateRecents.setRecentsComponentCallback(cb);
+ sAlternateRecents.setRecentsComponentCallback(cb);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index f1bf66d..09a6ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -27,6 +27,7 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -38,7 +39,6 @@ import android.os.UserHandle;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
-
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.recents.misc.Console;
@@ -57,12 +57,27 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+/**
+ * Annotation for a method that is only called from the primary user's SystemUI process and will be
+ * proxied to the current user.
+ */
+@interface ProxyFromPrimaryToCurrentUser {}
+/**
+ * Annotation for a method that may be called from any user's SystemUI process and will be proxied
+ * to the primary user.
+ */
+@interface ProxyFromAnyToPrimaryUser {}
/** A proxy implementation for the recents component */
public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
- final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
- final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
+ final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "triggeredFromAltTab";
+ final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "triggeredFromHomeKey";
+ final public static String EXTRA_RECENTS_VISIBILITY = "recentsVisibility";
+
+ // Owner proxy events
+ final public static String ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER =
+ "action_notify_recents_visibility_change";
final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
@@ -78,9 +93,22 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
* An implementation of ITaskStackListener, that allows us to listen for changes to the system
* task stacks and update recents accordingly.
*/
- class TaskStackListenerImpl extends ITaskStackListener.Stub {
+ class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
+ Handler mHandler;
+
+ public TaskStackListenerImpl(Handler handler) {
+ mHandler = handler;
+ }
+
@Override
public void onTaskStackChanged() {
+ // Debounce any task stack changes
+ mHandler.removeCallbacks(this);
+ mHandler.post(this);
+ }
+
+ /** Preloads the next task */
+ public void run() {
RecentsConfiguration config = RecentsConfiguration.getInstance();
if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
// Load the next task only if we aren't svelte
@@ -96,6 +124,20 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
}
+ /**
+ * A proxy for Recents events which happens strictly for the owner.
+ */
+ class RecentsOwnerEventProxyReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER:
+ visibilityChanged(intent.getBooleanExtra(EXTRA_RECENTS_VISIBILITY, false));
+ break;
+ }
+ }
+ }
+
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -104,6 +146,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
SystemServicesProxy mSystemServicesProxy;
Handler mHandler;
TaskStackListenerImpl mTaskStackListener;
+ RecentsOwnerEventProxyReceiver mProxyBroadcastReceiver;
boolean mBootCompleted;
boolean mStartAnimationTriggered;
boolean mCanReuseTaskStackViews = true;
@@ -123,7 +166,6 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
TaskStackView mDummyStackView;
// Variables to keep track of if we need to start recents after binding
- View mStatusBarView;
boolean mTriggeredFromAltTab;
long mLastToggleTime;
@@ -136,30 +178,37 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
mTaskStackBounds = new Rect();
// Register the task stack listener
- mTaskStackListener = new TaskStackListenerImpl();
+ mTaskStackListener = new TaskStackListenerImpl(mHandler);
mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
+
+ // Only the owner has the callback to update the SysUI visibility flags, so all non-owner
+ // instances of AlternateRecentsComponent needs to notify the owner when the visibility
+ // changes.
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(AlternateRecentsComponent.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
+ mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter,
+ null, mHandler);
+ }
+ }
+
+ /** Creates a new broadcast intent */
+ static Intent createLocalBroadcastIntent(Context context, String action) {
+ Intent intent = new Intent(action);
+ intent.setPackage(context.getPackageName());
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+ Intent.FLAG_RECEIVER_FOREGROUND);
+ return intent;
}
+ /** Initializes the Recents. */
+ @ProxyFromPrimaryToCurrentUser
public void onStart() {
// Initialize some static datastructures
TaskStackViewLayoutAlgorithm.initializeCurve();
// Load the header bar layout
- reloadHeaderBarLayout();
- // Try and pre-emptively bind the search widget on startup to ensure that we
- // have the right thumbnail bounds to animate to.
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- // If there is no id, then bind a new search app widget
- if (mConfig.searchBarAppWidgetId < 0) {
- AppWidgetHost host = new RecentsAppWidgetHost(mContext,
- Constants.Values.App.AppWidgetHostId);
- Pair<Integer, AppWidgetProviderInfo> widgetInfo =
- mSystemServicesProxy.bindSearchAppWidget(host);
- if (widgetInfo != null) {
- // Save the app widget id into the settings
- mConfig.updateSearchBarAppWidgetId(mContext, widgetInfo.first);
- }
- }
- }
+ reloadHeaderBarLayout(true);
// When we start, preload the data associated with the previous recent tasks.
// We can use a new plan since the caches will be the same.
@@ -177,9 +226,19 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
mBootCompleted = true;
}
- /** Shows the recents */
- public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) {
- mStatusBarView = statusBarView;
+ /** Shows the Recents. */
+ @ProxyFromPrimaryToCurrentUser
+ public void onShowRecents(boolean triggeredFromAltTab) {
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ showRecents(triggeredFromAltTab);
+ } else {
+ Intent intent = createLocalBroadcastIntent(mContext,
+ RecentsUserEventProxyReceiver.ACTION_PROXY_SHOW_RECENTS_TO_USER);
+ intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ }
+ }
+ void showRecents(boolean triggeredFromAltTab) {
mTriggeredFromAltTab = triggeredFromAltTab;
try {
@@ -189,16 +248,25 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
}
- /** Hides the recents */
+ /** Hides the Recents. */
+ @ProxyFromPrimaryToCurrentUser
public void onHideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
+ } else {
+ Intent intent = createLocalBroadcastIntent(mContext,
+ RecentsUserEventProxyReceiver.ACTION_PROXY_HIDE_RECENTS_TO_USER);
+ intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+ intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ }
+ }
+ void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
if (mBootCompleted) {
ActivityManager.RunningTaskInfo topTask = getTopMostTask();
if (topTask != null && isRecentsTopMost(topTask, null)) {
// Notify recents to hide itself
- Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY);
- intent.setPackage(mContext.getPackageName());
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
- Intent.FLAG_RECEIVER_FOREGROUND);
+ Intent intent = createLocalBroadcastIntent(mContext, ACTION_HIDE_RECENTS_ACTIVITY);
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
@@ -206,9 +274,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
}
- /** Toggles the alternate recents activity */
- public void onToggleRecents(View statusBarView) {
- mStatusBarView = statusBarView;
+ /** Toggles the Recents activity. */
+ @ProxyFromPrimaryToCurrentUser
+ public void onToggleRecents() {
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ toggleRecents();
+ } else {
+ Intent intent = createLocalBroadcastIntent(mContext,
+ RecentsUserEventProxyReceiver.ACTION_PROXY_TOGGLE_RECENTS_TO_USER);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ }
+ }
+ void toggleRecents() {
mTriggeredFromAltTab = false;
try {
@@ -218,7 +295,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
}
+ /** Preloads info for the Recents activity. */
+ @ProxyFromPrimaryToCurrentUser
public void onPreloadRecents() {
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ preloadRecents();
+ } else {
+ Intent intent = createLocalBroadcastIntent(mContext,
+ RecentsUserEventProxyReceiver.ACTION_PROXY_PRELOAD_RECENTS_TO_USER);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ }
+ }
+ void preloadRecents() {
// Preload only the raw task list into a new load plan (which will be consumed by the
// RecentsActivity)
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
@@ -309,15 +397,26 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
showRelativeAffiliatedTask(false);
}
+ /** Updates on configuration change. */
+ @ProxyFromPrimaryToCurrentUser
public void onConfigurationChanged(Configuration newConfig) {
+ if (mSystemServicesProxy.isForegroundUserOwner()) {
+ configurationChanged();
+ } else {
+ Intent intent = createLocalBroadcastIntent(mContext,
+ RecentsUserEventProxyReceiver.ACTION_PROXY_CONFIG_CHANGE_TO_USER);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ }
+ }
+ void configurationChanged() {
// Don't reuse task stack views if the configuration changes
mCanReuseTaskStackViews = false;
// Reload the header bar layout
- reloadHeaderBarLayout();
+ reloadHeaderBarLayout(false);
}
/** Prepares the header bar layout. */
- void reloadHeaderBarLayout() {
+ void reloadHeaderBarLayout(boolean reloadWidget) {
Resources res = mContext.getResources();
mWindowRect = mSystemServicesProxy.getWindowRect();
mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
@@ -325,6 +424,10 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
mConfig.updateOnConfigurationChange();
+ if (reloadWidget) {
+ // Reload the widget id before we get the task stack bounds
+ reloadSearchBarAppWidget(mContext, mSystemServicesProxy);
+ }
mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
(mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds);
if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
@@ -350,6 +453,24 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight);
}
+ /** Prepares the search bar app widget */
+ void reloadSearchBarAppWidget(Context context, SystemServicesProxy ssp) {
+ // Try and pre-emptively bind the search widget on startup to ensure that we
+ // have the right thumbnail bounds to animate to.
+ if (Constants.DebugFlags.App.EnableSearchLayout) {
+ // If there is no id, then bind a new search app widget
+ if (mConfig.searchBarAppWidgetId < 0) {
+ AppWidgetHost host = new RecentsAppWidgetHost(context,
+ Constants.Values.App.AppWidgetHostId);
+ Pair<Integer, AppWidgetProviderInfo> widgetInfo = ssp.bindSearchAppWidget(host);
+ if (widgetInfo != null) {
+ // Save the app widget id into the settings
+ mConfig.updateSearchBarAppWidgetId(context, widgetInfo.first);
+ }
+ }
+ }
+ }
+
/** Gets the top task. */
ActivityManager.RunningTaskInfo getTopMostTask() {
SystemServicesProxy ssp = mSystemServicesProxy;
@@ -397,10 +518,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
AtomicBoolean isTopTaskHome = new AtomicBoolean(true);
if (topTask != null && isRecentsTopMost(topTask, isTopTaskHome)) {
// Notify recents to toggle itself
- Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY);
- intent.setPackage(mContext.getPackageName());
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
- Intent.FLAG_RECEIVER_FOREGROUND);
+ Intent intent = createLocalBroadcastIntent(mContext, ACTION_TOGGLE_RECENTS_ACTIVITY);
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
mLastToggleTime = SystemClock.elapsedRealtime();
return;
@@ -474,7 +592,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
mStartAnimationTriggered = false;
- return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mStatusBarView,
+ return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(),
toTaskRect.height(), this);
}
@@ -623,7 +741,19 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
}
/** Notifies the callbacks that the visibility of Recents has changed. */
- public static void notifyVisibilityChanged(boolean visible) {
+ @ProxyFromAnyToPrimaryUser
+ public static void notifyVisibilityChanged(Context context, SystemServicesProxy ssp,
+ boolean visible) {
+ if (ssp.isForegroundUserOwner()) {
+ visibilityChanged(visible);
+ } else {
+ Intent intent = createLocalBroadcastIntent(context,
+ ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
+ intent.putExtra(EXTRA_RECENTS_VISIBILITY, visible);
+ context.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ }
+ }
+ static void visibilityChanged(boolean visible) {
if (sRecentsComponentCallbacks != null) {
sRecentsComponentCallbacks.onVisibilityChanged(visible);
}
@@ -667,10 +797,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
};
// Send the broadcast to notify Recents that the animation has started
- Intent intent = new Intent(ACTION_START_ENTER_ANIMATION);
- intent.setPackage(mContext.getPackageName());
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
- Intent.FLAG_RECEIVER_FOREGROUND);
+ Intent intent = createLocalBroadcastIntent(mContext, ACTION_START_ENTER_ANIMATION);
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
fallbackReceiver, null, Activity.RESULT_CANCELED, null, null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 6baff96..ee631f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -434,7 +434,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
protected void onStart() {
super.onStart();
mVisible = true;
- AlternateRecentsComponent.notifyVisibilityChanged(true);
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ SystemServicesProxy ssp = loader.getSystemServicesProxy();
+ AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, true);
// Register the broadcast receiver to handle messages from our service
IntentFilter filter = new IntentFilter();
@@ -444,7 +446,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
registerReceiver(mServiceBroadcastReceiver, filter);
// Register any broadcast receivers for the task loader
- RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
+ loader.registerReceivers(this, mRecentsView);
// Update the recent tasks
updateRecentsTasks(getIntent());
@@ -454,7 +456,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
protected void onStop() {
super.onStop();
mVisible = false;
- AlternateRecentsComponent.notifyVisibilityChanged(false);
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ SystemServicesProxy ssp = loader.getSystemServicesProxy();
+ AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, false);
// Notify the views that we are no longer visible
mRecentsView.onRecentsHidden();
@@ -463,7 +467,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
unregisterReceiver(mServiceBroadcastReceiver);
// Unregister any broadcast receivers for the task loader
- RecentsTaskLoader.getInstance().unregisterReceivers();
+ loader.unregisterReceivers();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java
new file mode 100644
index 0000000..236da5d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 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.systemui.recents;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import com.android.systemui.recent.Recents;
+
+
+/**
+ * A proxy for Recents events which happens strictly for non-owner users.
+ */
+public class RecentsUserEventProxyReceiver extends BroadcastReceiver {
+ final public static String ACTION_PROXY_SHOW_RECENTS_TO_USER =
+ "com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER";
+ final public static String ACTION_PROXY_HIDE_RECENTS_TO_USER =
+ "com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER";
+ final public static String ACTION_PROXY_TOGGLE_RECENTS_TO_USER =
+ "com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER";
+ final public static String ACTION_PROXY_PRELOAD_RECENTS_TO_USER =
+ "com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER";
+ final public static String ACTION_PROXY_CONFIG_CHANGE_TO_USER =
+ "com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ AlternateRecentsComponent recents = Recents.getRecentsComponent(
+ context.getApplicationContext(), true);
+ switch (intent.getAction()) {
+ case ACTION_PROXY_SHOW_RECENTS_TO_USER: {
+ boolean triggeredFromAltTab = intent.getBooleanExtra(
+ AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
+ recents.showRecents(triggeredFromAltTab);
+ break;
+ }
+ case ACTION_PROXY_HIDE_RECENTS_TO_USER: {
+ boolean triggeredFromAltTab = intent.getBooleanExtra(
+ AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
+ boolean triggeredFromHome = intent.getBooleanExtra(
+ AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false);
+ recents.hideRecents(triggeredFromAltTab, triggeredFromHome);
+ break;
+ }
+ case ACTION_PROXY_TOGGLE_RECENTS_TO_USER:
+ recents.toggleRecents();
+ break;
+ case ACTION_PROXY_PRELOAD_RECENTS_TO_USER:
+ recents.preloadRecents();
+ break;
+ case ACTION_PROXY_CONFIG_CHANGE_TO_USER:
+ recents.configurationChanged();
+ break;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 3fbd5a6..542f21c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -49,14 +49,12 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayInfo;
-import android.view.IWindowManager;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -396,6 +394,15 @@ public class SystemServicesProxy {
}
/**
+ * Returns whether the foreground user is the owner.
+ */
+ public boolean isForegroundUserOwner() {
+ if (mAm == null) return false;
+
+ return mAm.getCurrentUser() == UserHandle.USER_OWNER;
+ }
+
+ /**
* Resolves and returns the first Recents widget from the same package as the global
* assist activity.
*/
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 89aebe8..63a0cf6 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3421,7 +3421,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return false;
}
- // Windows are ordered in z order so start from the botton and find
+ // Windows are ordered in z order so start from the bottom and find
// the window of interest. After that all windows that cover it should
// be subtracted from the resulting region. Note that for accessibility
// we are returning only interactive windows.
@@ -3439,7 +3439,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
windowInteractiveRegion = outRegion;
continue;
}
- } else {
+ } else if (currentWindow.getType()
+ != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
Rect currentWindowBounds = mTempRect;
currentWindow.getBoundsInScreen(currentWindowBounds);
if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 3117a17..ca376fd 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -535,15 +535,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Log.d(TAG, "Creating new ProfileServiceConnections object for"
+ " profile: " + bluetoothProfile);
}
- Intent intent = null;
- if (bluetoothProfile == BluetoothProfile.HEADSET) {
- intent = new Intent(IBluetoothHeadset.class.getName());
- } else {
- return false;
- }
+
+ if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
+
+ Intent intent = new Intent(IBluetoothHeadset.class.getName());
psc = new ProfileServiceConnections(intent);
+ if (!psc.bindService()) return false;
+
mProfileServices.put(new Integer(bluetoothProfile), psc);
- psc.bindService();
}
}
@@ -571,7 +570,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
synchronized (mProfileServices) {
for (Integer i : mProfileServices.keySet()) {
ProfileServiceConnections psc = mProfileServices.get(i);
- mContext.unbindService(psc);
+ try {
+ mContext.unbindService(psc);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
+ }
psc.removeAllProxies();
}
mProfileServices.clear();
@@ -596,16 +599,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mIntent = intent;
}
- private void bindService() {
- if (mIntent != null && mService == null) {
- if (!doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
- Log.w(TAG, "Unable to bind with intent: " + mIntent
- + ". Triggering retry.");
- }
+ private boolean bindService() {
+ if (mIntent != null && mService == null &&
+ doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
msg.obj = this;
mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
+ return true;
}
+ Log.w(TAG, "Unable to bind with intent: " + mIntent);
+ return false;
}
private void addProxy(IBluetoothProfileServiceConnection proxy) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1227148..844980b 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1841,7 +1841,9 @@ public final class ActivityManagerService extends ActivityManagerNative
proc = mPendingPssProcesses.remove(0);
procState = proc.pssProcState;
lastPssTime = proc.lastPssTime;
- if (proc.thread != null && procState == proc.setProcState) {
+ if (proc.thread != null && procState == proc.setProcState
+ && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
+ < SystemClock.uptimeMillis()) {
pid = proc.pid;
} else {
proc = null;
@@ -17746,7 +17748,8 @@ public final class ActivityManagerService extends ActivityManagerNative
+ (app.nextPssTime-now) + ": " + app);
} else {
if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
- && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
+ && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
+ mTestPssMode)))) {
requestPssLocked(app, app.setProcState);
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
mTestPssMode, isSleeping(), now);
@@ -18969,6 +18972,31 @@ public final class ActivityManagerService extends ActivityManagerNative
}
mUserSwitchObservers.finishBroadcast();
}
+ stopGuestUserIfBackground();
+ }
+
+ /**
+ * Stops the guest user if it has gone to the background.
+ */
+ private void stopGuestUserIfBackground() {
+ synchronized (this) {
+ final int num = mUserLru.size();
+ for (int i = 0; i < num; i++) {
+ Integer oldUserId = mUserLru.get(i);
+ UserStartedState oldUss = mStartedUsers.get(oldUserId);
+ if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
+ || oldUss.mState == UserStartedState.STATE_STOPPING
+ || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+ continue;
+ }
+ UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
+ if (userInfo.isGuest()) {
+ // This is a user to be stopped.
+ stopUserLocked(oldUserId, null);
+ break;
+ }
+ }
+ }
}
void scheduleStartProfilesLocked() {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index aa86786..ae4af5f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -238,7 +238,7 @@ final class ProcessList {
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
// Increase the high min-free levels for cached processes for 64-bit
mOomMinFreeHigh[4] = (mOomMinFreeHigh[4]*3)/2;
- mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/8;
+ mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/4;
}
for (int i=0; i<mOomAdj.length; i++) {
@@ -411,7 +411,10 @@ final class ProcessList {
sb.append(ramKb);
}
- // The minimum amount of time after a state change it is safe ro collect PSS.
+ // How long after a state change that it is safe to collect PSS without it being dirty.
+ public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
+
+ // The minimum time interval after a state change it is safe to collect PSS.
public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
// The maximum amount of time we want to go between PSS collections.
@@ -441,6 +444,9 @@ final class ProcessList {
// The amount of time until PSS when a cached process stays in the same state.
private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
+ // The minimum time interval after a state change it is safe to collect PSS.
+ public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
+
// The amount of time during testing until PSS when a process first becomes top.
private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
@@ -548,6 +554,10 @@ final class ProcessList {
return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
}
+ public static long minTimeFromStateChange(boolean test) {
+ return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
+ }
+
public static long computeNextPssTime(int procState, boolean first, boolean test,
boolean sleeping, long now) {
final long[] table = test
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bb99916..650f0e2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1028,6 +1028,7 @@ public class NotificationManagerService extends SystemService {
? mListenersDisablingEffects.valueAt(0).component : null;
if (Objects.equals(suppressor, mEffectsSuppressor)) return;
mEffectsSuppressor = suppressor;
+ mZenModeHelper.setEffectsSuppressed(suppressor != null);
getContext().sendBroadcast(new Intent(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 012e22f..31d5cd7 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -17,6 +17,7 @@
package com.android.server.notification;
import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
import android.app.AppOpsManager;
@@ -77,6 +78,7 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
private int mPreviousRingerMode = -1;
+ private boolean mEffectsSuppressed;
public ZenModeHelper(Context context, Looper looper) {
mContext = context;
@@ -153,6 +155,12 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
}
}
+ public void setEffectsSuppressed(boolean effectsSuppressed) {
+ if (mEffectsSuppressed == effectsSuppressed) return;
+ mEffectsSuppressed = effectsSuppressed;
+ applyRestrictions();
+ }
+
public boolean shouldIntercept(NotificationRecord record) {
if (isSystem(record)) {
return false;
@@ -225,29 +233,35 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
ZenLog.traceUpdateZenMode(oldMode, newMode);
}
mZenMode = newMode;
+ applyRestrictions();
+ onZenUpdated(oldMode, newMode);
+ dispatchOnZenModeChanged();
+ }
+
+ private void applyRestrictions() {
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
- final String[] exceptionPackages = null; // none (for now)
+
+ // notification restrictions
+ final boolean muteNotifications = mEffectsSuppressed;
+ applyRestrictions(muteNotifications, USAGE_NOTIFICATION);
// call restrictions
- final boolean muteCalls = zen && !mConfig.allowCalls;
- mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_NOTIFICATION_RINGTONE,
- muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
- mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_NOTIFICATION_RINGTONE,
- muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
+ final boolean muteCalls = zen && !mConfig.allowCalls || mEffectsSuppressed;
+ applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
// alarm restrictions
final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
- mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM,
- muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+ applyRestrictions(muteAlarms, USAGE_ALARM);
+ }
+
+ private void applyRestrictions(boolean mute, int usage) {
+ final String[] exceptionPackages = null; // none (for now)
+ mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage,
+ mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
exceptionPackages);
- mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_ALARM,
- muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+ mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, usage,
+ mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
exceptionPackages);
-
- onZenUpdated(oldMode, newMode);
- dispatchOnZenModeChanged();
}
public void dump(PrintWriter pw, String prefix) {
@@ -257,6 +271,7 @@ public class ZenModeHelper implements AudioManagerInternal.RingerModeDelegate {
pw.print(prefix); pw.print("mDefaultConfig="); pw.println(mDefaultConfig);
pw.print(prefix); pw.print("mPreviousRingerMode="); pw.println(mPreviousRingerMode);
pw.print(prefix); pw.print("mDefaultPhoneApp="); pw.println(mDefaultPhoneApp);
+ pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
}
public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index c1420a8..37d811f 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -68,9 +68,18 @@ public class KeyguardDisableHandler extends Handler {
break;
case KEYGUARD_POLICY_CHANGED:
- mPolicy.enableKeyguard(true);
- // lazily evaluate this next time we're asked to disable keyguard
mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
+ if (mKeyguardTokenWatcher.isAcquired()) {
+ // If we are currently disabled we need to know if the keyguard
+ // should be re-enabled, so determine the allow state immediately.
+ mKeyguardTokenWatcher.updateAllowState();
+ if (mAllowDisableKeyguard != ALLOW_DISABLE_YES) {
+ mPolicy.enableKeyguard(true);
+ }
+ } else {
+ // lazily evaluate this next time we're asked to disable keyguard
+ mPolicy.enableKeyguard(true);
+ }
break;
}
}
@@ -81,24 +90,28 @@ public class KeyguardDisableHandler extends Handler {
super(handler, TAG);
}
- @Override
- public void acquired() {
+ public void updateAllowState() {
// We fail safe and prevent disabling keyguard in the unlikely event this gets
// called before DevicePolicyManagerService has started.
- if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
- DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- try {
- mAllowDisableKeyguard = dpm.getPasswordQuality(null,
- ActivityManagerNative.getDefault().getCurrentUser().id)
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
- ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
- } catch (RemoteException re) {
- // Nothing much we can do
- }
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ try {
+ mAllowDisableKeyguard = dpm.getPasswordQuality(null,
+ ActivityManagerNative.getDefault().getCurrentUser().id)
+ == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
+ ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
+ } catch (RemoteException re) {
+ // Nothing much we can do
}
}
+ }
+
+ @Override
+ public void acquired() {
+ if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
+ updateAllowState();
+ }
if (mAllowDisableKeyguard == ALLOW_DISABLE_YES) {
mPolicy.enableKeyguard(false);
} else {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 73e3213..d0ddeac 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -43,6 +43,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -3183,6 +3184,39 @@ public class TelephonyManager {
}
/**
+ * Override the roaming preference for the current ICCID.
+ *
+ * Using this call, the carrier app (see #hasCarrierPrivileges) can override
+ * the platform's notion of a network operator being considered roaming or not.
+ * The change only affects the ICCID that was active when this call was made.
+ *
+ * If null is passed as any of the input, the corresponding value is deleted.
+ *
+ * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges.
+ *
+ * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs.
+ * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs.
+ * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs.
+ * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs.
+ * @return true if the operation was executed correctly.
+ *
+ * @hide
+ */
+ public boolean setRoamingOverride(List<String> gsmRoamingList,
+ List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
+ List<String> cdmaNonRoamingList) {
+ try {
+ return getITelephony().setRoamingOverride(gsmRoamingList, gsmNonRoamingList,
+ cdmaRoamingList, cdmaNonRoamingList);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "setRoamingOverride RemoteException", ex);
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "setRoamingOverride NPE", ex);
+ }
+ return false;
+ }
+
+ /**
* Expose the rest of ITelephony to @SystemApi
*/
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 4affad8..ca14ca4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -792,6 +792,27 @@ interface ITelephony {
boolean setOperatorBrandOverride(String brand);
/**
+ * Override the roaming indicator for the current ICCID.
+ *
+ * Using this call, the carrier app (see #hasCarrierPrivileges) can override
+ * the platform's notion of a network operator being considered roaming or not.
+ * The change only affects the ICCID that was active when this call was made.
+ *
+ * If null is passed as any of the input, the corresponding value is deleted.
+ *
+ * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges.
+ *
+ * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs.
+ * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs.
+ * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs.
+ * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs.
+ * @return true if the operation was executed correctly.
+ */
+ boolean setRoamingOverride(in List<String> gsmRoamingList,
+ in List<String> gsmNonRoamingList, in List<String> cdmaRoamingList,
+ in List<String> cdmaNonRoamingList);
+
+ /**
* Returns the result and response from RIL for oem request
*
* @param oemReq the data is sent to ril.