summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt3
-rw-r--r--api/system-current.txt3
-rw-r--r--core/java/android/app/ActivityThread.java5
-rw-r--r--core/java/android/app/AlertDialog.java3
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java9
-rw-r--r--core/java/android/provider/Settings.java32
-rw-r--r--core/java/android/util/DisplayMetrics.java8
-rw-r--r--core/jni/Android.mk4
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java6
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java5
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java2
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java10
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java51
-rw-r--r--services/core/java/com/android/server/job/controllers/IdleController.java19
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--telephony/java/android/telephony/ServiceState.java37
-rw-r--r--tests/ActivityTests/AndroidManifest.xml1
-rw-r--r--tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java5
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java16
24 files changed, 255 insertions, 71 deletions
diff --git a/api/current.txt b/api/current.txt
index e295a63..cb63aaa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -106,6 +106,7 @@ package android {
field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
+ field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
@@ -26444,6 +26445,7 @@ package android.provider {
field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
+ field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -33956,6 +33958,7 @@ package android.util {
field public static final int DENSITY_280 = 280; // 0x118
field public static final int DENSITY_360 = 360; // 0x168
field public static final int DENSITY_400 = 400; // 0x190
+ field public static final int DENSITY_420 = 420; // 0x1a4
field public static final int DENSITY_560 = 560; // 0x230
field public static final int DENSITY_DEFAULT = 160; // 0xa0
field public static final int DENSITY_HIGH = 240; // 0xf0
diff --git a/api/system-current.txt b/api/system-current.txt
index 8b9af5e..a9bc944 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -180,6 +180,7 @@ package android {
field public static final java.lang.String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
field public static final java.lang.String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES";
field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
+ field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
@@ -28502,6 +28503,7 @@ package android.provider {
field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
+ field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -36248,6 +36250,7 @@ package android.util {
field public static final int DENSITY_280 = 280; // 0x118
field public static final int DENSITY_360 = 360; // 0x168
field public static final int DENSITY_400 = 400; // 0x190
+ field public static final int DENSITY_420 = 420; // 0x1a4
field public static final int DENSITY_560 = 560; // 0x230
field public static final int DENSITY_DEFAULT = 160; // 0xa0
field public static final int DENSITY_HIGH = 240; // 0xf0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fd88a05..da21eaf 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4235,11 +4235,6 @@ public final class ActivityThread {
configDiff = mConfiguration.updateFrom(config);
config = applyCompatConfiguration(mCurDefaultDisplayDpi);
-
- final Theme systemTheme = getSystemContext().getTheme();
- if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
- systemTheme.rebase();
- }
}
ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index abe12dc..7824072 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -1082,7 +1082,8 @@ public class AlertDialog extends Dialog implements DialogInterface {
* create and display the dialog.
*/
public AlertDialog create() {
- final AlertDialog dialog = new AlertDialog(P.mContext);
+ // Context has already been wrapped with the appropriate theme.
+ final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index c505b0b..e3414d9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3204,8 +3204,13 @@ public class DevicePolicyManager {
* Called by a profile or device owner to set the application restrictions for a given target
* application running in the profile.
*
- * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be
- * boolean, int, String, or String[].
+ * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be:
+ * <ul>
+ * <li>{@code boolean}
+ * <li>{@code int}
+ * <li>{@code String} or {@code String[]}
+ * <li>From {@link android.os.Build.VERSION_CODES#M}, {@code Bundle} or {@code Bundle[]}
+ * </ul>
*
* <p>The application restrictions are only made visible to the target application and the
* profile or device owner.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6e178a4..fe95864 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -616,20 +616,46 @@ public final class Settings {
/**
* Activity Action: Show screen for controlling which apps can ignore battery optimizations.
* <p>
- * Input: Optionally, the Intent's data URI specifies the application package name
- * to be shown, with the "package" scheme. That is "package:com.my.app".
+ * Input: Nothing.
* <p>
* Output: Nothing.
* <p>
* You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations
* PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is
- * already ignoring optimizations.
+ * already ignoring optimizations. You can use
+ * {@link #ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} to ask the user to put you
+ * on this list.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS =
"android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS";
/**
+ * Activity Action: Ask the user to allow an to ignore battery optimizations (that is,
+ * put them on the whitelist of apps shown by
+ * {@link #ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}). For an app to use this, it also
+ * must hold the {@link android.Manifest.permission#REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}
+ * permission.
+ * <p><b>Note:</b> most applications should <em>not</em> use this; there are many facilities
+ * provided by the platform for applications to operate correctly in the various power
+ * saving mode. This is only for unusual applications that need to deeply control their own
+ * execution, at the potential expense of the user's battery life. Note that these applications
+ * greatly run the risk of showing to the user has how power consumers on their device.</p>
+ * <p>
+ * Input: The Intent's data URI must specify the application package name
+ * to be shown, with the "package" scheme. That is "package:com.my.app".
+ * <p>
+ * Output: Nothing.
+ * <p>
+ * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations
+ * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is
+ * already ignoring optimizations.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS =
+ "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+
+ /**
* @hide
* Activity Action: Show the "app ops" settings screen.
* <p>
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index a36e66c..9a69600 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -90,6 +90,14 @@ public class DisplayMetrics {
public static final int DENSITY_400 = 400;
/**
+ * Intermediate density for screens that sit somewhere between
+ * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+ * This is not a density that applications should target, instead relying
+ * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+ */
+ public static final int DENSITY_420 = 420;
+
+ /**
* Standard quantized DPI for extra-extra-high-density screens.
*/
public static final int DENSITY_XXHIGH = 480;
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 5e5450e..6b07a47 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -269,6 +269,10 @@ LOCAL_CFLAGS += -Wall -Werror -Wno-error=deprecated-declarations -Wunused -Wunre
# is not being compiled with that level. Remove once this has changed.
LOCAL_CFLAGS += -Wno-c++11-extensions
+# b/22414716: thread_local (android/graphics/Paint.cpp) and Clang don't like each other at the
+# moment.
+LOCAL_CLANG := false
+
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 53b553e8..629d14b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2257,6 +2257,13 @@
<permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"
android:protectionLevel="system|signature" />
+ <!-- Permission an application must hold in order to use
+ {@link android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}.
+ This is a normal permission: an app requesting it will always be granted the
+ permission, without the user needing to approve or see it. -->
+ <permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
+ android:protectionLevel="normal" />
+
<!-- @SystemApi Allows an application to collect battery statistics -->
<permission android:name="android.permission.BATTERY_STATS"
android:protectionLevel="signature|privileged|development" />
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index bf069d3..32f6a89 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -786,12 +786,16 @@ public class RippleDrawable extends LayerDrawable {
mMaskColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_IN);
}
- // Draw the appropriate mask.
+ // Draw the appropriate mask anchored to (0,0).
+ final int left = bounds.left;
+ final int top = bounds.top;
+ mMaskCanvas.translate(-left, -top);
if (maskType == MASK_EXPLICIT) {
drawMask(mMaskCanvas);
} else if (maskType == MASK_CONTENT) {
drawContent(mMaskCanvas);
}
+ mMaskCanvas.translate(left, top);
}
private int getMaskType() {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index e74334b..b9a9c24 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -148,7 +148,10 @@ public class SettingsBackupAgent extends BackupAgentHelper {
private WifiManager mWfm;
private static String mWifiConfigFile;
+ // Chain of asynchronous operations used when rewriting the wifi supplicant config file
+ WifiDisableRunnable mWifiDisable = null;
WifiRestoreRunnable mWifiRestore = null;
+ int mRetainedWifiState; // used only during config file rewrite
// Class for capturing a network definition from the wifi supplicant config file
static class Network {
@@ -407,9 +410,47 @@ public class SettingsBackupAgent extends BackupAgentHelper {
writeNewChecksums(stateChecksums, newState);
}
+ class WifiDisableRunnable implements Runnable {
+ final WifiRestoreRunnable mNextPhase;
+
+ public WifiDisableRunnable(WifiRestoreRunnable next) {
+ mNextPhase = next;
+ }
+
+ @Override
+ public void run() {
+ if (DEBUG_BACKUP) {
+ Log.v(TAG, "Disabling wifi during restore");
+ }
+ final ContentResolver cr = getContentResolver();
+ final int scanAlways = Settings.Global.getInt(cr,
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+ final int retainedWifiState = enableWifi(false);
+ if (scanAlways != 0) {
+ Settings.Global.putInt(cr,
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+ }
+
+ // Tell the final stage how to clean up after itself
+ mNextPhase.setPriorState(retainedWifiState, scanAlways);
+
+ // And run it after a modest pause to give broadcasts and content
+ // observers time an opportunity to run on this looper thread, so
+ // that the wifi stack actually goes all the way down.
+ new Handler(getMainLooper()).postDelayed(mNextPhase, 2500);
+ }
+ }
+
class WifiRestoreRunnable implements Runnable {
private byte[] restoredSupplicantData;
private byte[] restoredWifiConfigFile;
+ private int retainedWifiState; // provided by disable stage
+ private int scanAlways; // provided by disable stage
+
+ void setPriorState(int retainedState, int always) {
+ retainedWifiState = retainedState;
+ scanAlways = always;
+ }
void incorporateWifiSupplicant(BackupDataInput data) {
restoredSupplicantData = new byte[data.getDataSize()];
@@ -437,20 +478,8 @@ public class SettingsBackupAgent extends BackupAgentHelper {
public void run() {
if (restoredSupplicantData != null || restoredWifiConfigFile != null) {
if (DEBUG_BACKUP) {
- Log.v(TAG, "Starting deferred restore of wifi data");
- }
- final ContentResolver cr = getContentResolver();
- final int scanAlways = Settings.Global.getInt(cr,
- Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
- final int retainedWifiState = enableWifi(false);
- if (scanAlways != 0) {
- Settings.Global.putInt(cr,
- Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+ Log.v(TAG, "Applying restored wifi data");
}
- // !!! Give the wifi stack a moment to quiesce. We've observed the
- // response to disabling WIFI_SCAN_ALWAYS_AVAILABLE taking more
- // than 1500ms, so we wait a generous 2500 here before proceeding.
- try { Thread.sleep(2500); } catch (InterruptedException e) {}
if (restoredSupplicantData != null) {
restoreWifiSupplicant(FILE_WIFI_SUPPLICANT,
restoredSupplicantData, restoredSupplicantData.length);
@@ -465,7 +494,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
}
// restore the previous WIFI state.
if (scanAlways != 0) {
- Settings.Global.putInt(cr,
+ Settings.Global.putInt(getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, scanAlways);
}
enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
@@ -479,6 +508,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
void initWifiRestoreIfNecessary() {
if (mWifiRestore == null) {
mWifiRestore = new WifiRestoreRunnable();
+ mWifiDisable = new WifiDisableRunnable(mWifiRestore);
}
}
@@ -518,13 +548,16 @@ public class SettingsBackupAgent extends BackupAgentHelper {
}
// If we have wifi data to restore, post a runnable to perform the
- // bounce-and-update operation a little ways in the future.
+ // bounce-and-update operation a little ways in the future. The
+ // 'disable' runnable brings down the stack and remembers its state,
+ // and in turn schedules the 'restore' runnable to do the rewrite
+ // and cleanup operations.
if (mWifiRestore != null) {
long wifiBounceDelayMillis = Settings.Global.getLong(
getContentResolver(),
Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
WIFI_BOUNCE_DELAY_MILLIS);
- new Handler(getMainLooper()).postDelayed(mWifiRestore, wifiBounceDelayMillis);
+ new Handler(getMainLooper()).postDelayed(mWifiDisable, wifiBounceDelayMillis);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index abdebf3..0068f84 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -1121,9 +1121,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mViewPool.returnViewToPool(tv);
}
- // Notify the callback that we've removed the task and it can clean up after it
- mCb.onTaskViewDismissed(removedTask);
-
// Get the stack scroll of the task to anchor to (since we are removing something, the front
// most task will be our anchor task)
Task anchorTask = null;
@@ -1172,6 +1169,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Fade the dismiss button back in
showDismissAllButton();
}
+
+ // Notify the callback that we've removed the task and it can clean up after it. Note, we
+ // do this after onAllTaskViewsDismissed() is called, to allow the home activity to be
+ // started before the call to remove the task.
+ mCb.onTaskViewDismissed(removedTask);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 00fa653..7065343 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -41,6 +41,7 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
@@ -1713,10 +1714,16 @@ public abstract class BaseStatusBar extends SystemUI implements
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ final Icon smallIcon = n.getSmallIcon();
+ if (smallIcon == null) {
+ handleNotificationError(sbn,
+ "No small icon in notification from " + sbn.getPackageName());
+ return null;
+ }
final StatusBarIcon ic = new StatusBarIcon(
sbn.getUser(),
sbn.getPackageName(),
- n.getSmallIcon(),
+ smallIcon,
n.iconLevel,
n.number,
n.tickerText);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 6627360..42a2f90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
@@ -601,6 +602,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
post(new Runnable() {
@Override
@@ -671,7 +673,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void onFingerprintError(int msgId, String errString) {
- if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) {
+ if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()
+ || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
return;
}
// TODO: Go to bouncer if this is "too many attempts" (lockout) error.
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 30680ed..fa87270 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -2905,9 +2905,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
// Now that we've told the host, push out an update.
sendUpdateIntentLocked(provider, appWidgetIds);
- providersUpdated = true;
}
}
+ providersUpdated = true;
}
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 83e8db0..aab6374 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2604,7 +2604,8 @@ public class AccountManagerService
// Prune the list down to just the requested type.
visibleAccountTypes = new ArrayList<>();
visibleAccountTypes.add(type);
- } // else aggregate all the visible accounts (it won't matter if the list is empty).
+ } // else aggregate all the visible accounts (it won't matter if the
+ // list is empty).
long identityToken = clearCallingIdentity();
try {
@@ -3788,8 +3789,15 @@ public class AccountManagerService
private List<String> getTypesForCaller(
int callingUid, int userId, boolean isOtherwisePermitted) {
List<String> managedAccountTypes = new ArrayList<>();
+ long identityToken = Binder.clearCallingIdentity();
+ Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> serviceInfos;
+ try {
+ serviceInfos = mAuthenticatorCache.getAllServices(userId);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
- mAuthenticatorCache.getAllServices(userId)) {
+ serviceInfos) {
final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
if (isOtherwisePermitted || sigChk == PackageManager.SIGNATURE_MATCH) {
managedAccountTypes.add(serviceInfo.type.type);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index a75cc48..6e34876 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3740,7 +3740,12 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
boolean prevIsHome = false;
- if (tr.isOverHomeStack()) {
+
+ // If true, we should resume the home activity next if the task we are moving to the
+ // back is over the home stack. We force to false if the task we are moving to back
+ // is the home task and we don't want it resumed after moving to the back.
+ final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
+ if (canGoHome) {
final TaskRecord nextTask = getNextTask(tr);
if (nextTask != null) {
nextTask.setTaskToReturnTo(tr.getTaskToReturnTo());
@@ -3774,8 +3779,7 @@ final class ActivityStack {
}
final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
- if (prevIsHome || task == tr && tr.isOverHomeStack()
- || numTasks <= 1 && isOnHomeDisplay()) {
+ if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c705fbf..2c9d82b 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -454,6 +454,18 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
"Must have " + permission + " permission.");
}
+ int getEffectiveUserId(int userId) {
+ UserManager um = UserManager.get(mContext);
+ if (um != null) {
+ final long callingIdentity = Binder.clearCallingIdentity();
+ userId = um.getCredentialOwnerProfile(userId);
+ Binder.restoreCallingIdentity(callingIdentity);
+ } else {
+ Slog.e(TAG, "Unable to acquire UserManager");
+ }
+ return userId;
+ }
+
boolean isCurrentUserOrProfile(int userId) {
UserManager um = UserManager.get(mContext);
@@ -686,11 +698,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
}
final byte [] cryptoClone = Arrays.copyOf(cryptoToken, cryptoToken.length);
+ // Group ID is arbitrarily set to parent profile user ID. It just represents
+ // the default fingerprints for the user.
+ final int effectiveGroupId = getEffectiveUserId(groupId);
+
final boolean restricted = isRestricted();
mHandler.post(new Runnable() {
@Override
public void run() {
- startEnrollment(token, cryptoClone, groupId, receiver, flags, restricted);
+ startEnrollment(token, cryptoClone, effectiveGroupId, receiver, flags, restricted);
}
});
}
@@ -724,11 +740,16 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
Slog.w(TAG, "Calling not granted permission to use fingerprint");
return;
}
+
+ // Group ID is arbitrarily set to parent profile user ID. It just represents
+ // the default fingerprints for the user.
+ final int effectiveGroupId = getEffectiveUserId(groupId);
+
final boolean restricted = isRestricted();
mHandler.post(new Runnable() {
@Override
public void run() {
- startAuthentication(token, opId, groupId, receiver, flags, restricted);
+ startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted);
}
});
}
@@ -751,10 +772,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
final boolean restricted = isRestricted();
+
+ // Group ID is arbitrarily set to parent profile user ID. It just represents
+ // the default fingerprints for the user.
+ final int effectiveGroupId = getEffectiveUserId(groupId);
mHandler.post(new Runnable() {
@Override
public void run() {
- startRemove(token, fingerId, groupId, receiver, restricted);
+ startRemove(token, fingerId, effectiveGroupId, receiver, restricted);
}
});
@@ -771,10 +796,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
@Override // Binder call
public void rename(final int fingerId, final int groupId, final String name) {
checkPermission(MANAGE_FINGERPRINT);
+
+ // Group ID is arbitrarily set to parent profile user ID. It just represents
+ // the default fingerprints for the user.
+ final int effectiveGroupId = getEffectiveUserId(groupId);
mHandler.post(new Runnable() {
@Override
public void run() {
- mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, groupId, name);
+ mFingerprintUtils.renameFingerprintForUser(mContext, fingerId,
+ effectiveGroupId, name);
}
});
}
@@ -784,15 +814,19 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
if (!canUseFingerprint(opPackageName)) {
return Collections.emptyList();
}
- return FingerprintService.this.getEnrolledFingerprints(userId);
+ int effectiveUserId = getEffectiveUserId(userId);
+
+ return FingerprintService.this.getEnrolledFingerprints(effectiveUserId);
}
@Override // Binder call
- public boolean hasEnrolledFingerprints(int groupId, String opPackageName) {
+ public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
if (!canUseFingerprint(opPackageName)) {
return false;
}
- return FingerprintService.this.hasEnrolledFingerprints(groupId);
+
+ int effectiveUserId = getEffectiveUserId(userId);
+ return FingerprintService.this.hasEnrolledFingerprints(effectiveUserId);
}
@Override // Binder call
@@ -829,8 +863,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
IFingerprintDaemon daemon = getFingerprintDaemon();
if (daemon != null) {
try {
- // TODO: if this is a managed profile, use the profile parent's directory for
- // storage.
+ userId = getEffectiveUserId(userId);
final File systemDir = Environment.getUserSystemDirectory(userId);
final File fpDir = new File(systemDir, FP_DATA_DIR);
if (!fpDir.exists()) {
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 8e2ca18..92df851 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -108,6 +108,7 @@ public class IdleController extends StateController {
private AlarmManager mAlarm;
private PendingIntent mIdleTriggerIntent;
boolean mIdle;
+ boolean mScreenOn;
public IdlenessTracker() {
mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
@@ -120,6 +121,7 @@ public class IdleController extends StateController {
// At boot we presume that the user has just "interacted" with the
// device in some meaningful way.
mIdle = false;
+ mScreenOn = true;
}
public boolean isIdle() {
@@ -149,12 +151,14 @@ public class IdleController extends StateController {
if (action.equals(Intent.ACTION_SCREEN_ON)
|| action.equals(Intent.ACTION_DREAMING_STOPPED)) {
- // possible transition to not-idle
+ if (DEBUG) {
+ Slog.v(TAG,"exiting idle : " + action);
+ }
+ mScreenOn = true;
+ //cancel the alarm
+ mAlarm.cancel(mIdleTriggerIntent);
if (mIdle) {
- if (DEBUG) {
- Slog.v(TAG, "exiting idle : " + action);
- }
- mAlarm.cancel(mIdleTriggerIntent);
+ // possible transition to not-idle
mIdle = false;
reportNewIdleState(mIdle);
}
@@ -169,11 +173,12 @@ public class IdleController extends StateController {
Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+ when);
}
+ mScreenOn = false;
mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
} else if (action.equals(ACTION_TRIGGER_IDLE)) {
- // idle time starts now
- if (!mIdle) {
+ // idle time starts now. Do not set mIdle if screen is on.
+ if (!mIdle && !mScreenOn) {
if (DEBUG) {
Slog.v(TAG, "Idle trigger fired @ " + SystemClock.elapsedRealtime());
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 014527b..eb02199 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1024,12 +1024,6 @@ public final class SystemServer {
w.getDefaultDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);
- // The system context's theme may be configuration-dependent.
- final Theme systemTheme = context.getTheme();
- if (systemTheme.getChangingConfigurations() != 0) {
- systemTheme.rebase();
- }
-
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 303a492..80515cf 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -220,6 +220,8 @@ public class ServiceState implements Parcelable {
private int mCdmaEriIconIndex;
private int mCdmaEriIconMode;
+ private boolean mIsDataRoamingFromRegistration;
+
/**
* get String description of roaming type
* @hide
@@ -297,6 +299,7 @@ public class ServiceState implements Parcelable {
mCdmaEriIconIndex = s.mCdmaEriIconIndex;
mCdmaEriIconMode = s.mCdmaEriIconMode;
mIsEmergencyOnly = s.mIsEmergencyOnly;
+ mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
}
/**
@@ -324,6 +327,7 @@ public class ServiceState implements Parcelable {
mCdmaEriIconIndex = in.readInt();
mCdmaEriIconMode = in.readInt();
mIsEmergencyOnly = in.readInt() != 0;
+ mIsDataRoamingFromRegistration = in.readInt() != 0;
}
public void writeToParcel(Parcel out, int flags) {
@@ -348,6 +352,7 @@ public class ServiceState implements Parcelable {
out.writeInt(mCdmaEriIconIndex);
out.writeInt(mCdmaEriIconMode);
out.writeInt(mIsEmergencyOnly ? 1 : 0);
+ out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
}
public int describeContents() {
@@ -439,6 +444,26 @@ public class ServiceState implements Parcelable {
}
/**
+ * Set whether data network registration state is roaming
+ *
+ * This should only be set to the roaming value received
+ * once the data registration phase has completed.
+ * @hide
+ */
+ public void setDataRoamingFromRegistration(boolean dataRoaming) {
+ mIsDataRoamingFromRegistration = dataRoaming;
+ }
+
+ /**
+ * Get whether data network registration state is roaming
+ * @return true if registration indicates roaming, false otherwise
+ * @hide
+ */
+ public boolean getDataRoamingFromRegistration() {
+ return mIsDataRoamingFromRegistration;
+ }
+
+ /**
* Get current data network roaming type
* @return roaming type
* @hide
@@ -599,7 +624,8 @@ public class ServiceState implements Parcelable {
+ ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
+ mCdmaRoamingIndicator
+ mCdmaDefaultRoamingIndicator
- + (mIsEmergencyOnly ? 1 : 0));
+ + (mIsEmergencyOnly ? 1 : 0)
+ + (mIsDataRoamingFromRegistration ? 1 : 0));
}
@Override
@@ -635,7 +661,8 @@ public class ServiceState implements Parcelable {
&& equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
&& equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
s.mCdmaDefaultRoamingIndicator)
- && mIsEmergencyOnly == s.mIsEmergencyOnly);
+ && mIsEmergencyOnly == s.mIsEmergencyOnly
+ && mIsDataRoamingFromRegistration == s.mIsDataRoamingFromRegistration);
}
/**
@@ -736,7 +763,8 @@ public class ServiceState implements Parcelable {
+ " " + mSystemId
+ " RoamInd=" + mCdmaRoamingIndicator
+ " DefRoamInd=" + mCdmaDefaultRoamingIndicator
- + " EmergOnly=" + mIsEmergencyOnly);
+ + " EmergOnly=" + mIsEmergencyOnly
+ + " IsDataRoamingFromRegistration=" + mIsDataRoamingFromRegistration);
}
private void setNullState(int state) {
@@ -762,6 +790,7 @@ public class ServiceState implements Parcelable {
mCdmaEriIconIndex = -1;
mCdmaEriIconMode = -1;
mIsEmergencyOnly = false;
+ mIsDataRoamingFromRegistration = false;
}
public void setStateOutOfService() {
@@ -934,6 +963,7 @@ public class ServiceState implements Parcelable {
mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
mIsEmergencyOnly = m.getBoolean("emergencyOnly");
+ mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
}
/**
@@ -962,6 +992,7 @@ public class ServiceState implements Parcelable {
m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
+ m.putBoolean("isDataRoamingFromRegistration", Boolean.valueOf(mIsDataRoamingFromRegistration));
}
/** @hide */
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml
index 73cb432..7b9c9f1 100644
--- a/tests/ActivityTests/AndroidManifest.xml
+++ b/tests/ActivityTests/AndroidManifest.xml
@@ -24,6 +24,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-sdk android:targetSdkVersion="22" />
<application android:label="ActivityTest">
<activity android:name="ActivityTestMain">
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 2f0bf39..5fbfe8a 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -465,9 +465,12 @@ public class ActivityTestMain extends Activity {
menu.add("Ignore battery optimizations").setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override public boolean onMenuItemClick(MenuItem item) {
- Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
+ Intent intent;
if (!mPower.isIgnoringBatteryOptimizations(getPackageName())) {
+ intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", getPackageName(), null));
+ } else {
+ intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
startActivity(intent);
return true;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 47258b6..baf2e2e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -97,13 +97,13 @@ public final class DelegateManager<T> {
* @return the delegate or null if not found.
*/
@Nullable
- public T getDelegate(long native_object) {
+ public synchronized T getDelegate(long native_object) {
if (native_object > 0) {
- T delegate = mDelegates.get(native_object);
+ T delegate = mDelegates.get(native_object);
if (Debug.DEBUG) {
if (delegate == null) {
- System.out.println("Unknown " + mClass.getSimpleName() + " with int " +
+ System.err.println("Unknown " + mClass.getSimpleName() + " with int " +
native_object);
}
}
@@ -119,14 +119,18 @@ public final class DelegateManager<T> {
* @param newDelegate the delegate to add
* @return a unique native int to identify the delegate
*/
- public long addNewDelegate(T newDelegate) {
+ public synchronized long addNewDelegate(T newDelegate) {
long native_object = ++mDelegateCounter;
+
mDelegates.put(native_object, newDelegate);
assert !mJavaReferences.contains(newDelegate);
mJavaReferences.add(newDelegate);
if (Debug.DEBUG) {
- System.out.println("New " + mClass.getSimpleName() + " with int " + native_object);
+ System.out.println(
+ "New " + mClass.getSimpleName() + " " +
+ "with int " +
+ native_object);
}
return native_object;
@@ -136,7 +140,7 @@ public final class DelegateManager<T> {
* Removes the main reference on the given delegate.
* @param native_object the native integer representing the delegate.
*/
- public void removeJavaReferenceFor(long native_object) {
+ public synchronized void removeJavaReferenceFor(long native_object) {
T delegate = getDelegate(native_object);
if (Debug.DEBUG) {