Merge "Fix admin policies in managed profiles" into lmp-dev
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0e98175..4b705dd 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3847,14 +3847,14 @@
* their launch had come from the original activity.
* @hide
*/
- public void startActivityAsCaller(Intent intent, @Nullable Bundle options) {
+ public void startActivityAsCaller(Intent intent, @Nullable Bundle options, int userId) {
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivityAsCaller(
this, mMainThread.getApplicationThread(), mToken, this,
- intent, -1, options);
+ intent, -1, options, userId);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, -1, ar.getResultCode(),
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6c67c09..4e2ff0b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -184,8 +184,9 @@
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
+ int userId = data.readInt();
int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
- resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
+ resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
reply.writeNoException();
reply.writeInt(result);
return true;
@@ -2435,7 +2436,7 @@
}
public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
+ int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2459,6 +2460,7 @@
} else {
data.writeInt(0);
}
+ data.writeInt(userId);
mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index b72addf..be26f30 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -69,7 +69,7 @@
ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
+ int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ba3a234..60a013e 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1671,7 +1671,7 @@
*/
public ActivityResult execStartActivityAsCaller(
Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
+ Intent intent, int requestCode, Bundle options, int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -1695,7 +1695,7 @@
.startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
+ requestCode, 0, null, options, userId);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a9d16bc..a30ae57 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -439,14 +439,20 @@
= "android.app.action.SET_NEW_PASSWORD";
/**
- * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from a
- * managed profile to its parent.
+ * Flag used by {@link #addCrossProfileIntentFilter} to allow access
+ * <em>from</em> a managed profile <em>to</em> its parent. That is, any
+ * matching activities in the parent profile are included in the
+ * disambiguation list shown when an app in the managed profile calls
+ * {@link Activity#startActivity(Intent)}.
*/
public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001;
/**
- * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from the
- * parent to its managed profile.
+ * Flag used by {@link #addCrossProfileIntentFilter} to allow access
+ * <em>from</em> a parent <em>to</em> its managed profile. That is, any
+ * matching activities in the managed profile are included in the
+ * disambiguation list shown when an app in the parent profile calls
+ * {@link Activity#startActivity(Intent)}.
*/
public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 6daefc8..ba62cd6 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -20,6 +20,7 @@
import android.content.pm.IPackageInstallerCallback;
import android.content.pm.IPackageInstallerSession;
import android.content.pm.PackageInstaller;
+import android.content.pm.ParceledListSlice;
import android.content.IntentSender;
import android.graphics.Bitmap;
@@ -37,8 +38,8 @@
PackageInstaller.SessionInfo getSessionInfo(int sessionId);
- List<PackageInstaller.SessionInfo> getAllSessions(int userId);
- List<PackageInstaller.SessionInfo> getMySessions(String installerPackageName, int userId);
+ ParceledListSlice getAllSessions(int userId);
+ ParceledListSlice getMySessions(String installerPackageName, int userId);
void registerCallback(IPackageInstallerCallback callback, int userId);
void unregisterCallback(IPackageInstallerCallback callback);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 765b2a9..b66bd01 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -235,6 +235,9 @@
public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
/** @hide */
+ public boolean coreApp;
+
+ /** @hide */
public boolean requiredForAllUsers;
/** @hide */
@@ -293,6 +296,7 @@
dest.writeTypedArray(reqFeatures, parcelableFlags);
dest.writeTypedArray(featureGroups, parcelableFlags);
dest.writeInt(installLocation);
+ dest.writeInt(coreApp ? 1 : 0);
dest.writeInt(requiredForAllUsers ? 1 : 0);
dest.writeString(restrictedAccountType);
dest.writeString(requiredAccountType);
@@ -337,6 +341,7 @@
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
featureGroups = source.createTypedArray(FeatureGroupInfo.CREATOR);
installLocation = source.readInt();
+ coreApp = source.readInt() != 0;
requiredForAllUsers = source.readInt() != 0;
restrictedAccountType = source.readString();
requiredAccountType = source.readString();
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index f249c5f..80efd0b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -399,7 +399,7 @@
}
try {
- return mInstaller.getAllSessions(mUserId);
+ return mInstaller.getAllSessions(mUserId).getList();
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -410,7 +410,7 @@
*/
public @NonNull List<SessionInfo> getMySessions() {
try {
- return mInstaller.getMySessions(mInstallerPackageName, mUserId);
+ return mInstaller.getMySessions(mInstallerPackageName, mUserId).getList();
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3364741..ca4ff6a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -415,6 +415,7 @@
pi.sharedUserLabel = p.mSharedUserLabel;
pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
pi.installLocation = p.installLocation;
+ pi.coreApp = p.coreApp;
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = p.mRequiredForAllUsers;
@@ -1384,6 +1385,8 @@
PARSE_DEFAULT_INSTALL_LOCATION);
pkg.applicationInfo.installLocation = pkg.installLocation;
+ pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false);
+
sa.recycle();
/* Set the global "forward lock" flag */
@@ -4267,6 +4270,8 @@
public int installLocation;
+ public boolean coreApp;
+
/* An app that's required for all users and cannot be uninstalled for a user */
public boolean mRequiredForAllUsers;
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index d9493752..6e2f84a 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -20,26 +20,28 @@
import android.app.Activity;
import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
import android.app.AppGlobals;
-import android.os.Bundle;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.UserInfo;
+import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
import android.widget.Toast;
+
import java.util.List;
-import java.util.Set;
-/*
- * This is used in conjunction with the {@link setCrossProfileIntentFilter} method of
- * {@link DevicePolicyManager} to enable intents to be passed in and out of a managed profile.
+/**
+ * This is used in conjunction with
+ * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to
+ * be passed in and out of a managed profile.
*/
-
public class IntentForwarderActivity extends Activity {
public static String TAG = "IntentForwarderActivity";
@@ -104,7 +106,23 @@
final boolean shouldShowDisclosure =
!UserHandle.isSameApp(ri.activityInfo.applicationInfo.uid, Process.SYSTEM_UID);
- startActivityAsUser(newIntent, userDest);
+ try {
+ startActivityAsCaller(newIntent, null, userDest.getIdentifier());
+ } catch (RuntimeException e) {
+ int launchedFromUid = -1;
+ String launchedFromPackage = "?";
+ try {
+ launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+ getActivityToken());
+ launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+ getActivityToken());
+ } catch (RemoteException ignored) {
+ }
+
+ Slog.wtf(TAG, "Unable to launch as UID " + launchedFromUid + " package "
+ + launchedFromPackage + ", while running in "
+ + ActivityThread.currentProcessName(), e);
+ }
if (shouldShowDisclosure) {
Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index aa55d23..0062e2d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -641,7 +641,7 @@
return;
}
try {
- startActivityAsCaller(intent, null);
+ startActivityAsCaller(intent, null, UserHandle.USER_NULL);
} catch (RuntimeException e) {
String launchedFromPackage;
try {
diff --git a/core/res/res/values-mcc234-mnc08/config.xml b/core/res/res/values-mcc234-mnc08/config.xml
new file mode 100644
index 0000000..13d4d8f
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc08/config.xml
@@ -0,0 +1,26 @@
+<?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">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>23430</item>
+ <item>23433</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4aabc84..c156887 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4839,17 +4839,17 @@
<string name="day_of_week_label_typeface">sans-serif</string>
<!-- Notify use that they are in Lock-to-app -->
- <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Recents at the same time.</string>
+ <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Overview at the same time.</string>
<!-- Notify use that they are in Lock-to-app in accessibility mode -->
- <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Recents.</string>
+ <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Overview.</string>
<!-- Notify user that they are locked in lock-to-app mode -->
<string name="lock_to_app_toast_locked">Screen is pinned. Unpinning isn\'t allowed by your organization.</string>
<!-- Lock-to-app dialog title. -->
<string name="lock_to_app_title">Use screen pinning?</string>
<!-- Lock-to-app dialog description. -->
- <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Back and Recents at the same time.</string>
+ <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Back and Overview at the same time.</string>
<!-- Lock-to-app dialog description when in accessibility mode. -->
- <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Recents.</string>
+ <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Overview.</string>
<!-- Lock-to-app negative response. -->
<string name="lock_to_app_negative">NO, THANKS</string>
<!-- Lock-to-app positive response. -->
diff --git a/docs/html/design/media/dialogs_examples.png b/docs/html/design/media/dialogs_examples.png
index 6ffcee2..c136476 100644
--- a/docs/html/design/media/dialogs_examples.png
+++ b/docs/html/design/media/dialogs_examples.png
Binary files differ
diff --git a/docs/html/design/media/navigation_drawer_titles_icons.png b/docs/html/design/media/navigation_drawer_titles_icons.png
index 902a72d..7cf1e0c 100644
--- a/docs/html/design/media/navigation_drawer_titles_icons.png
+++ b/docs/html/design/media/navigation_drawer_titles_icons.png
Binary files differ
diff --git a/docs/html/design/media/selection_adjusting_actions.png b/docs/html/design/media/selection_adjusting_actions.png
index 32a7fec..0799b6b 100644
--- a/docs/html/design/media/selection_adjusting_actions.png
+++ b/docs/html/design/media/selection_adjusting_actions.png
Binary files differ
diff --git a/docs/html/design/media/touch_feedback_communication.png b/docs/html/design/media/touch_feedback_communication.png
index 1d4a9dc..f8162d0 100644
--- a/docs/html/design/media/touch_feedback_communication.png
+++ b/docs/html/design/media/touch_feedback_communication.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_notifications.png b/docs/html/design/media/ui_overview_notifications.png
index 7975657..6043412 100644
--- a/docs/html/design/media/ui_overview_notifications.png
+++ b/docs/html/design/media/ui_overview_notifications.png
Binary files differ
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 84ada6f..20254f0 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -286,7 +286,9 @@
mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() {
@Override
public void onDied() {
- if (isFinishing()) {
+ // If we are finishing or we are in a state that we do not need any
+ // data from the printing app, then no need to finish.
+ if (isFinishing() || (isFinalState(mState) && !mPrintedDocument.isUpdating())) {
return;
}
setState(STATE_PRINT_CANCELED);
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9ee18f3..71b9b61 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -40,8 +40,8 @@
<!-- Message that is read when you enter recent apps in TalkBack -->
<plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one">1 recent app</item>
- <item quantity="other">%d recent apps</item>
+ <item quantity="one">1 screen in Overview</item>
+ <item quantity="other">%d screens in Overview</item>
</plurals>
<!-- The label in the bar at the top of the status bar when there are no notifications
@@ -206,7 +206,7 @@
<!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_menu">Menu</string>
<!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_recent">Recent screens</string>
+ <string name="accessibility_recent">Overview</string>
<!-- Content description of the search button for accessibility. [CHAR LIMIT=NONE] -->
<string name="accessibility_search_light">Search</string>
<!-- Content description of the camera button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -413,7 +413,7 @@
<!-- Content description for the settings button in the status bar header. [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_settings">Settings</string>
<!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_desc_recent_apps">Recent screens.</string>
+ <string name="accessibility_desc_recent_apps">Overview.</string>
<!-- Content description of the user tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_user">User <xliff:g id="user" example="John Doe">%s</xliff:g>.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index d8c99f8..a7ff0bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -372,6 +372,7 @@
}
protected void onTrackingStarted() {
+ mClosing = false;
mTracking = true;
mCollapseAfterPeek = false;
mBar.onTrackingStarted(PanelView.this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index e4a1c27..853628e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -738,8 +738,9 @@
if (mExpandedOnStart) {
// We are collapsing the shade, so the first child can get as most as high as the
- // current height.
- mFirstChildMaxHeight = mFirstChildWhileExpanding.getActualHeight();
+ // current height or the end value of the animation.
+ mFirstChildMaxHeight = StackStateAnimator.getFinalActualHeight(
+ mFirstChildWhileExpanding);
} else {
updateFirstChildMaxSizeToMaxHeight();
}
@@ -801,9 +802,14 @@
this.mIsExpanded = isExpanded;
}
- public void notifyChildrenChanged(ViewGroup hostView) {
+ public void notifyChildrenChanged(final ViewGroup hostView) {
if (mIsExpansionChanging) {
- updateFirstChildHeightWhileExpanding(hostView);
+ hostView.post(new Runnable() {
+ @Override
+ public void run() {
+ updateFirstChildHeightWhileExpanding(hostView);
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index a69390e..433357e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -709,7 +709,7 @@
};
}
- private <T> T getChildTag(View child, int tag) {
+ private static <T> T getChildTag(View child, int tag) {
return (T) child.getTag(tag);
}
@@ -848,4 +848,20 @@
currentAnimator.cancel();
}
}
+
+ /**
+ * Get the end value of the height animation running on a view or the actualHeight
+ * if no animation is running.
+ */
+ public static int getFinalActualHeight(ExpandableView view) {
+ if (view == null) {
+ return 0;
+ }
+ ValueAnimator heightAnimator = getChildTag(view, TAG_ANIMATOR_HEIGHT);
+ if (heightAnimator == null) {
+ return view.getActualHeight();
+ } else {
+ return getChildTag(view, TAG_END_HEIGHT);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8357366..8dfb321 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3561,7 +3561,7 @@
@Override
public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options) {
+ int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
// This is very dangerous -- it allows you to perform a start activity (including
// permission grants) as any app that may launch one of your own activities. So
@@ -3599,11 +3599,15 @@
targetPackage = sourceRecord.launchedFromPackage;
}
+ if (userId == UserHandle.USER_NULL) {
+ userId = UserHandle.getUserId(sourceRecord.app.uid);
+ }
+
// TODO: Switch to user app stacks here.
try {
int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
- null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
+ null, null, options, userId, null, null);
return ret;
} catch (SecurityException e) {
// XXX need to figure out how to propagate to original app.
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 198273e..1a0e45e 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -205,17 +205,20 @@
pw.print(" resultWho="); pw.print(resultWho);
pw.print(" resultCode="); pw.println(requestCode);
}
- final String iconFilename = taskDescription.getIconFilename();
- if (iconFilename != null || taskDescription.getLabel() != null ||
- taskDescription.getPrimaryColor() != 0) {
- pw.print(prefix); pw.print("taskDescription:");
- 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 (taskDescription != null) {
+ final String iconFilename = taskDescription.getIconFilename();
+ if (iconFilename != null || taskDescription.getLabel() != null ||
+ taskDescription.getPrimaryColor() != 0) {
+ pw.print(prefix); pw.print("taskDescription:");
+ 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);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index b2300a6..fc53c50 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -73,8 +73,9 @@
}
/**
- * Called right after the action is created. Initialization or first step to take
- * for the action can be done in this method.
+ * Called after the action is created. Initialization or first step to take
+ * for the action can be done in this method. Shall update {@code mState} to
+ * indicate that the action has started.
*
* @return true if the operation is successful; otherwise false.
*/
@@ -162,6 +163,10 @@
mActionTimer.sendTimerMessage(state, delayMillis);
}
+ boolean started() {
+ return mState != STATE_NONE;
+ }
+
protected final void sendCommand(HdmiCecMessage cmd) {
mService.sendCecCommand(cmd);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 41ac589..8f9af61 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -617,14 +617,25 @@
@ServiceThreadOnly
void addAndStartAction(final HdmiCecFeatureAction action) {
assertRunOnServiceThread();
+ mActions.add(action);
if (mService.isPowerStandbyOrTransient()) {
- Slog.w(TAG, "Skip the action during Standby: " + action);
+ Slog.i(TAG, "Not ready to start action. Queued for deferred start:" + action);
return;
}
- mActions.add(action);
action.start();
}
+ @ServiceThreadOnly
+ void startQueuedActions() {
+ assertRunOnServiceThread();
+ for (HdmiCecFeatureAction action : mActions) {
+ if (!action.started()) {
+ Slog.i(TAG, "Starting queued action:" + action);
+ action.start();
+ }
+ }
+ }
+
// See if we have an action of a given type in progress.
@ServiceThreadOnly
<T extends HdmiCecFeatureAction> boolean hasAction(final Class<T> clazz) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index b0ddf2ac..780d54b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -39,11 +39,18 @@
}
@Override
+ void init() {
+ super.init();
+ mIsActiveSource = false;
+ }
+
+ @Override
@ServiceThreadOnly
protected void onAddressAllocated(int logicalAddress, int reason) {
assertRunOnServiceThread();
mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
mAddress, mService.getPhysicalAddress(), mDeviceType));
+ startQueuedActions();
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index bd9f04b..0fb4b48 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -142,6 +142,7 @@
launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
reason != HdmiControlService.INITIATED_BY_BOOT_UP);
launchDeviceDiscovery();
+ startQueuedActions();
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 4d9b4e9..60d1520 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -415,12 +415,17 @@
assertRunOnServiceThread();
// A container for [Device type, Local device info].
ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>();
- clearLocalDevices();
for (int type : mLocalDevices) {
- final HdmiCecLocalDevice localDevice = HdmiCecLocalDevice.create(this, type);
+ HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type);
+ if (localDevice == null) {
+ localDevice = HdmiCecLocalDevice.create(this, type);
+ }
localDevice.init();
localDevices.add(localDevice);
}
+ // It's now safe to flush existing local devices from mCecController since they were
+ // already moved to 'localDevices'.
+ clearLocalDevices();
allocateLogicalAddress(localDevices, initiatedBy);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 9db3fba..2150e9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -45,6 +45,7 @@
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
@@ -714,7 +715,7 @@
}
@Override
- public List<SessionInfo> getAllSessions(int userId) {
+ public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions");
final List<SessionInfo> result = new ArrayList<>();
@@ -726,11 +727,11 @@
}
}
}
- return result;
+ return new ParceledListSlice<>(result);
}
@Override
- public List<SessionInfo> getMySessions(String installerPackageName, int userId) {
+ public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) {
mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions");
mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
@@ -744,7 +745,7 @@
}
}
}
- return result;
+ return new ParceledListSlice<>(result);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a8a946a..b79e157 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -80,6 +80,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.admin.IDevicePolicyManager;
import android.app.backup.IBackupManager;
@@ -4471,62 +4472,164 @@
}
if (pkgs != null) {
- // Filter out packages that aren't recently used.
- //
- // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
- // should do a full dexopt.
- if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
- // TODO: add a property to control this?
- long dexOptLRUThresholdInMinutes;
- if (mLazyDexOpt) {
- dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
- } else {
- dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
- }
- long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
-
- int total = pkgs.size();
- int skipped = 0;
- long now = System.currentTimeMillis();
- for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
- PackageParser.Package pkg = i.next();
- long then = pkg.mLastPackageUsageTimeInMills;
- if (then + dexOptLRUThresholdInMills < now) {
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
- ((then == 0) ? "never" : new Date(then)));
- }
- i.remove();
- skipped++;
+ // Sort apps by importance for dexopt ordering. Important apps are given more priority
+ // in case the device runs out of space.
+ ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
+ // Give priority to core apps.
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (pkg.coreApp) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
}
+ sortedPkgs.add(pkg);
+ it.remove();
}
+ }
+ // Give priority to system apps that listen for pre boot complete.
+ Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
+ HashSet<String> pkgNames = getPackageNamesForIntent(intent);
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (pkgNames.contains(pkg.packageName)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
+ // Give priority to system apps.
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
+ // Give priority to updated system apps.
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (isUpdatedSystemApp(pkg)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
+ // Give priority to apps that listen for boot complete.
+ intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
+ pkgNames = getPackageNamesForIntent(intent);
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (pkgNames.contains(pkg.packageName)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
+ // Filter out packages that aren't recently used.
+ filterRecentlyUsedApps(pkgs);
+ // Add all remaining apps.
+ for (PackageParser.Package pkg : pkgs) {
if (DEBUG_DEXOPT) {
- Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
+ Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
}
+ sortedPkgs.add(pkg);
}
int i = 0;
- for (PackageParser.Package pkg : pkgs) {
- i++;
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size()
- + ": " + pkg.packageName);
+ int total = sortedPkgs.size();
+ File dataDir = Environment.getDataDirectory();
+ long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
+ if (lowThreshold == 0) {
+ throw new IllegalStateException("Invalid low memory threshold");
+ }
+ for (PackageParser.Package pkg : sortedPkgs) {
+ long usableSpace = dataDir.getUsableSpace();
+ if (usableSpace < lowThreshold) {
+ Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
+ break;
}
- if (!isFirstBoot()) {
- try {
- ActivityManagerNative.getDefault().showBootMessage(
- mContext.getResources().getString(
- R.string.android_upgrading_apk,
- i, pkgs.size()), true);
- } catch (RemoteException e) {
+ performBootDexOpt(pkg, ++i, total);
+ }
+ }
+ }
+
+ private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) {
+ // Filter out packages that aren't recently used.
+ //
+ // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
+ // should do a full dexopt.
+ if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
+ // TODO: add a property to control this?
+ long dexOptLRUThresholdInMinutes;
+ if (mLazyDexOpt) {
+ dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
+ } else {
+ dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
+ }
+ long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
+
+ int total = pkgs.size();
+ int skipped = 0;
+ long now = System.currentTimeMillis();
+ for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
+ PackageParser.Package pkg = i.next();
+ long then = pkg.mLastPackageUsageTimeInMills;
+ if (then + dexOptLRUThresholdInMills < now) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
+ ((then == 0) ? "never" : new Date(then)));
}
- }
- PackageParser.Package p = pkg;
- synchronized (mInstallLock) {
- performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */,
- true /* include dependencies */);
+ i.remove();
+ skipped++;
}
}
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
+ }
+ }
+ }
+
+ private HashSet<String> getPackageNamesForIntent(Intent intent) {
+ List<ResolveInfo> ris = null;
+ try {
+ ris = AppGlobals.getPackageManager().queryIntentReceivers(
+ intent, null, 0, UserHandle.USER_OWNER);
+ } catch (RemoteException e) {
+ }
+ HashSet<String> pkgNames = new HashSet<String>();
+ if (ris != null) {
+ for (ResolveInfo ri : ris) {
+ pkgNames.add(ri.activityInfo.packageName);
+ }
+ }
+ return pkgNames;
+ }
+
+ private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
+ }
+ if (!isFirstBoot()) {
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ mContext.getResources().getString(R.string.android_upgrading_apk,
+ curr, total), true);
+ } catch (RemoteException e) {
+ }
+ }
+ PackageParser.Package p = pkg;
+ synchronized (mInstallLock) {
+ performDexOptLI(p, null /* instruction sets */, false /* force dex */,
+ false /* defer */, true /* include dependencies */);
}
}
@@ -5077,6 +5180,9 @@
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ } else {
+ // Only allow system apps to be flagged as core apps.
+ pkg.coreApp = false;
}
if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7dc2de2..af4ae44 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5316,6 +5316,9 @@
@Override
public List<String> getCrossProfileWidgetProviders(int profileId) {
synchronized (DevicePolicyManagerService.this) {
+ if (mDeviceOwner == null) {
+ return Collections.emptyList();
+ }
ComponentName ownerComponent = mDeviceOwner.getProfileOwnerComponent(profileId);
if (ownerComponent == null) {
return Collections.emptyList();