Merge "Always apply window insets to action modes" into lmp-dev
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 701ab1d..5f3ed61 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5066,7 +5066,7 @@
public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
ActivityManager.TaskDescription td;
// Scale the icon down to something reasonable if it is provided
- if (taskDescription.getIcon() != null) {
+ if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9486a72..85d4839 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -56,9 +56,11 @@
import android.util.DisplayMetrics;
import android.util.Size;
import android.util.Slog;
+import org.xmlpull.v1.XmlSerializer;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -508,8 +510,18 @@
* Information you can set and retrieve about the current activity within the recent task list.
*/
public static class TaskDescription implements Parcelable {
+ /** @hide */
+ public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
+ private static final String ATTR_TASKDESCRIPTIONLABEL =
+ ATTR_TASKDESCRIPTION_PREFIX + "label";
+ private static final String ATTR_TASKDESCRIPTIONCOLOR =
+ ATTR_TASKDESCRIPTION_PREFIX + "color";
+ private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
+ ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";
+
private String mLabel;
private Bitmap mIcon;
+ private String mIconFilename;
private int mColorPrimary;
/**
@@ -529,6 +541,12 @@
mColorPrimary = colorPrimary;
}
+ /** @hide */
+ public TaskDescription(String label, int colorPrimary, String iconFilename) {
+ this(label, null, colorPrimary);
+ mIconFilename = iconFilename;
+ }
+
/**
* Creates the TaskDescription to the specified values.
*
@@ -559,7 +577,10 @@
* Creates a copy of another TaskDescription.
*/
public TaskDescription(TaskDescription td) {
- this(td.getLabel(), td.getIcon(), td.getPrimaryColor());
+ mLabel = td.mLabel;
+ mIcon = td.mIcon;
+ setPrimaryColor(td.mColorPrimary);
+ mIconFilename = td.mIconFilename;
}
private TaskDescription(Parcel source) {
@@ -579,7 +600,7 @@
* @hide
*/
public void setPrimaryColor(int primaryColor) {
- mColorPrimary = primaryColor;
+ mColorPrimary = 0xFF000000 | primaryColor;
}
/**
@@ -591,6 +612,16 @@
}
/**
+ * Moves the icon bitmap reference from an actual Bitmap to a file containing the
+ * bitmap.
+ * @hide
+ */
+ public void setIconFilename(String iconFilename) {
+ mIconFilename = iconFilename;
+ mIcon = null;
+ }
+
+ /**
* @return The label and description of the current state of this task.
*/
public String getLabel() {
@@ -601,7 +632,22 @@
* @return The icon that represents the current state of this task.
*/
public Bitmap getIcon() {
- return mIcon;
+ if (mIcon != null) {
+ return mIcon;
+ }
+ if (mIconFilename != null) {
+ try {
+ return ActivityManagerNative.getDefault().
+ getTaskDescriptionIcon(mIconFilename);
+ } catch (RemoteException e) {
+ }
+ }
+ return null;
+ }
+
+ /** @hide */
+ public String getIconFilename() {
+ return mIconFilename;
}
/**
@@ -611,6 +657,30 @@
return mColorPrimary;
}
+ /** @hide */
+ public void saveToXml(XmlSerializer out) throws IOException {
+ if (mLabel != null) {
+ out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
+ }
+ if (mColorPrimary != 0) {
+ out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary));
+ }
+ if (mIconFilename != null) {
+ out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
+ }
+ }
+
+ /** @hide */
+ public void restoreFromXml(String attrName, String attrValue) {
+ if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
+ setLabel(attrValue);
+ } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
+ setPrimaryColor((int) Long.parseLong(attrValue, 16));
+ } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
+ setIconFilename(attrValue);
+ }
+ }
+
@Override
public int describeContents() {
return 0;
@@ -631,12 +701,19 @@
mIcon.writeToParcel(dest, 0);
}
dest.writeInt(mColorPrimary);
+ if (mIconFilename == null) {
+ dest.writeInt(0);
+ } else {
+ dest.writeInt(1);
+ dest.writeString(mIconFilename);
+ }
}
public void readFromParcel(Parcel source) {
mLabel = source.readInt() > 0 ? source.readString() : null;
mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
mColorPrimary = source.readInt();
+ mIconFilename = source.readInt() > 0 ? source.readString() : null;
}
public static final Creator<TaskDescription> CREATOR
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 677fcef..11470e3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2253,6 +2253,20 @@
return true;
}
+ case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String filename = data.readString();
+ Bitmap icon = getTaskDescriptionIcon(filename);
+ reply.writeNoException();
+ if (icon == null) {
+ reply.writeInt(0);
+ } else {
+ reply.writeInt(1);
+ icon.writeToParcel(reply, 0);
+ }
+ return true;
+ }
+
case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -5241,6 +5255,20 @@
}
@Override
+ public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(filename);
+ mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
+ reply.readException();
+ final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ return icon;
+ }
+
+ @Override
public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8fa1fd53..aa5fea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -451,6 +451,7 @@
public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
throws RemoteException;
+ public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
@@ -775,4 +776,5 @@
int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
+ int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index b677888..c850f71 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -814,8 +814,8 @@
}
}
if (mTargetIds.size() == 0 && mTargets.size() == 0 &&
- (mTargetTypes == null || mTargetTypes.isEmpty() &&
- (mTargetNames == null || mTargetNames.isEmpty()))) {
+ (mTargetTypes == null || mTargetTypes.isEmpty()) &&
+ (mTargetNames == null || mTargetNames.isEmpty())) {
return true;
}
if (mTargetIds.contains(targetId) || mTargets.contains(target)) {
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 06b7a93..0687905 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -1205,7 +1205,6 @@
if (!hasSections || !mMatchDragPosition) {
return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
}
-
// Ignore headers.
firstVisibleItem -= mHeaderCount;
if (firstVisibleItem < 0) {
@@ -1255,9 +1254,19 @@
// across the last item account for whatever space is remaining.
if (firstVisibleItem > 0 && firstVisibleItem + visibleItemCount == totalItemCount) {
final View lastChild = mList.getChildAt(visibleItemCount - 1);
- final float lastItemVisible = (float) (mList.getHeight() - mList.getPaddingBottom()
- - lastChild.getTop()) / lastChild.getHeight();
- result += (1 - result) * lastItemVisible;
+ final int bottomPadding = mList.getPaddingBottom();
+ final int maxSize;
+ final int currentVisibleSize;
+ if (mList.getClipToPadding()) {
+ maxSize = lastChild.getHeight();
+ currentVisibleSize = mList.getHeight() - bottomPadding - lastChild.getTop();
+ } else {
+ maxSize = lastChild.getHeight() + bottomPadding;
+ currentVisibleSize = mList.getHeight() - lastChild.getTop();
+ }
+ if (currentVisibleSize > 0 && maxSize > 0) {
+ result += (1 - result) * ((float) currentVisibleSize / maxSize );
+ }
}
return result;
diff --git a/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index 5e67395..0000000
--- a/core/res/res/drawable-hdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 9c2ee13..0000000
--- a/core/res/res/drawable-hdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index cb8f78a..0000000
--- a/core/res/res/drawable-mdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 64d4c81..0000000
--- a/core/res/res/drawable-mdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index 8e7862f..0000000
--- a/core/res/res/drawable-xhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index 95cb83f..0000000
--- a/core/res/res/drawable-xhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index eb495c6..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index c2268af..0000000
--- a/core/res/res/drawable-xxhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
deleted file mode 100644
index fbcd7d4..0000000
--- a/core/res/res/drawable-xxxhdpi/spinner_textfield_activated_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png
deleted file mode 100644
index ebc9bf7..0000000
--- a/core/res/res/drawable-xxxhdpi/spinner_textfield_default_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/spinner_textfield_background_material.xml b/core/res/res/drawable/spinner_textfield_background_material.xml
index 5bdff4a..2732d53 100644
--- a/core/res/res/drawable/spinner_textfield_background_material.xml
+++ b/core/res/res/drawable/spinner_textfield_background_material.xml
@@ -17,17 +17,29 @@
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="@dimen/control_inset_material">
<selector android:autoMirrored="true">
- <item android:state_checked="true">
- <nine-patch android:src="@drawable/spinner_textfield_activated_mtrl_alpha"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:state_pressed="true">
- <nine-patch android:src="@drawable/spinner_textfield_activated_mtrl_alpha"
- android:tint="?attr/colorControlActivated" />
+ <item android:state_checked="false" android:state_pressed="false">
+ <layer-list android:paddingMode="stack">
+ <item>
+ <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+ android:tint="?attr/colorControlNormal" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
+ android:tint="?attr/colorControlNormal" />
+ </item>
+ </layer-list>
</item>
<item>
- <nine-patch android:src="@drawable/spinner_textfield_default_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
+ <layer-list android:paddingMode="stack">
+ <item>
+ <nine-patch android:src="@drawable/textfield_activated_mtrl_alpha"
+ android:tint="?attr/colorControlActivated" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/spinner_mtrl_am_alpha"
+ android:tint="?attr/colorControlActivated" />
+ </item>
+ </layer-list>
</item>
</selector>
</inset>
diff --git a/core/res/res/values-mcc238-mnc06/config.xml b/core/res/res/values-mcc238-mnc06/config.xml
new file mode 100644
index 0000000..afc0cc4
--- /dev/null
+++ b/core/res/res/values-mcc238-mnc06/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- SIM does not save, but the voice mail number to be changed. -->
+ <bool name="editable_voicemailnumber">true</bool>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ef3f47e..949c38c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1811,4 +1811,7 @@
<!-- Sprint need a 70 ms delay for 3way call -->
<integer name="config_cdma_3waycall_flash_delay">0</integer>
+
+ <!--SIM does not save, but the voice mail number to be changed. -->
+ <bool name="editable_voicemailnumber">false</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ea7188d..ed43faf 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -322,6 +322,7 @@
<java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_5" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_24" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_5" />
+ <java-symbol type="bool" name="editable_voicemailnumber" />
<java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
<java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0445fe8..e9a1acf 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -670,6 +670,8 @@
<string name="recents_lock_to_app_button_label">lock to app</string>
<!-- Recents: Temporary string for the button in the recents search bar. [CHAR LIMIT=NONE] -->
<string name="recents_search_bar_label">search</string>
+ <!-- Recents: Launch error string. [CHAR LIMIT=NONE] -->
+ <string name="recents_launch_error_message">Could not start <xliff:g id="app" example="Calendar">%s</xliff:g>.</string>
<!-- Expanded Status Bar Header: Battery Charged [CHAR LIMIT=40] -->
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 787de4e..5caf1ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -32,6 +33,7 @@
import android.graphics.Rect;
import android.os.Handler;
import android.os.UserHandle;
+import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import com.android.systemui.R;
@@ -118,6 +120,22 @@
// Load the header bar layout
reloadHeaderBarLayout();
mBootCompleted = true;
+
+ // 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);
+ }
+ }
+ }
}
/** Shows the recents */
@@ -222,9 +240,8 @@
// Bring an active task to the foreground
mSystemServicesProxy.moveTaskToFront(toTask.key.id, launchOpts);
} else {
- try {
- mSystemServicesProxy.startActivityFromRecents(toTask.key.id, launchOpts);
- } catch (ActivityNotFoundException anfe) {}
+ mSystemServicesProxy.startActivityFromRecents(mContext, toTask.key.id,
+ toTask.activityLabel, launchOpts);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 8f92027..a49bbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -405,6 +405,22 @@
mConfig.updateOnConfigurationChange();
onConfigurationChange();
}
+
+ // Start listening for widget package changes if there is one bound, post it since we don't
+ // want it stalling the startup
+ if (mConfig.searchBarAppWidgetId >= 0) {
+ final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
+ new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
+ mRecentsView.post(new Runnable() {
+ @Override
+ public void run() {
+ RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
+ if (cb != null) {
+ mAppWidgetHost.startListening(cb);
+ }
+ }
+ });
+ }
}
/** Inflates the debug overlay if debug mode is enabled. */
@@ -464,22 +480,6 @@
protected void onResume() {
super.onResume();
- // Start listening for widget package changes if there is one bound, post it since we don't
- // want it stalling the startup
- if (mConfig.searchBarAppWidgetId >= 0) {
- final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
- new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
- mRecentsView.postDelayed(new Runnable() {
- @Override
- public void run() {
- RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
- if (cb != null) {
- mAppWidgetHost.startListening(cb);
- }
- }
- }, 1);
- }
-
// Mark Recents as visible
mVisible = true;
}
@@ -496,11 +496,6 @@
// Unregister any broadcast receivers for the task loader
RecentsTaskLoader.getInstance().unregisterReceivers();
-
- // Stop listening for widget package changes if there was one bound
- if (mAppWidgetHost.isListening()) {
- mAppWidgetHost.stopListening();
- }
}
@Override
@@ -509,6 +504,11 @@
// Unregister the system broadcast receivers
unregisterReceiver(mSystemBroadcastReceiver);
+
+ // Stop listening for widget package changes if there was one bound
+ if (mAppWidgetHost.isListening()) {
+ mAppWidgetHost.stopListening();
+ }
}
@Override
@@ -614,6 +614,12 @@
}
@Override
+ public void onTaskLaunchFailed() {
+ // Return to Home
+ dismissRecentsToHomeRaw(true);
+ }
+
+ @Override
public void onAllTaskViewsDismissed() {
mFinishLaunchHomeRunnable.run();
}
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 11b7b8b..9554f01 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -57,6 +57,7 @@
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import java.io.IOException;
@@ -515,12 +516,18 @@
return takeScreenshot();
}
- public void startActivityFromRecents(int taskId, ActivityOptions options) {
+ /** Starts an activity from recents. */
+ public boolean startActivityFromRecents(Context context, int taskId, String taskName,
+ ActivityOptions options) {
if (mIam != null) {
try {
mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle());
- } catch (RemoteException e) {
+ return true;
+ } catch (Exception e) {
+ Console.logError(context,
+ context.getString(R.string.recents_launch_error_message, taskName));
}
}
+ return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index e6d0280..6c22a3b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -56,6 +56,7 @@
/** The RecentsView callbacks */
public interface RecentsViewCallbacks {
public void onTaskViewClicked();
+ public void onTaskLaunchFailed();
public void onAllTaskViewsDismissed();
public void onExitToHomeAnimationTriggered();
}
@@ -471,13 +472,18 @@
// Bring an active task to the foreground
ssp.moveTaskToFront(task.key.id, launchOpts);
} else {
- try {
- ssp.startActivityFromRecents(task.key.id, launchOpts);
+ if (ssp.startActivityFromRecents(getContext(), task.key.id,
+ task.activityLabel, launchOpts)) {
if (launchOpts == null && lockToTask) {
ssp.lockCurrentTask();
}
- } catch (ActivityNotFoundException anfe) {
- Console.logError(getContext(), "Could not start Activity");
+ } else {
+ // Dismiss the task and return the user to home if we fail to
+ // launch the task
+ onTaskViewDismissed(task);
+ if (mCb != null) {
+ mCb.onTaskLaunchFailed();
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 685c184..4715d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -67,8 +67,7 @@
@Override
public void onClick(View v) {
- final UserManager um = UserManager.get(getContext());
- if (um.isUserSwitcherEnabled()) {
+ if (opensUserSwitcherWhenClicked()) {
if (mKeyguardMode) {
if (mKeyguardUserSwitcher != null) {
mKeyguardUserSwitcher.show(true /* animate */);
@@ -92,9 +91,8 @@
super.onPopulateAccessibilityEvent(event);
if (isClickable()) {
- final UserManager um = UserManager.get(getContext());
String text;
- if (um.isUserSwitcherEnabled()) {
+ if (opensUserSwitcherWhenClicked()) {
String currentUser = null;
if (mQsPanel != null) {
UserSwitcherController controller = mQsPanel.getHost()
@@ -122,4 +120,9 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ private boolean opensUserSwitcherWhenClicked() {
+ UserManager um = UserManager.get(getContext());
+ return UserManager.supportsMultipleUsers() && um.isUserSwitcherEnabled();
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6d8e105..741cffe 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8375,12 +8375,17 @@
synchronized (this) {
ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r != null) {
- r.taskDescription = td;
+ r.setTaskDescription(td);
r.task.updateTaskDescription();
}
}
}
+ @Override
+ public Bitmap getTaskDescriptionIcon(String filename) {
+ return mTaskPersister.getTaskDescriptionIcon(filename);
+ }
+
private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
mRecentTasks.remove(tr);
tr.removedFromRecents(mTaskPersister);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index adea271..2db7cec 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -205,14 +205,18 @@
pw.print(" resultWho="); pw.print(resultWho);
pw.print(" resultCode="); pw.println(requestCode);
}
- if (taskDescription.getIcon() != null || taskDescription.getLabel() != null ||
+ final String iconFilename = taskDescription.getIconFilename();
+ if (iconFilename != null || taskDescription.getLabel() != null ||
taskDescription.getPrimaryColor() != 0) {
pw.print(prefix); pw.print("taskDescription:");
- pw.print(" icon="); pw.print(taskDescription.getIcon());
+ pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
pw.print(" label=\""); pw.print(taskDescription.getLabel()); pw.print("\"");
pw.print(" color=");
pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
}
+ if (iconFilename == null && taskDescription.getIcon() != null) {
+ pw.print(prefix); pw.println("taskDescription contains Bitmap");
+ }
if (results != null) {
pw.print(prefix); pw.print("results="); pw.println(results);
}
@@ -1093,6 +1097,17 @@
TaskPersister.IMAGE_EXTENSION;
}
+ void setTaskDescription(TaskDescription _taskDescription) {
+ Bitmap icon;
+ if (_taskDescription.getIconFilename() == null &&
+ (icon = _taskDescription.getIcon()) != null) {
+ final String iconFilename = createImageFilename(createTime, task.taskId);
+ mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilename);
+ _taskDescription.setIconFilename(iconFilename);
+ }
+ taskDescription = _taskDescription;
+ }
+
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
out.attribute(null, ATTR_ID, String.valueOf(createTime));
out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
@@ -1106,8 +1121,7 @@
out.attribute(null, ATTR_USERID, String.valueOf(userId));
if (taskDescription != null) {
- task.saveTaskDescription(taskDescription, createImageFilename(createTime, task.taskId),
- out);
+ taskDescription.saveToXml(out);
}
out.startTag(null, TAG_INTENT);
@@ -1151,9 +1165,8 @@
componentSpecified = Boolean.valueOf(attrValue);
} else if (ATTR_USERID.equals(attrName)) {
userId = Integer.valueOf(attrValue);
- } else if (TaskRecord.readTaskDescriptionAttribute(taskDescription, attrName,
- attrValue)) {
- // Completed in TaskRecord.readTaskDescriptionAttribute()
+ } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
+ taskDescription.restoreFromXml(attrName, attrValue);
} else {
Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
}
@@ -1197,11 +1210,6 @@
null, null, 0, componentSpecified, stackSupervisor, null, null);
r.persistentState = persistentState;
-
- if (createTime >= 0) {
- taskDescription.setIcon(TaskPersister.restoreImage(createImageFilename(createTime,
- taskId)));
- }
r.taskDescription = taskDescription;
r.createTime = createTime;
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index df1772a..1c0564f 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -218,7 +218,16 @@
yieldIfQueueTooDeep();
}
- Bitmap getThumbnail(String filename) {
+ Bitmap getTaskDescriptionIcon(String filename) {
+ // See if it is in the write queue
+ final Bitmap icon = getImageFromWriteQueue(filename);
+ if (icon != null) {
+ return icon;
+ }
+ return restoreImage(filename);
+ }
+
+ Bitmap getImageFromWriteQueue(String filename) {
synchronized (this) {
for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
final WriteQueueItem item = mWriteQueue.get(queueNdx);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index f74b795..73c9783 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -25,6 +25,7 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskThumbnail;
+import android.app.ActivityManager.TaskDescription;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -70,15 +71,12 @@
private static final String ATTR_LASTDESCRIPTION = "last_description";
private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
- private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label";
- private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color";
private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
private static final String ATTR_CALLING_UID = "calling_uid";
private static final String ATTR_CALLING_PACKAGE = "calling_package";
- private static final String LAST_ACTIVITY_ICON_SUFFIX = "_last_activity_icon_";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -113,8 +111,7 @@
// This represents the last resolved activity values for this task
// NOTE: This value needs to be persisted with each task
- ActivityManager.TaskDescription lastTaskDescription =
- new ActivityManager.TaskDescription();
+ TaskDescription lastTaskDescription = new TaskDescription();
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
@@ -180,7 +177,7 @@
}
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
- ActivityManager.TaskDescription _taskDescription) {
+ TaskDescription _taskDescription) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -215,7 +212,7 @@
boolean _askedCompatMode, int _taskType, int _userId, int _effectiveUid,
String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
- ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
+ TaskDescription _lastTaskDescription, int taskAffiliation,
int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
String callingPackage) {
mService = service;
@@ -441,7 +438,7 @@
thumbs.mainThumbnail = mLastThumbnail;
thumbs.thumbnailFileDescriptor = null;
if (mLastThumbnail == null) {
- thumbs.mainThumbnail = mService.mTaskPersister.getThumbnail(mFilename);
+ thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
}
// Only load the thumbnail file if we don't have a thumbnail
if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) {
@@ -759,7 +756,7 @@
// recent activity values, then we do not fall back to the last set
// values in the TaskRecord.
String label = null;
- Bitmap icon = null;
+ String iconFilename = null;
int colorPrimary = 0;
for (--activityNdx; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = mActivities.get(activityNdx);
@@ -767,15 +764,15 @@
if (label == null) {
label = r.taskDescription.getLabel();
}
- if (icon == null) {
- icon = r.taskDescription.getIcon();
+ if (iconFilename == null) {
+ iconFilename = r.taskDescription.getIconFilename();
}
if (colorPrimary == 0) {
colorPrimary = r.taskDescription.getPrimaryColor();
}
}
}
- lastTaskDescription = new ActivityManager.TaskDescription(label, icon, colorPrimary);
+ lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
// Update the task affiliation color if we are the parent of the group
if (taskId == mAffiliatedTaskId) {
mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
@@ -784,18 +781,19 @@
}
int findEffectiveRootIndex() {
- int activityNdx;
+ int effectiveNdx = 0;
final int topActivityNdx = mActivities.size() - 1;
- for (activityNdx = 0; activityNdx < topActivityNdx; ++activityNdx) {
+ for (int activityNdx = 0; activityNdx < topActivityNdx; ++activityNdx) {
final ActivityRecord r = mActivities.get(activityNdx);
if (r.finishing) {
continue;
}
+ effectiveNdx = activityNdx;
if ((r.info.flags & ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
break;
}
}
- return activityNdx;
+ return effectiveNdx;
}
void updateEffectiveIntent() {
@@ -804,41 +802,6 @@
setIntent(r);
}
- void saveTaskDescription(ActivityManager.TaskDescription taskDescription,
- String iconFilename, XmlSerializer out) throws IOException {
- if (taskDescription != null) {
- final String label = taskDescription.getLabel();
- if (label != null) {
- out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label);
- }
- final int colorPrimary = taskDescription.getPrimaryColor();
- if (colorPrimary != 0) {
- out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary));
- }
- final Bitmap icon = taskDescription.getIcon();
- if (icon != null) {
- mService.mTaskPersister.saveImage(icon, iconFilename);
- }
- }
- }
-
- static boolean readTaskDescriptionAttribute(ActivityManager.TaskDescription taskDescription,
- String attrName, String attrValue) {
- if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
- taskDescription.setLabel(attrValue);
- } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
- taskDescription.setPrimaryColor((int) Long.parseLong(attrValue, 16));
- } else {
- return false;
- }
- return true;
- }
-
- private static String createLastTaskDescriptionIconFilename(int taskId, long lastActiveTime) {
- return String.valueOf(taskId) + LAST_ACTIVITY_ICON_SUFFIX + lastActiveTime +
- TaskPersister.IMAGE_EXTENSION;
- }
-
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
if (ActivityManagerService.DEBUG_RECENTS) Slog.i(TAG, "Saving task=" + this);
@@ -875,8 +838,7 @@
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
}
if (lastTaskDescription != null) {
- saveTaskDescription(lastTaskDescription, createLastTaskDescriptionIconFilename(taskId,
- lastActiveTime), out);
+ lastTaskDescription.saveToXml(out);
}
out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
@@ -934,7 +896,7 @@
boolean neverRelinquishIdentity = true;
int taskId = -1;
final int outerDepth = in.getDepth();
- ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription();
+ TaskDescription taskDescription = new TaskDescription();
int taskAffiliation = -1;
int taskAffiliationColor = 0;
int prevTaskId = -1;
@@ -980,8 +942,8 @@
lastTimeOnTop = Long.valueOf(attrValue);
} else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
neverRelinquishIdentity = Boolean.valueOf(attrValue);
- } else if (readTaskDescriptionAttribute(taskDescription, attrName, attrValue)) {
- // Completed in TaskPersister.readTaskDescriptionAttribute()
+ } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
+ taskDescription.restoreFromXml(attrName, attrValue);
} else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
taskAffiliation = Integer.valueOf(attrValue);
} else if (ATTR_PREV_AFFILIATION.equals(attrName)) {
@@ -1025,11 +987,6 @@
}
}
- if (lastActiveTime >= 0) {
- taskDescription.setIcon(TaskPersister.restoreImage(
- createLastTaskDescriptionIconFilename(taskId, lastActiveTime)));
- }
-
if (!hasRootAffinity) {
rootAffinity = affinity;
} else if ("@".equals(rootAffinity)) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a3da1e6..fdf2fc8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3356,7 +3356,8 @@
}
isFullScreen =
((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ==
- SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN);
+ SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) ||
+ ((win.mAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0);
}
if (atoken.mLaunchTaskBehind) {
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
index 5385413..0ec4d9d 100644
--- a/tests/Compatibility/Android.mk
+++ b/tests/Compatibility/Android.mk
@@ -18,12 +18,12 @@
# We only want this apk build for tests.
LOCAL_MODULE_TAGS := tests
+LOCAL_JAVA_LIBRARIES := android.test.runner
# Include all test java files.
LOCAL_SRC_FILES := \
$(call all-java-files-under, src)
-LOCAL_SDK_VERSION := 8
LOCAL_PACKAGE_NAME := AppCompatibilityTest
include $(BUILD_PACKAGE)
diff --git a/tests/Compatibility/AndroidManifest.xml b/tests/Compatibility/AndroidManifest.xml
index 103ef4c..2884532 100644
--- a/tests/Compatibility/AndroidManifest.xml
+++ b/tests/Compatibility/AndroidManifest.xml
@@ -24,6 +24,4 @@
android:name=".AppCompatibilityRunner"
android:targetPackage="com.android.compatibilitytest"
android:label="App Compability Test Runner" />
-
- <uses-sdk android:minSdkVersion="8"></uses-sdk>
</manifest>
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
index a2e9117..5794b2b 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -147,11 +147,19 @@
* during the app launch.
*/
private ProcessErrorStateInfo launchActivity(String packageName) {
+ // the recommended way to see if this is a tv or not.
+ boolean isleanback = !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
+ && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
+ Intent intent;
+ if (isleanback) {
+ Log.d(TAG, "Leanback and relax!");
+ intent = mPackageManager.getLeanbackLaunchIntentForPackage(packageName);
+ } else {
+ intent = mPackageManager.getLaunchIntentForPackage(packageName);
+ }
// Skip if the apk does not have a launch intent.
if (intent == null) {
Log.d(TAG, "Skipping " + packageName + "; missing launch intent");