summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt9
-rw-r--r--api/system-current.txt9
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java14
-rw-r--r--core/java/android/app/backup/BackupTransport.java2
-rw-r--r--core/java/android/app/backup/RecentsBackupHelper.java16
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl6
-rw-r--r--core/java/android/content/res/Resources.java96
-rw-r--r--core/java/android/provider/AlarmClock.java144
-rw-r--r--core/java/android/widget/ProgressBar.java6
-rw-r--r--core/java/android/widget/RadialTimePickerView.java187
-rw-r--r--core/java/com/android/server/backup/PreferredActivityBackupHelper.java175
-rw-r--r--core/java/com/android/server/backup/SystemBackupAgent.java26
-rw-r--r--core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.pngbin136 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.pngbin136 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.pngbin136 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.pngbin138 -> 0 bytes
-rw-r--r--core/res/res/drawable/list_divider_material.xml11
-rw-r--r--data/fonts/fallback_fonts.xml17
-rw-r--r--data/fonts/fonts.xml11
-rw-r--r--[-rwxr-xr-x]packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java14
-rw-r--r--rs/java/android/renderscript/FieldPacker.java225
-rw-r--r--rs/java/android/renderscript/ScriptGroup2.java2
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicBlur.java2
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java1
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java6
-rw-r--r--services/core/java/com/android/server/job/controllers/AppIdleController.java2
-rw-r--r--services/core/java/com/android/server/job/controllers/TimeController.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java85
-rw-r--r--services/core/java/com/android/server/pm/Settings.java16
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java75
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsDatabase.java46
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java2
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java34
34 files changed, 863 insertions, 384 deletions
diff --git a/api/current.txt b/api/current.txt
index cb63af7..7e24003 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5712,6 +5712,7 @@ package android.app.admin {
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -24148,8 +24149,16 @@ package android.provider {
field public static final java.lang.String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
field public static final java.lang.String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
field public static final java.lang.String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
+ field public static final java.lang.String ACTION_VOICE_CANCEL_ALARM = "android.intent.action.VOICE_CANCEL_ALARM";
+ field public static final java.lang.String ACTION_VOICE_DELETE_ALARM = "android.intent.action.VOICE_DELETE_ALARM";
+ field public static final java.lang.String ALARM_SEARCH_MODE_ALL = "all";
+ field public static final java.lang.String ALARM_SEARCH_MODE_NEXT = "next";
+ field public static final java.lang.String ALARM_SEARCH_MODE_NONE = "none";
+ field public static final java.lang.String ALARM_SEARCH_MODE_TIME = "time";
+ field public static final java.lang.String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.ALARM_SEARCH_MODE";
field public static final java.lang.String EXTRA_DAYS = "android.intent.extra.alarm.DAYS";
field public static final java.lang.String EXTRA_HOUR = "android.intent.extra.alarm.HOUR";
+ field public static final java.lang.String EXTRA_IS_PM = "android.intent.extra.alarm.IS_PM";
field public static final java.lang.String EXTRA_LENGTH = "android.intent.extra.alarm.LENGTH";
field public static final java.lang.String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
field public static final java.lang.String EXTRA_MINUTES = "android.intent.extra.alarm.MINUTES";
diff --git a/api/system-current.txt b/api/system-current.txt
index 7ef0008..3f2e19b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5818,6 +5818,7 @@ package android.app.admin {
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -26031,8 +26032,16 @@ package android.provider {
field public static final java.lang.String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
field public static final java.lang.String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
field public static final java.lang.String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
+ field public static final java.lang.String ACTION_VOICE_CANCEL_ALARM = "android.intent.action.VOICE_CANCEL_ALARM";
+ field public static final java.lang.String ACTION_VOICE_DELETE_ALARM = "android.intent.action.VOICE_DELETE_ALARM";
+ field public static final java.lang.String ALARM_SEARCH_MODE_ALL = "all";
+ field public static final java.lang.String ALARM_SEARCH_MODE_NEXT = "next";
+ field public static final java.lang.String ALARM_SEARCH_MODE_NONE = "none";
+ field public static final java.lang.String ALARM_SEARCH_MODE_TIME = "time";
+ field public static final java.lang.String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.ALARM_SEARCH_MODE";
field public static final java.lang.String EXTRA_DAYS = "android.intent.extra.alarm.DAYS";
field public static final java.lang.String EXTRA_HOUR = "android.intent.extra.alarm.HOUR";
+ field public static final java.lang.String EXTRA_IS_PM = "android.intent.extra.alarm.IS_PM";
field public static final java.lang.String EXTRA_LENGTH = "android.intent.extra.alarm.LENGTH";
field public static final java.lang.String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
field public static final java.lang.String EXTRA_MINUTES = "android.intent.extra.alarm.MINUTES";
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e917522..68f4707 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -502,6 +502,20 @@ public class DevicePolicyManager {
*/
public static final String EXTRA_PROVISIONING_BT_USE_PROXY
= "android.app.extra.PROVISIONING_BT_USE_PROXY";
+
+ /**
+ * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
+ * holds data needed by the system to wipe factory reset protection. The data needed to wipe
+ * the device depend on the installed factory reset protection implementation. For example,
+ * if an account is needed to unlock a device, this extra may contain data used to
+ * authenticate that account.
+ *
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
+ * provisioning via an NFC bump.
+ */
+ public static final String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
+ = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS";
+
/**
* This MIME type is used for starting the Device Owner provisioning that does not require
* provisioning features introduced in Android API level
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index ca6dc69..1131ff9 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -464,7 +464,7 @@ public class BackupTransport {
* transport level).
*
* <p>After this method returns zero, the system will then call
- * {@link #getNextFullRestorePackage()} to begin the restore process for the next
+ * {@link #nextRestorePackage()} to begin the restore process for the next
* application, and the sequence begins again.
*
* <p>The transport should always close this socket when returning from this method.
diff --git a/core/java/android/app/backup/RecentsBackupHelper.java b/core/java/android/app/backup/RecentsBackupHelper.java
index fd69d20..1a64da6 100644
--- a/core/java/android/app/backup/RecentsBackupHelper.java
+++ b/core/java/android/app/backup/RecentsBackupHelper.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package android.app.backup;
import android.content.Context;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index fb7c96d..649bb47 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -269,6 +269,12 @@ interface IPackageManager {
void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage);
/**
+ * Backup/restore support - only the system uid may use these.
+ */
+ byte[] getPreferredActivityBackup(int userId);
+ void restorePreferredActivities(in byte[] backup, int userId);
+
+ /**
* Report the set of 'Home' activity candidates, plus (if any) which of them
* is the current "always use this one" setting.
*/
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 299eb7e..334d180 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -117,6 +117,9 @@ public class Resources {
private static final LongSparseArray<android.content.res.ConstantState<ColorStateList>>
sPreloadedColorStateLists = new LongSparseArray<>();
+ private static final String CACHE_NOT_THEMED = "";
+ private static final String CACHE_NULL_THEME = "null_theme";
+
// Pool of TypedArrays targeted to this Resources object.
final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
@@ -2441,8 +2444,8 @@ public class Resources {
}
}
- // Next, check preloaded drawables. These are unthemed but may have
- // themeable attributes.
+ // Next, check preloaded drawables. These may contain unresolved theme
+ // attributes.
final ConstantState cs;
if (isColorDrawable) {
cs = sPreloadedColorDrawables.get(key);
@@ -2450,42 +2453,49 @@ public class Resources {
cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key);
}
- final Drawable dr;
+ Drawable dr;
if (cs != null) {
- final Drawable clonedDr = cs.newDrawable(this);
- if (theme != null) {
- dr = clonedDr.mutate();
- dr.applyTheme(theme);
- dr.clearMutated();
- } else {
- dr = clonedDr;
- }
+ dr = cs.newDrawable(this);
} else if (isColorDrawable) {
dr = new ColorDrawable(value.data);
} else {
- dr = loadDrawableForCookie(value, id, theme);
+ dr = loadDrawableForCookie(value, id, null);
+ }
+
+ // Determine if the drawable has unresolved theme attributes. If it
+ // does, we'll need to apply a theme and store it in a theme-specific
+ // cache.
+ final String cacheKey;
+ if (!dr.canApplyTheme()) {
+ cacheKey = CACHE_NOT_THEMED;
+ } else if (theme == null) {
+ cacheKey = CACHE_NULL_THEME;
+ } else {
+ cacheKey = theme.getKey();
+ dr = dr.mutate();
+ dr.applyTheme(theme);
+ dr.clearMutated();
}
// If we were able to obtain a drawable, store it in the appropriate
- // cache (either preload or themed).
+ // cache: preload, not themed, null theme, or theme-specific.
if (dr != null) {
dr.setChangingConfigurations(value.changingConfigurations);
- cacheDrawable(value, theme, isColorDrawable, caches, key, dr);
+ cacheDrawable(value, isColorDrawable, caches, cacheKey, key, dr);
}
return dr;
}
- private void cacheDrawable(TypedValue value, Theme theme, boolean isColorDrawable,
+ private void cacheDrawable(TypedValue value, boolean isColorDrawable,
ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
- long key, Drawable dr) {
+ String cacheKey, long key, Drawable dr) {
final ConstantState cs = dr.getConstantState();
if (cs == null) {
return;
}
if (mPreloading) {
- // Preloaded drawables never have a theme, but may be themeable.
final int changingConfigs = cs.getChangingConfigurations();
if (isColorDrawable) {
if (verifyPreloadConfig(changingConfigs, 0, value.resourceId, "drawable")) {
@@ -2507,14 +2517,13 @@ public class Resources {
}
} else {
synchronized (mAccessLock) {
- final String themeKey = theme == null ? "" : theme.mKey;
- LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
+ LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(cacheKey);
if (themedCache == null) {
// Clean out the caches before we add more. This shouldn't
// happen very often.
pruneCaches(caches);
themedCache = new LongSparseArray<>(1);
- caches.put(themeKey, themedCache);
+ caches.put(cacheKey, themedCache);
}
themedCache.put(key, new WeakReference<>(cs));
}
@@ -2612,46 +2621,47 @@ public class Resources {
ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
long key, Theme theme) {
synchronized (mAccessLock) {
- final String themeKey = theme != null ? theme.mKey : "";
- final LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
- if (themedCache != null) {
- final Drawable themedDrawable = getCachedDrawableLocked(themedCache, key);
- if (themedDrawable != null) {
- return themedDrawable;
- }
+ // First search theme-agnostic cache.
+ final Drawable unthemedDrawable = getCachedDrawableLocked(
+ caches, key, CACHE_NOT_THEMED);
+ if (unthemedDrawable != null) {
+ return unthemedDrawable;
}
- // No cached drawable, we'll need to create a new one.
- return null;
+ // Next search theme-specific cache.
+ final String themeKey = theme != null ? theme.getKey() : CACHE_NULL_THEME;
+ return getCachedDrawableLocked(caches, key, themeKey);
}
}
+ private Drawable getCachedDrawableLocked(
+ ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
+ long key, String themeKey) {
+ final LongSparseArray<WeakReference<ConstantState>> cache = caches.get(themeKey);
+ if (cache != null) {
+ final ConstantState entry = getConstantStateLocked(cache, key);
+ if (entry != null) {
+ return entry.newDrawable(this);
+ }
+ }
+ return null;
+ }
+
private ConstantState getConstantStateLocked(
LongSparseArray<WeakReference<ConstantState>> drawableCache, long key) {
final WeakReference<ConstantState> wr = drawableCache.get(key);
- if (wr != null) { // we have the key
+ if (wr != null) {
final ConstantState entry = wr.get();
if (entry != null) {
- //Log.i(TAG, "Returning cached drawable @ #" +
- // Integer.toHexString(((Integer)key).intValue())
- // + " in " + this + ": " + entry);
return entry;
- } else { // our entry has been purged
+ } else {
+ // Our entry has been purged.
drawableCache.delete(key);
}
}
return null;
}
- private Drawable getCachedDrawableLocked(
- LongSparseArray<WeakReference<ConstantState>> drawableCache, long key) {
- final ConstantState entry = getConstantStateLocked(drawableCache, key);
- if (entry != null) {
- return entry.newDrawable(this);
- }
- return null;
- }
-
@Nullable
ColorStateList loadColorStateList(TypedValue value, int id, Theme theme)
throws NotFoundException {
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index 724d76d..25a35e1 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -43,8 +43,14 @@ public final class AlarmClock {
* should remove this alarm after it has been dismissed. If an identical alarm exists matching
* all parameters, the implementation may re-use it instead of creating a new one (in this case,
* the alarm should not be removed after dismissal).
- *
+ * </p><p>
* This action always enables the alarm.
+ * </p><p>
+ * This activity could also be started in Voice Interaction mode. The activity should check
+ * {@link android.app.Activity#isVoiceInteraction}, and if true, the implementation should
+ * report a deeplink of the created/enabled alarm using
+ * {@link android.app.VoiceInteractor.CompleteVoiceRequest}. This allows follow-on voice actions
+ * such as {@link #ACTION_VOICE_CANCEL_ALARM} to cancel the alarm that was just enabled.
* </p>
* <h3>Request parameters</h3>
* <ul>
@@ -63,6 +69,48 @@ public final class AlarmClock {
public static final String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
/**
+ * Voice Activity Action: Cancel an alarm.
+ * Requires: The activity must check {@link android.app.Activity#isVoiceInteraction}, i.e. be
+ * started in Voice Interaction mode.
+ * <p>
+ * Cancels the specified alarm by voice. To cancel means to disable, but not delete, the alarm.
+ * See {@link #ACTION_VOICE_DELETE_ALARM} to delete an alarm by voice.
+ * </p><p>
+ * The alarm to cancel can be specified or searched for in one of the following ways:
+ * <ol>
+ * <li>The Intent's data URI specifies a deeplink to the alarm.
+ * <li>If the Intent's data URI is unspecified, then the extra {@link #EXTRA_ALARM_SEARCH_MODE} is
+ * required to determine how to search for the alarm.
+ *
+ * @see #ACTION_VOICE_DELETE_ALARM
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_VOICE_CANCEL_ALARM =
+ "android.intent.action.VOICE_CANCEL_ALARM";
+
+ /**
+ * Voice Activity Action: Delete an alarm.
+ * Requires: The activity must check {@link android.app.Activity#isVoiceInteraction}, i.e. be
+ * started in Voice Interaction mode.
+ * <p>
+ * Deletes the specified alarm by voice.
+ * See {@link #ACTION_VOICE_CANCEL_ALARM} to cancel (disable) an alarm by voice.
+ * </p><p>
+ * The alarm to delete can be specified or searched for in one of the following ways:
+ * <ol>
+ * <li>The Intent's data URI specifies a deeplink to the alarm.
+ * <li>If the Intent's data URI is unspecified, then the extra {@link #EXTRA_ALARM_SEARCH_MODE} is
+ * required to determine how to search for the alarm.
+ *
+ * @see #ACTION_VOICE_CANCEL_ALARM
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_VOICE_DELETE_ALARM =
+ "android.intent.action.VOICE_DELETE_ALARM";
+
+ /**
* Activity Action: Set a timer.
* <p>
* Activates an existing timer or creates a new one.
@@ -99,6 +147,100 @@ public final class AlarmClock {
public static final String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
/**
+ * Bundle extra: Specify the type of search mode to look up an alarm.
+ * <p>
+ * Used by {@link #ACTION_VOICE_CANCEL_ALARM} and {@link #ACTION_VOICE_DELETE_ALARM} to identify
+ * the alarm(s) to cancel or delete, respectively.
+ * </p><p>
+ * This extra is only required when the alarm is not already identified by a deeplink as
+ * specified in the Intent's data URI.
+ * </p><p>
+ * The value of this extra is a {@link String}, restricted to the following set of supported
+ * search modes:
+ * <ul>
+ * <li><i>Time</i> - {@link #ALARM_SEARCH_MODE_TIME}: Selects the alarm that is most
+ * closely matched by the search parameters {@link #EXTRA_HOUR}, {@link #EXTRA_MINUTES},
+ * {@link #EXTRA_IS_PM}.
+ * <li><i>Next alarm</i> - {@link #ALARM_SEARCH_MODE_NEXT}: Selects the alarm that will
+ * ring next, or the alarm that is currently ringing, if any.
+ * <li><i>All alarms</i> - {@link #ALARM_SEARCH_MODE_ALL}: Selects all alarms.
+ * <li><i>None</i> - {@link #ALARM_SEARCH_MODE_NONE}: No search mode specified. The
+ * implementation should ask the user to select a search mode using
+ * {@link android.app.VoiceInteractor.PickOptionRequest} and proceed with a voice flow to
+ * identify the alarm.
+ * </ul>
+ * </ol>
+ *
+ * @see #ALARM_SEARCH_MODE_TIME
+ * @see #ALARM_SEARCH_MODE_NEXT
+ * @see #ALARM_SEARCH_MODE_ALL
+ * @see #ALARM_SEARCH_MODE_NONE
+ * @see #ACTION_VOICE_CANCEL_ALARM
+ * @see #ACTION_VOICE_DELETE_ALARM
+ */
+ public static final String EXTRA_ALARM_SEARCH_MODE =
+ "android.intent.extra.alarm.ALARM_SEARCH_MODE";
+
+ /**
+ * Search for the alarm that is most closely matched by the search parameters
+ * {@link #EXTRA_HOUR}, {@link #EXTRA_MINUTES}, {@link #EXTRA_IS_PM}.
+ * In this search mode, at least one of these additional extras are required.
+ * <ul>
+ * <li>{@link #EXTRA_HOUR} - The hour to search for the alarm.
+ * <li>{@link #EXTRA_MINUTES} - The minute to search for the alarm.
+ * <li>{@link #EXTRA_IS_PM} - Whether the hour is AM or PM.
+ * </ul>
+ *
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ public static final String ALARM_SEARCH_MODE_TIME = "time";
+
+ /**
+ * Selects the alarm that will ring next, or the alarm that is currently ringing, if any.
+ *
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ public static final String ALARM_SEARCH_MODE_NEXT = "next";
+
+ /**
+ * Selects all alarms.
+ *
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ public static final String ALARM_SEARCH_MODE_ALL = "all";
+
+ /**
+ * No search mode specified. The implementation should ask the user to select a search mode
+ * using {@link android.app.VoiceInteractor.PickOptionRequest} and proceed with a voice flow to
+ * identify the alarm.
+ *
+ * @see #EXTRA_ALARM_SEARCH_MODE
+ */
+ public static final String ALARM_SEARCH_MODE_NONE = "none";
+
+ /**
+ * Bundle extra: The AM/PM of the alarm.
+ * <p>
+ * Used by {@link #ACTION_VOICE_CANCEL_ALARM} and {@link #ACTION_VOICE_DELETE_ALARM}.
+ * </p><p>
+ * This extra is optional and only used when {@link #EXTRA_ALARM_SEARCH_MODE} is set to
+ * {@link #ALARM_SEARCH_MODE_TIME}. In this search mode, the {@link #EXTRA_IS_PM} is
+ * used together with {@link #EXTRA_HOUR} and {@link #EXTRA_MINUTES}. The implementation should
+ * look up the alarm that is most closely matched by these search parameters.
+ * If {@link #EXTRA_IS_PM} is missing, then the AM/PM of the specified {@link #EXTRA_HOUR} is
+ * ambiguous and the implementation should ask for clarification from the user.
+ * </p><p>
+ * The value is a {@link Boolean}, where false=AM and true=PM.
+ * </p>
+ *
+ * @see #ACTION_VOICE_CANCEL_ALARM
+ * @see #ACTION_VOICE_DELETE_ALARM
+ * @see #EXTRA_HOUR
+ * @see #EXTRA_MINUTES
+ */
+ public static final String EXTRA_IS_PM = "android.intent.extra.alarm.IS_PM";
+
+ /**
* Bundle extra: Weekdays for repeating alarm.
* <p>
* Used by {@link #ACTION_SET_ALARM}.
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 50d701a..16353e8 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -316,7 +316,7 @@ public class ProgressBar extends View {
mProgressTintInfo = new ProgressTintInfo();
}
mProgressTintInfo.mProgressTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_progressBackgroundTintMode, -1), null);
+ R.styleable.ProgressBar_progressTintMode, -1), null);
mProgressTintInfo.mHasProgressTintMode = true;
}
@@ -334,7 +334,7 @@ public class ProgressBar extends View {
mProgressTintInfo = new ProgressTintInfo();
}
mProgressTintInfo.mProgressBackgroundTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_progressTintMode, -1), null);
+ R.styleable.ProgressBar_progressBackgroundTintMode, -1), null);
mProgressTintInfo.mHasProgressBackgroundTintMode = true;
}
@@ -365,7 +365,7 @@ public class ProgressBar extends View {
mProgressTintInfo.mHasSecondaryProgressTint = true;
}
- if (a.hasValue(R.styleable.ProgressBar_indeterminateTint)) {
+ if (a.hasValue(R.styleable.ProgressBar_indeterminateTintMode)) {
if (mProgressTintInfo == null) {
mProgressTintInfo = new ProgressTintInfo();
}
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 143dea4..52e1728 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -79,8 +79,10 @@ public class RadialTimePickerView extends View {
// Transparent alpha level
private static final int ALPHA_TRANSPARENT = 0;
- private static final int DEGREES_FOR_ONE_HOUR = 30;
- private static final int DEGREES_FOR_ONE_MINUTE = 6;
+ private static final int HOURS_IN_DAY = 24;
+ private static final int MINUTES_IN_HOUR = 60;
+ private static final int DEGREES_FOR_ONE_HOUR = 360 / HOURS_IN_DAY;
+ private static final int DEGREES_FOR_ONE_MINUTE = 360 / MINUTES_IN_HOUR;
private static final int[] HOURS_NUMBERS = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
private static final int[] HOURS_NUMBERS_24 = {0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
@@ -140,8 +142,7 @@ public class RadialTimePickerView extends View {
private final float[] mInnerTextX = new float[12];
private final float[] mInnerTextY = new float[12];
- private final int[] mLineLength = new int[3];
- private final int[] mSelectionDegrees = new int[3];
+ private final int[] mSelectionDegrees = new int[2];
private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<>();
private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<>();
@@ -168,13 +169,13 @@ public class RadialTimePickerView extends View {
private int mYCenter;
private int mCircleRadius;
- private int mMinHypotenuseForInnerNumber;
- private int mMaxHypotenuseForOuterNumber;
- private int mHalfwayHypotenusePoint;
+ private int mMinDistForInnerNumber;
+ private int mMaxDistForOuterNumber;
+ private int mHalfwayDist;
private String[] mOuterTextHours;
private String[] mInnerTextHours;
- private String[] mOuterTextMinutes;
+ private String[] mMinutesText;
private AnimatorSet mTransition;
private int mAmOrPm;
@@ -462,11 +463,10 @@ public class RadialTimePickerView extends View {
private void setCurrentHourInternal(int hour, boolean callback, boolean autoAdvance) {
final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
mSelectionDegrees[HOURS] = degrees;
- mSelectionDegrees[HOURS_INNER] = degrees;
// 0 is 12 AM (midnight) and 12 is 12 PM (noon).
final int amOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM;
- final boolean isOnInnerCircle = mIs24HourMode && hour >= 1 && hour <= 12;
+ final boolean isOnInnerCircle = getInnerCircleForHour(hour);
if (mAmOrPm != amOrPm || mIsOnInnerCircle != isOnInnerCircle) {
mAmOrPm = amOrPm;
mIsOnInnerCircle = isOnInnerCircle;
@@ -488,8 +488,7 @@ public class RadialTimePickerView extends View {
* @return the current hour between 0 and 23 (inclusive)
*/
public int getCurrentHour() {
- return getHourForDegrees(
- mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS], mIsOnInnerCircle);
+ return getHourForDegrees(mSelectionDegrees[HOURS], mIsOnInnerCircle);
}
private int getHourForDegrees(int degrees, boolean innerCircle) {
@@ -497,11 +496,11 @@ public class RadialTimePickerView extends View {
if (mIs24HourMode) {
// Convert the 12-hour value into 24-hour time based on where the
// selector is positioned.
- if (innerCircle && hour == 0) {
- // Inner circle is 1 through 12.
+ if (!innerCircle && hour == 0) {
+ // Outer circle is 1 through 12.
hour = 12;
- } else if (!innerCircle && hour != 0) {
- // Outer circle is 13 through 23 and 0.
+ } else if (innerCircle && hour != 0) {
+ // Inner circle is 13 through 23 and 0.
hour += 12;
}
} else if (mAmOrPm == PM) {
@@ -510,6 +509,9 @@ public class RadialTimePickerView extends View {
return hour;
}
+ /**
+ * @param hour the hour in 24-hour time or 12-hour time
+ */
private int getDegreesForHour(int hour) {
// Convert to be 0-11.
if (mIs24HourMode) {
@@ -522,12 +524,19 @@ public class RadialTimePickerView extends View {
return hour * DEGREES_FOR_ONE_HOUR;
}
+ /**
+ * @param hour the hour in 24-hour time or 12-hour time
+ */
+ private boolean getInnerCircleForHour(int hour) {
+ return mIs24HourMode && (hour == 0 || hour > 12);
+ }
+
public void setCurrentMinute(int minute) {
setCurrentMinuteInternal(minute, true);
}
private void setCurrentMinuteInternal(int minute, boolean callback) {
- mSelectionDegrees[MINUTES] = (minute % 60) * DEGREES_FOR_ONE_MINUTE;
+ mSelectionDegrees[MINUTES] = (minute % MINUTES_IN_HOUR) * DEGREES_FOR_ONE_MINUTE;
invalidate();
@@ -572,6 +581,7 @@ public class RadialTimePickerView extends View {
initData();
invalidate();
+ mTouchHelper.invalidateRoot();
}
public void showMinutes(boolean animate) {
@@ -587,6 +597,7 @@ public class RadialTimePickerView extends View {
initData();
invalidate();
+ mTouchHelper.invalidateRoot();
}
private void initHoursAndMinutesText() {
@@ -608,7 +619,7 @@ public class RadialTimePickerView extends View {
mInnerTextHours = mHours12Texts;
}
- mOuterTextMinutes = mMinutesTexts;
+ mMinutesText = mMinutesTexts;
final int hoursAlpha = mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT;
mAlpha[HOURS].setValue(hoursAlpha);
@@ -627,9 +638,9 @@ public class RadialTimePickerView extends View {
mYCenter = getHeight() / 2;
mCircleRadius = Math.min(mXCenter, mYCenter);
- mMinHypotenuseForInnerNumber = mCircleRadius - mTextInset[HOURS_INNER] - mSelectorRadius;
- mMaxHypotenuseForOuterNumber = mCircleRadius - mTextInset[HOURS] + mSelectorRadius;
- mHalfwayHypotenusePoint = mCircleRadius - (mTextInset[HOURS] + mTextInset[HOURS_INNER]) / 2;
+ mMinDistForInnerNumber = mCircleRadius - mTextInset[HOURS_INNER] - mSelectorRadius;
+ mMaxDistForOuterNumber = mCircleRadius - mTextInset[HOURS] + mSelectorRadius;
+ mHalfwayDist = mCircleRadius - (mTextInset[HOURS] + mTextInset[HOURS_INNER]) / 2;
calculatePositionsHours();
calculatePositionsMinutes();
@@ -674,6 +685,7 @@ public class RadialTimePickerView extends View {
private void drawMinutes(Canvas canvas, float alphaMod) {
final int minutesAlpha = (int) (mAlpha[MINUTES].getValue() * alphaMod + 0.5f);
if (minutesAlpha > 0) {
+ // Draw the minute selector under the elements.
drawSelector(canvas, MINUTES, mSelectorPath, alphaMod);
// Exclude the selector region, then draw minutes with no
@@ -681,7 +693,7 @@ public class RadialTimePickerView extends View {
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipPath(mSelectorPath, Region.Op.DIFFERENCE);
drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mTextColor[MINUTES],
- mOuterTextMinutes, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES],
+ mMinutesText, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES],
minutesAlpha, false, 0, false);
canvas.restore();
@@ -690,7 +702,7 @@ public class RadialTimePickerView extends View {
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipPath(mSelectorPath, Region.Op.INTERSECT);
drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mTextColor[MINUTES],
- mOuterTextMinutes, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES],
+ mMinutesText, mOuterTextX[MINUTES], mOuterTextY[MINUTES], mPaint[MINUTES],
minutesAlpha, true, mSelectionDegrees[MINUTES], true);
canvas.restore();
}
@@ -718,7 +730,7 @@ public class RadialTimePickerView extends View {
// Calculate the current radius at which to place the selection circle.
final int selRadius = mSelectorRadius;
final int selLength = mCircleRadius - mTextInset[index];
- final double selAngleRad = Math.toRadians(mSelectionDegrees[index]);
+ final double selAngleRad = Math.toRadians(mSelectionDegrees[index % 2]);
final float selCenterX = mXCenter + selLength * (float) Math.sin(selAngleRad);
final float selCenterY = mYCenter - selLength * (float) Math.cos(selAngleRad);
@@ -734,10 +746,10 @@ public class RadialTimePickerView extends View {
}
// Draw the dot if we're between two items.
- final boolean shouldDrawDot = mSelectionDegrees[index] % 30 != 0;
+ final boolean shouldDrawDot = mSelectionDegrees[index % 2] % 30 != 0;
if (shouldDrawDot) {
final Paint dotPaint = mPaintSelector[index % 2][SELECTOR_DOT];
- dotPaint.setColor(color);
+ dotPaint.setColor(mSelectorDotColor);
canvas.drawCircle(selCenterX, selCenterY, mSelectorDotRadius, dotPaint);
}
@@ -898,56 +910,43 @@ public class RadialTimePickerView extends View {
}
private int getDegreesFromXY(float x, float y, boolean constrainOutside) {
- final double hypotenuse = Math.sqrt(
- (y - mYCenter) * (y - mYCenter) + (x - mXCenter) * (x - mXCenter));
+ // Ensure the point is inside the touchable area.
+ final int innerBound;
+ final int outerBound;
+ if (mIs24HourMode && mShowHours) {
+ innerBound = mMinDistForInnerNumber;
+ outerBound = mMaxDistForOuterNumber;
+ } else {
+ final int index = mShowHours ? HOURS : MINUTES;
+ final int center = mCircleRadius - mTextInset[index];
+ innerBound = center - mSelectorRadius;
+ outerBound = center + mSelectorRadius;
+ }
- // Basic check if we're outside the range of the disk
- if (constrainOutside && hypotenuse > mCircleRadius) {
+ final double dX = x - mXCenter;
+ final double dY = y - mYCenter;
+ final double distFromCenter = Math.sqrt(dX * dX + dY * dY);
+ if (distFromCenter < innerBound || constrainOutside && distFromCenter > outerBound) {
return -1;
}
- // Check
- if (mIs24HourMode && mShowHours) {
- if (hypotenuse >= mMinHypotenuseForInnerNumber
- && hypotenuse <= mHalfwayHypotenusePoint) {
- mIsOnInnerCircle = true;
- } else if ((hypotenuse <= mMaxHypotenuseForOuterNumber || !constrainOutside)
- && hypotenuse >= mHalfwayHypotenusePoint) {
- mIsOnInnerCircle = false;
- } else {
- return -1;
- }
+ // Convert to degrees.
+ final int degrees = (int) (Math.toDegrees(Math.atan2(dY, dX) + Math.PI / 2) + 0.5);
+ if (degrees < 0) {
+ return degrees + 360;
} else {
- final int index = (mShowHours) ? HOURS : MINUTES;
- final float length = (mCircleRadius - mTextInset[index]);
- final int distanceToNumber = (int) (hypotenuse - length);
- final int maxAllowedDistance = mTextInset[index];
- if (distanceToNumber < -maxAllowedDistance
- || (constrainOutside && distanceToNumber > maxAllowedDistance)) {
- return -1;
- }
+ return degrees;
}
+ }
- final float opposite = Math.abs(y - mYCenter);
- int degrees = (int) (Math.toDegrees(Math.asin(opposite / hypotenuse)) + 0.5);
-
- // Now we have to translate to the correct quadrant.
- final boolean rightSide = (x > mXCenter);
- final boolean topSide = (y < mYCenter);
- if (rightSide) {
- if (topSide) {
- degrees = 90 - degrees;
- } else {
- degrees = 90 + degrees;
- }
- } else {
- if (topSide) {
- degrees = 270 + degrees;
- } else {
- degrees = 270 - degrees;
- }
+ private boolean getInnerCircleFromXY(float x, float y) {
+ if (mIs24HourMode && mShowHours) {
+ final double dX = x - mXCenter;
+ final double dY = y - mYCenter;
+ final double distFromCenter = Math.sqrt(dX * dX + dY * dY);
+ return distFromCenter <= mHalfwayDist;
}
- return degrees;
+ return false;
}
boolean mChangedDuringTouch = false;
@@ -987,34 +986,28 @@ public class RadialTimePickerView extends View {
private boolean handleTouchInput(
float x, float y, boolean forceSelection, boolean autoAdvance) {
- // Calling getDegreesFromXY has side effects, so cache
- // whether we used to be on the inner circle.
- final boolean wasOnInnerCircle = mIsOnInnerCircle;
+ final boolean isOnInnerCircle = getInnerCircleFromXY(x, y);
final int degrees = getDegreesFromXY(x, y, false);
if (degrees == -1) {
return false;
}
- final int[] selectionDegrees = mSelectionDegrees;
final int type;
final int newValue;
final boolean valueChanged;
if (mShowHours) {
final int snapDegrees = snapOnly30s(degrees, 0) % 360;
- valueChanged = selectionDegrees[HOURS] != snapDegrees
- || selectionDegrees[HOURS_INNER] != snapDegrees
- || wasOnInnerCircle != mIsOnInnerCircle;
-
- selectionDegrees[HOURS] = snapDegrees;
- selectionDegrees[HOURS_INNER] = snapDegrees;
+ valueChanged = mIsOnInnerCircle != isOnInnerCircle
+ || mSelectionDegrees[HOURS] != snapDegrees;
+ mIsOnInnerCircle = isOnInnerCircle;
+ mSelectionDegrees[HOURS] = snapDegrees;
type = HOURS;
newValue = getCurrentHour();
} else {
final int snapDegrees = snapPrefer30s(degrees) % 360;
- valueChanged = selectionDegrees[MINUTES] != snapDegrees;
-
- selectionDegrees[MINUTES] = snapDegrees;
+ valueChanged = mSelectionDegrees[MINUTES] != snapDegrees;
+ mSelectionDegrees[MINUTES] = snapDegrees;
type = MINUTES;
newValue = getCurrentMinute();
}
@@ -1132,17 +1125,11 @@ public class RadialTimePickerView extends View {
@Override
protected int getVirtualViewAt(float x, float y) {
final int id;
-
- // Calling getDegreesXY() has side-effects, so we need to cache the
- // current inner circle value and restore after the call.
- final boolean wasOnInnerCircle = mIsOnInnerCircle;
final int degrees = getDegreesFromXY(x, y, true);
- final boolean isOnInnerCircle = mIsOnInnerCircle;
- mIsOnInnerCircle = wasOnInnerCircle;
-
if (degrees != -1) {
final int snapDegrees = snapOnly30s(degrees, 0) % 360;
if (mShowHours) {
+ final boolean isOnInnerCircle = getInnerCircleFromXY(x, y);
final int hour24 = getHourForDegrees(snapDegrees, isOnInnerCircle);
final int hour = mIs24HourMode ? hour24 : hour24To12(hour24);
id = makeId(TYPE_HOUR, hour);
@@ -1153,8 +1140,10 @@ public class RadialTimePickerView extends View {
// If the touched minute is closer to the current minute
// than it is to the snapped minute, return current.
+ final int currentOffset = getCircularDiff(current, touched, MINUTES_IN_HOUR);
+ final int snappedOffset = getCircularDiff(snapped, touched, MINUTES_IN_HOUR);
final int minute;
- if (Math.abs(current - touched) < Math.abs(snapped - touched)) {
+ if (currentOffset < snappedOffset) {
minute = current;
} else {
minute = snapped;
@@ -1168,6 +1157,20 @@ public class RadialTimePickerView extends View {
return id;
}
+ /**
+ * Returns the difference in degrees between two values along a circle.
+ *
+ * @param first value in the range [0,max]
+ * @param second value in the range [0,max]
+ * @param max the maximum value along the circle
+ * @return the difference in between the two values
+ */
+ private int getCircularDiff(int first, int second, int max) {
+ final int diff = Math.abs(first - second);
+ final int midpoint = max / 2;
+ return (diff > midpoint) ? (max - diff) : diff;
+ }
+
@Override
protected void getVisibleVirtualViews(IntArray virtualViewIds) {
if (mShowHours) {
@@ -1178,7 +1181,7 @@ public class RadialTimePickerView extends View {
}
} else {
final int current = getCurrentMinute();
- for (int i = 0; i < 60; i += MINUTE_INCREMENT) {
+ for (int i = 0; i < MINUTES_IN_HOUR; i += MINUTE_INCREMENT) {
virtualViewIds.add(makeId(TYPE_MINUTE, i));
// If the current minute falls between two increments,
@@ -1236,7 +1239,7 @@ public class RadialTimePickerView extends View {
if (value < current && nextValue > current) {
// The current value is between two snap values.
return makeId(type, current);
- } else if (nextValue < 60) {
+ } else if (nextValue < MINUTES_IN_HOUR) {
return makeId(type, nextValue);
}
}
@@ -1290,7 +1293,7 @@ public class RadialTimePickerView extends View {
final float centerRadius;
final float degrees;
if (type == TYPE_HOUR) {
- final boolean innerCircle = mIs24HourMode && value > 0 && value <= 12;
+ final boolean innerCircle = getInnerCircleForHour(value);
if (innerCircle) {
centerRadius = mCircleRadius - mTextInset[HOURS_INNER];
radius = mSelectorRadius;
diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
new file mode 100644
index 0000000..6ac0d89
--- /dev/null
+++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import android.app.AppGlobals;
+import android.app.backup.BackupDataInputStream;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupHelper;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.org.bouncycastle.util.Arrays;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class PreferredActivityBackupHelper implements BackupHelper {
+ private static final String TAG = "PreferredBackup";
+ private static final boolean DEBUG = true;
+
+ // current schema of the backup state blob
+ private static final int STATE_VERSION = 1;
+
+ // key under which the preferred-activity state blob is committed to backup
+ private static final String KEY_PREFERRED = "preferred-activity";
+
+ final Context mContext;
+
+ public PreferredActivityBackupHelper(Context context) {
+ mContext = context;
+ }
+
+ // The fds passed here are shared among all helpers, so we mustn't close them
+ private void writeState(ParcelFileDescriptor stateFile, byte[] payload) {
+ try {
+ FileOutputStream fos = new FileOutputStream(stateFile.getFileDescriptor());
+
+ // We explicitly don't close 'out' because we must not close the backing fd.
+ // The FileOutputStream will not close it implicitly.
+ @SuppressWarnings("resource")
+ DataOutputStream out = new DataOutputStream(fos);
+
+ out.writeInt(STATE_VERSION);
+ if (payload == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(payload.length);
+ out.write(payload);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to write updated state", e);
+ }
+ }
+
+ private byte[] readState(ParcelFileDescriptor oldStateFd) {
+ FileInputStream fis = new FileInputStream(oldStateFd.getFileDescriptor());
+ BufferedInputStream bis = new BufferedInputStream(fis);
+
+ @SuppressWarnings("resource")
+ DataInputStream in = new DataInputStream(bis);
+
+ byte[] oldState = null;
+ try {
+ int version = in.readInt();
+ if (version == STATE_VERSION) {
+ int size = in.readInt();
+ if (size > 0) {
+ if (size > 200*1024) {
+ Slog.w(TAG, "Suspiciously large state blog; ignoring. N=" + size);
+ } else {
+ // size looks okay; make the return buffer and fill it
+ oldState = new byte[size];
+ in.read(oldState);
+ }
+ }
+ } else {
+ Slog.w(TAG, "Prior state from unrecognized version " + version);
+ }
+ } catch (EOFException e) {
+ // Empty file is expected on first backup, so carry on. If the state
+ // is truncated we just treat it the same way.
+ oldState = null;
+ } catch (Exception e) {
+ Slog.w(TAG, "Error examing prior backup state " + e.getMessage());
+ oldState = null;
+ }
+
+ return oldState;
+ }
+
+ @Override
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ byte[] payload = null;
+ try {
+ byte[] oldPayload = readState(oldState);
+
+ IPackageManager pm = AppGlobals.getPackageManager();
+ byte[] newPayload = pm.getPreferredActivityBackup(UserHandle.USER_OWNER);
+ if (!Arrays.areEqual(oldPayload, newPayload)) {
+ if (DEBUG) {
+ Slog.i(TAG, "State has changed => writing new preferred app payload");
+ }
+ data.writeEntityHeader(KEY_PREFERRED, newPayload.length);
+ data.writeEntityData(newPayload, newPayload.length);
+ } else {
+ if (DEBUG) {
+ Slog.i(TAG, "No change to state => not writing to wire");
+ }
+ }
+
+ // Always need to re-record the state, even if nothing changed
+ payload = newPayload;
+ } catch (Exception e) {
+ // On failures we'll wind up committing a zero-size state payload. This is
+ // a forward-safe situation because we know we commit the entire new payload
+ // on prior-state mismatch.
+ Slog.w(TAG, "Unable to record preferred activities", e);
+ } finally {
+ writeState(newState, payload);
+ }
+ }
+
+ @Override
+ public void restoreEntity(BackupDataInputStream data) {
+ IPackageManager pm = AppGlobals.getPackageManager();
+ try {
+ byte[] payload = new byte[data.size()];
+ data.read(payload);
+ if (DEBUG) {
+ Slog.i(TAG, "Restoring preferred activities; size=" + payload.length);
+ }
+ pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
+ } catch (Exception e) {
+ Slog.e(TAG, "Exception reading restore data", e);
+ }
+ }
+
+ @Override
+ public void writeNewStateDescription(ParcelFileDescriptor newState) {
+ writeState(newState, null);
+ }
+
+}
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 037fd66..19d9e29 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -16,7 +16,6 @@
package com.android.server.backup;
-
import android.app.ActivityManagerNative;
import android.app.IWallpaperManager;
import android.app.backup.BackupDataInput;
@@ -43,6 +42,13 @@ import java.io.IOException;
public class SystemBackupAgent extends BackupAgentHelper {
private static final String TAG = "SystemBackupAgent";
+ // Names of the helper tags within the dataset. Changing one of these names will
+ // break the ability to restore from datasets that predate the change.
+ private static final String WALLPAPER_HELPER = "wallpaper";
+ private static final String RECENTS_HELPER = "recents";
+ private static final String SYNC_SETTINGS_HELPER = "account_sync_settings";
+ private static final String PREFERRED_HELPER = "preferred_activities";
+
// These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME
// are also used in the full-backup file format, so must not change unless steps are
// taken to support the legacy backed-up datasets.
@@ -84,10 +90,10 @@ public class SystemBackupAgent extends BackupAgentHelper {
Slog.e(TAG, "Couldn't get wallpaper name\n" + re);
}
}
- addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files, keys));
- addHelper("recents", new RecentsBackupHelper(SystemBackupAgent.this));
- addHelper("account_sync_settings",
- new AccountSyncSettingsBackupHelper(SystemBackupAgent.this));
+ addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this, files, keys));
+ addHelper(RECENTS_HELPER, new RecentsBackupHelper(this));
+ addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
+ addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(this));
super.onBackup(oldState, data, newState);
}
@@ -113,15 +119,15 @@ public class SystemBackupAgent extends BackupAgentHelper {
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
// On restore, we also support a previous data schema "system_files"
- addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this,
+ addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this,
new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO },
new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} ));
- addHelper("system_files", new WallpaperBackupHelper(SystemBackupAgent.this,
+ addHelper("system_files", new WallpaperBackupHelper(this,
new String[] { WALLPAPER_IMAGE },
new String[] { WALLPAPER_IMAGE_KEY} ));
- addHelper("recents", new RecentsBackupHelper(SystemBackupAgent.this));
- addHelper("account_sync_settings",
- new AccountSyncSettingsBackupHelper(SystemBackupAgent.this));
+ addHelper(RECENTS_HELPER, new RecentsBackupHelper(this));
+ addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
+ addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(this));
try {
super.onRestore(data, appVersionCode, newState);
diff --git a/core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.png
deleted file mode 100644
index 2fa6d7e..0000000
--- a/core/res/res/drawable-hdpi/list_divider_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.png
deleted file mode 100644
index 070bdbf..0000000
--- a/core/res/res/drawable-mdpi/list_divider_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.png
deleted file mode 100644
index 0d2836d..0000000
--- a/core/res/res/drawable-xhdpi/list_divider_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.png
deleted file mode 100644
index b8ac46d..0000000
--- a/core/res/res/drawable-xxhdpi/list_divider_mtrl_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/list_divider_material.xml b/core/res/res/drawable/list_divider_material.xml
index babb646..658a59d 100644
--- a/core/res/res/drawable/list_divider_material.xml
+++ b/core/res/res/drawable/list_divider_material.xml
@@ -14,7 +14,10 @@
limitations under the License.
-->
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/list_divider_mtrl_alpha"
- android:tint="?attr/colorForeground"
- android:alpha="0.12" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tint="?attr/colorForeground">
+ <solid android:color="#1f000000" />
+ <size
+ android:height="1dp"
+ android:width="1dp" />
+</shape>
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 42b5d5d..5c3b90b 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -181,6 +181,18 @@
</family>
<family>
<fileset>
+ <file variant="elegant">NotoSansOriya-Regular.ttf</file>
+ <file variant="elegant">NotoSansOriya-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file variant="compact">NotoSansOriyaUI-Regular.ttf</file>
+ <file variant="compact">NotoSansOriyaUI-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
<file>NotoSansSinhala-Regular.ttf</file>
<file>NotoSansSinhala-Bold.ttf</file>
</fileset>
@@ -355,11 +367,6 @@
</family>
<family>
<fileset>
- <file>Lohit-Odia.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
<file lang="zh-Hans">NotoSansHans-Regular.otf</file>
</fileset>
</family>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 37527e9..f3a7647 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -191,6 +191,14 @@
<font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font>
</family>
+ <family variant="elegant">
+ <font weight="400" style="normal">NotoSansOriya-Regular.ttf</font>
+ <font weight="700" style="normal">NotoSansOriya-Bold.ttf</font>
+ </family>
+ <family variant="compact">
+ <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font>
+ <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font>
+ </family>
<family>
<font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font>
<font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font>
@@ -299,9 +307,6 @@
<family>
<font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
</family>
- <family>
- <font weight="400" style="normal">Lohit-Odia.ttf</font>
- </family>
<family lang="zh-Hans">
<font weight="400" style="normal">NotoSansHans-Regular.otf</font>
</family>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 64b4452..dd2368f 100755..100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -527,7 +527,11 @@ public final class CachedBluetoothDevice implements Comparable<CachedBluetoothDe
void onUuidChanged() {
updateProfiles();
ParcelUuid[] uuids = mDevice.getUuids();
+
long timeout = MAX_UUID_DELAY_FOR_AUTO_CONNECT;
+ if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) {
+ timeout = MAX_HOGP_DELAY_FOR_AUTO_CONNECT;
+ }
if (DEBUG) {
Log.d(TAG, "onUuidChanged: Time since last connect"
@@ -535,14 +539,12 @@ public final class CachedBluetoothDevice implements Comparable<CachedBluetoothDe
}
/*
- * If a connect was attempted earlier without any UUID, we will do the
- * connect now.
+ * If a connect was attempted earlier without any UUID, we will do the connect now.
+ * Otherwise, allow the connect on UUID change.
*/
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) {
- timeout = MAX_HOGP_DELAY_FOR_AUTO_CONNECT;
- }
if (!mProfiles.isEmpty()
- && (mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
+ && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()
+ || (mConnectAttempted == 0))) {
connectWithoutResettingTimer(false);
}
dispatchAttributesChanged();
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index 0f967fc..de1c497 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -47,6 +47,15 @@ public class FieldPacker {
// subAlign() can never work correctly for copied FieldPacker objects.
}
+ static FieldPacker createFromArray(Object[] args) {
+ FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
+ for (Object arg : args) {
+ fp.addSafely(arg);
+ }
+ fp.resize(fp.mPos);
+ return fp;
+ }
+
public void align(int v) {
if ((v <= 0) || ((v & (v - 1)) != 0)) {
throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
@@ -618,294 +627,182 @@ public class FieldPacker {
return mPos;
}
- private static void addToPack(FieldPacker fp, Object obj) {
+ private void add(Object obj) {
if (obj instanceof Boolean) {
- fp.addBoolean(((Boolean)obj).booleanValue());
+ addBoolean((Boolean)obj);
return;
}
if (obj instanceof Byte) {
- fp.addI8(((Byte)obj).byteValue());
+ addI8((Byte)obj);
return;
}
if (obj instanceof Short) {
- fp.addI16(((Short)obj).shortValue());
+ addI16((Short)obj);
return;
}
if (obj instanceof Integer) {
- fp.addI32(((Integer)obj).intValue());
+ addI32((Integer)obj);
return;
}
if (obj instanceof Long) {
- fp.addI64(((Long)obj).longValue());
+ addI64((Long)obj);
return;
}
if (obj instanceof Float) {
- fp.addF32(((Float)obj).floatValue());
+ addF32((Float)obj);
return;
}
if (obj instanceof Double) {
- fp.addF64(((Double)obj).doubleValue());
+ addF64((Double)obj);
return;
}
if (obj instanceof Byte2) {
- fp.addI8((Byte2)obj);
+ addI8((Byte2)obj);
return;
}
if (obj instanceof Byte3) {
- fp.addI8((Byte3)obj);
+ addI8((Byte3)obj);
return;
}
if (obj instanceof Byte4) {
- fp.addI8((Byte4)obj);
+ addI8((Byte4)obj);
return;
}
if (obj instanceof Short2) {
- fp.addI16((Short2)obj);
+ addI16((Short2)obj);
return;
}
if (obj instanceof Short3) {
- fp.addI16((Short3)obj);
+ addI16((Short3)obj);
return;
}
if (obj instanceof Short4) {
- fp.addI16((Short4)obj);
+ addI16((Short4)obj);
return;
}
if (obj instanceof Int2) {
- fp.addI32((Int2)obj);
+ addI32((Int2)obj);
return;
}
if (obj instanceof Int3) {
- fp.addI32((Int3)obj);
+ addI32((Int3)obj);
return;
}
if (obj instanceof Int4) {
- fp.addI32((Int4)obj);
+ addI32((Int4)obj);
return;
}
if (obj instanceof Long2) {
- fp.addI64((Long2)obj);
+ addI64((Long2)obj);
return;
}
if (obj instanceof Long3) {
- fp.addI64((Long3)obj);
+ addI64((Long3)obj);
return;
}
if (obj instanceof Long4) {
- fp.addI64((Long4)obj);
+ addI64((Long4)obj);
return;
}
if (obj instanceof Float2) {
- fp.addF32((Float2)obj);
+ addF32((Float2)obj);
return;
}
if (obj instanceof Float3) {
- fp.addF32((Float3)obj);
+ addF32((Float3)obj);
return;
}
if (obj instanceof Float4) {
- fp.addF32((Float4)obj);
+ addF32((Float4)obj);
return;
}
if (obj instanceof Double2) {
- fp.addF64((Double2)obj);
+ addF64((Double2)obj);
return;
}
if (obj instanceof Double3) {
- fp.addF64((Double3)obj);
+ addF64((Double3)obj);
return;
}
if (obj instanceof Double4) {
- fp.addF64((Double4)obj);
+ addF64((Double4)obj);
return;
}
if (obj instanceof Matrix2f) {
- fp.addMatrix((Matrix2f)obj);
+ addMatrix((Matrix2f)obj);
return;
}
if (obj instanceof Matrix3f) {
- fp.addMatrix((Matrix3f)obj);
+ addMatrix((Matrix3f)obj);
return;
}
if (obj instanceof Matrix4f) {
- fp.addMatrix((Matrix4f)obj);
+ addMatrix((Matrix4f)obj);
return;
}
if (obj instanceof BaseObj) {
- fp.addObj((BaseObj)obj);
+ addObj((BaseObj)obj);
return;
}
}
- private static int getPackedSize(Object obj) {
- if (obj instanceof Boolean) {
- return 1;
- }
-
- if (obj instanceof Byte) {
- return 1;
- }
-
- if (obj instanceof Short) {
- return 2;
- }
-
- if (obj instanceof Integer) {
- return 4;
- }
-
- if (obj instanceof Long) {
- return 8;
- }
-
- if (obj instanceof Float) {
- return 4;
- }
-
- if (obj instanceof Double) {
- return 8;
- }
-
- if (obj instanceof Byte2) {
- return 2;
- }
-
- if (obj instanceof Byte3) {
- return 3;
- }
-
- if (obj instanceof Byte4) {
- return 4;
- }
-
- if (obj instanceof Short2) {
- return 4;
- }
-
- if (obj instanceof Short3) {
- return 6;
- }
-
- if (obj instanceof Short4) {
- return 8;
- }
-
- if (obj instanceof Int2) {
- return 8;
- }
-
- if (obj instanceof Int3) {
- return 12;
- }
-
- if (obj instanceof Int4) {
- return 16;
- }
-
- if (obj instanceof Long2) {
- return 16;
- }
-
- if (obj instanceof Long3) {
- return 24;
- }
-
- if (obj instanceof Long4) {
- return 32;
- }
-
- if (obj instanceof Float2) {
- return 8;
- }
-
- if (obj instanceof Float3) {
- return 12;
+ private boolean resize(int newSize) {
+ if (newSize == mLen) {
+ return false;
}
- if (obj instanceof Float4) {
- return 16;
- }
-
- if (obj instanceof Double2) {
- return 16;
- }
-
- if (obj instanceof Double3) {
- return 24;
- }
-
- if (obj instanceof Double4) {
- return 32;
- }
-
- if (obj instanceof Matrix2f) {
- return 16;
- }
-
- if (obj instanceof Matrix3f) {
- return 36;
- }
-
- if (obj instanceof Matrix4f) {
- return 64;
- }
-
- if (obj instanceof BaseObj) {
- if (RenderScript.sPointerSize == 8) {
- return 32;
- } else {
- return 4;
- }
- }
-
- return 0;
+ byte[] newData = new byte[newSize];
+ System.arraycopy(mData, 0, newData, 0, mPos);
+ mData = newData;
+ mLen = newSize;
+ return true;
}
- static FieldPacker createFieldPack(Object[] args) {
- int len = 0;
- for (Object arg : args) {
- len += getPackedSize(arg);
- }
- FieldPacker fp = new FieldPacker(len);
- for (Object arg : args) {
- addToPack(fp, arg);
- }
- return fp;
+ private void addSafely(Object obj) {
+ boolean retry;
+ final int oldPos = mPos;
+ do {
+ retry = false;
+ try {
+ add(obj);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ mPos = oldPos;
+ resize(mLen * 2);
+ retry = true;
+ }
+ } while (retry);
}
- private final byte mData[];
+ private byte mData[];
private int mPos;
private int mLen;
private BitSet mAlignment;
-
}
-
-
diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java
index 9d73ac4..8b9f73e 100644
--- a/rs/java/android/renderscript/ScriptGroup2.java
+++ b/rs/java/android/renderscript/ScriptGroup2.java
@@ -126,7 +126,7 @@ public class ScriptGroup2 extends BaseObj {
public Closure(RenderScript rs, Script.InvokeID invokeID,
Object[] args, Map<Script.FieldID, Object> globals) {
super(0, rs);
- mFP = FieldPacker.createFieldPack(args);
+ mFP = FieldPacker.createFromArray(args);
mArgs = args;
mBindings = globals;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
index 5c4edd3..60e2b6d 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -34,7 +34,7 @@ public final class ScriptIntrinsicBlur extends ScriptIntrinsic {
* Create an intrinsic for applying a blur to an allocation. The
* default radius is 5.0.
*
- * Supported elements types are {@link Element#U8_4}
+ * Supported elements types are {@link Element#U8_4 Element#U8}
*
* @param rs The RenderScript context
* @param e Element type for inputs and outputs
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5cc59e5..96840a2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -94,6 +94,7 @@ import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
+import com.android.server.pm.PackageManagerService;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 43f74fc..4ac2b48 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -785,6 +785,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr != null) {
onNewAvrAdded(avr);
+ } else {
+ setSystemAudioMode(false, true);
}
}
});
@@ -1615,10 +1617,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
removeAction(SystemAudioAutoInitiationAction.class);
removeAction(SystemAudioStatusAction.class);
removeAction(VolumeControlAction.class);
-
- // Turn off the mode but do not write it the settings, so that the next time TV powers on
- // the system audio mode setting can be restored automatically.
- setSystemAudioMode(false, false);
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 03e9ad5..8a9f3e1 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -42,7 +42,7 @@ public class AppIdleController extends StateController
implements UsageStatsManagerInternal.AppIdleStateChangeListener {
private static final String LOG_TAG = "AppIdleController";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
// Singleton factory
private static Object sCreationLock = new Object();
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 4c6cb17..b3d7287 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -91,14 +91,20 @@ public class TimeController extends StateController {
public synchronized void maybeStartTrackingJob(JobStatus job) {
if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
maybeStopTrackingJob(job);
+ boolean isInsert = false;
ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
while (it.hasPrevious()) {
JobStatus ts = it.previous();
if (ts.getLatestRunTimeElapsed() < job.getLatestRunTimeElapsed()) {
// Insert
+ isInsert = true;
break;
}
}
+ if(isInsert)
+ {
+ it.next();
+ }
it.add(job);
maybeUpdateAlarms(
job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3c99484..2ff1718 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -87,6 +87,7 @@ import com.android.server.Watchdog;
import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.storage.DeviceStorageMonitorInternal;
+import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.app.ActivityManager;
@@ -189,11 +190,14 @@ import android.util.PrintStreamPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.Xml;
import android.view.Display;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -246,6 +250,7 @@ public class PackageManagerService extends IPackageManager.Stub {
static final boolean DEBUG_SETTINGS = false;
static final boolean DEBUG_PREFERRED = false;
static final boolean DEBUG_UPGRADE = false;
+ private static final boolean DEBUG_BACKUP = true;
private static final boolean DEBUG_INSTALL = false;
private static final boolean DEBUG_REMOVE = false;
private static final boolean DEBUG_BROADCASTS = false;
@@ -866,6 +871,9 @@ public class PackageManagerService extends IPackageManager.Stub {
final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
+ // backup/restore of preferred activity state
+ private static final String TAG_PREFERRED_BACKUP = "pa";
+
private final String mRequiredVerifierPackage;
private final PackageUsage mPackageUsage = new PackageUsage();
@@ -12525,6 +12533,83 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ /**
+ * Non-Binder method, support for the backup/restore mechanism: write the
+ * full set of preferred activities in its canonical XML format. Returns true
+ * on success; false otherwise.
+ */
+ @Override
+ public byte[] getPreferredActivityBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getPreferredActivityBackup()");
+ }
+
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ try {
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, "utf-8");
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_PREFERRED_BACKUP);
+
+ synchronized (mPackages) {
+ mSettings.writePreferredActivitiesLPr(serializer, userId, true);
+ }
+
+ serializer.endTag(null, TAG_PREFERRED_BACKUP);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Unable to write preferred activities for backup", e);
+ }
+ return null;
+ }
+
+ return dataStream.toByteArray();
+ }
+
+ @Override
+ public void restorePreferredActivities(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restorePreferredActivities()");
+ }
+
+ try {
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new ByteArrayInputStream(backup), null);
+
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ }
+ if (type != XmlPullParser.START_TAG) {
+ // oops didn't find a start tag?!
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Didn't find start tag during restore");
+ }
+ return;
+ }
+
+ // this is supposed to be TAG_PREFERRED_BACKUP
+ if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Found unexpected tag " + parser.getName());
+ }
+ return;
+ }
+
+ // skip interfering stuff, then we're aligned with the backing implementation
+ while ((type = parser.next()) == XmlPullParser.TEXT) { }
+ synchronized (mPackages) {
+ mSettings.readPreferredActivitiesLPw(parser, userId);
+ }
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
+ }
+ }
+ }
+
@Override
public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
int sourceUserId, int targetUserId, int flags) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 0d2ef89..6930965 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -45,15 +45,16 @@ import android.os.UserManager;
import android.util.AtomicFile;
import android.text.TextUtils;
import android.util.LogPrinter;
-
import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
+import com.android.server.backup.PreferredActivityBackupHelper;
import com.android.server.pm.PackageManagerService.DumpState;
import java.io.FileNotFoundException;
@@ -1108,7 +1109,13 @@ final class Settings {
mExternalDatabaseVersion = CURRENT_DATABASE_VERSION;
}
- private void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
+ /**
+ * Applies the preferred activity state described by the given XML. This code
+ * also supports the restore-from-backup code path.
+ *
+ * @see PreferredActivityBackupHelper
+ */
+ void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
@@ -1399,6 +1406,11 @@ final class Settings {
return components;
}
+ /**
+ * Record the state of preferred activity configuration into XML. This is used both
+ * for recording packages.xml internally and for supporting backup/restore of the
+ * preferred activity configuration.
+ */
void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(null, "preferred-activities");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d365759..796868c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -617,8 +617,8 @@ public class WindowManagerService extends IWindowManager.Stub
static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
boolean mAnimateWallpaperWithTarget;
- // We give a wallpaper up to 1000ms to finish drawing before playing app transitions.
- static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 1000;
+ // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
+ static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
static final int WALLPAPER_DRAW_NORMAL = 0;
static final int WALLPAPER_DRAW_PENDING = 1;
static final int WALLPAPER_DRAW_TIMEOUT = 2;
@@ -9064,41 +9064,40 @@ public class WindowManagerService extends IWindowManager.Stub
goodToGo = false;
}
}
-// Stuck in a state with mWallpaperDrawState == WALLPAPER_DRAW_PENDING without a timeout. Leave
-// commented out until that is understood.
-// if (goodToGo && isWallpaperVisible(mWallpaperTarget)) {
-// boolean wallpaperGoodToGo = true;
-// for (int curTokenIndex = mWallpaperTokens.size() - 1;
-// curTokenIndex >= 0 && wallpaperGoodToGo; curTokenIndex--) {
-// WindowToken token = mWallpaperTokens.get(curTokenIndex);
-// for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
-// curWallpaperIndex--) {
-// WindowState wallpaper = token.windows.get(curWallpaperIndex);
-// if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
-// // We've told this wallpaper to be visible, but it is not drawn yet
-// wallpaperGoodToGo = false;
-// if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
-// // wait for this wallpaper until it is drawn or timeout
-// goodToGo = false;
-// }
-// if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
-// mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
-// mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
-// mH.sendEmptyMessageDelayed(H.WALLPAPER_DRAW_PENDING_TIMEOUT,
-// WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
-// }
-// if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
-// "Wallpaper should be visible but has not been drawn yet. " +
-// "mWallpaperDrawState=" + mWallpaperDrawState);
-// break;
-// }
-// }
-// }
-// if (wallpaperGoodToGo) {
-// mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
-// mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
-// }
-// }
+
+ if (goodToGo && isWallpaperVisible(mWallpaperTarget)) {
+ boolean wallpaperGoodToGo = true;
+ for (int curTokenIndex = mWallpaperTokens.size() - 1;
+ curTokenIndex >= 0 && wallpaperGoodToGo; curTokenIndex--) {
+ WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
+ curWallpaperIndex--) {
+ WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
+ // We've told this wallpaper to be visible, but it is not drawn yet
+ wallpaperGoodToGo = false;
+ if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
+ // wait for this wallpaper until it is drawn or timeout
+ goodToGo = false;
+ }
+ if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
+ mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
+ mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
+ mH.sendEmptyMessageDelayed(H.WALLPAPER_DRAW_PENDING_TIMEOUT,
+ WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
+ }
+ if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
+ "Wallpaper should be visible but has not been drawn yet. " +
+ "mWallpaperDrawState=" + mWallpaperDrawState);
+ break;
+ }
+ }
+ }
+ if (wallpaperGoodToGo) {
+ mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+ mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
+ }
+ }
}
if (goodToGo) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
@@ -9890,7 +9889,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+ winAnimator.prepareSurfaceLocked(recoveringMemory);
final AppWindowToken atoken = w.mAppToken;
if (DEBUG_STARTING_WINDOW && atoken != null
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index ac1b0f1..056267d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1341,7 +1341,7 @@ class WindowStateAnimator {
}
}
- void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
+ private void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
int width;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 235567c..4498b84 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -18,6 +18,7 @@ package com.android.server.usage;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageStatsManager;
+import android.os.Build;
import android.util.AtomicFile;
import android.util.Slog;
@@ -35,7 +36,7 @@ import java.util.List;
* Provides an interface to query for UsageStat data from an XML database.
*/
class UsageStatsDatabase {
- private static final int CURRENT_VERSION = 2;
+ private static final int CURRENT_VERSION = 3;
private static final String TAG = "UsageStatsDatabase";
private static final boolean DEBUG = UsageStatsService.DEBUG;
@@ -47,6 +48,8 @@ class UsageStatsDatabase {
private final TimeSparseArray<AtomicFile>[] mSortedStatFiles;
private final UnixCalendar mCal;
private final File mVersionFile;
+ private boolean mFirstUpdate;
+ private boolean mNewUpdate;
public UsageStatsDatabase(File dir) {
mIntervalDirs = new File[] {
@@ -73,7 +76,7 @@ class UsageStatsDatabase {
}
}
- checkVersionLocked();
+ checkVersionAndBuildLocked();
indexFilesLocked();
// Delete files that are in the future.
@@ -194,10 +197,35 @@ class UsageStatsDatabase {
}
}
- private void checkVersionLocked() {
+ /**
+ * Is this the first update to the system from L to M?
+ */
+ boolean isFirstUpdate() {
+ return mFirstUpdate;
+ }
+
+ /**
+ * Is this a system update since we started tracking build fingerprint in the version file?
+ */
+ boolean isNewUpdate() {
+ return mNewUpdate;
+ }
+
+ private void checkVersionAndBuildLocked() {
int version;
+ String buildFingerprint;
+ String currentFingerprint = getBuildFingerprint();
+ mFirstUpdate = true;
+ mNewUpdate = true;
try (BufferedReader reader = new BufferedReader(new FileReader(mVersionFile))) {
version = Integer.parseInt(reader.readLine());
+ buildFingerprint = reader.readLine();
+ if (buildFingerprint != null) {
+ mFirstUpdate = false;
+ }
+ if (currentFingerprint.equals(buildFingerprint)) {
+ mNewUpdate = false;
+ }
} catch (NumberFormatException | IOException e) {
version = 0;
}
@@ -205,9 +233,15 @@ class UsageStatsDatabase {
if (version != CURRENT_VERSION) {
Slog.i(TAG, "Upgrading from version " + version + " to " + CURRENT_VERSION);
doUpgradeLocked(version);
+ }
+ if (version != CURRENT_VERSION || mNewUpdate) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(mVersionFile))) {
writer.write(Integer.toString(CURRENT_VERSION));
+ writer.write("\n");
+ writer.write(currentFingerprint);
+ writer.write("\n");
+ writer.flush();
} catch (IOException e) {
Slog.e(TAG, "Failed to write new version");
throw new RuntimeException(e);
@@ -215,6 +249,12 @@ class UsageStatsDatabase {
}
}
+ private String getBuildFingerprint() {
+ return Build.VERSION.RELEASE + ";"
+ + Build.VERSION.CODENAME + ";"
+ + Build.VERSION.INCREMENTAL;
+ }
+
private void doUpgradeLocked(int thisVersion) {
if (thisVersion < 2) {
// Delete all files if we are version 0. This is a pre-release version,
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index f458dbc..cc0ab81 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -92,7 +92,7 @@ public class UsageStatsService extends SystemService implements
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
- private static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = 3L * 24 * 60 * 60 * 1000; //3 days
+ private static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = 1L * 24 * 60 * 60 * 1000; // 1 day
private long mAppIdleDurationMillis;
private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener>
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index afe27c7..0a9481a 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -19,8 +19,11 @@ package com.android.server.usage;
import android.app.usage.ConfigurationStats;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
+import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.content.Context;
@@ -60,6 +63,7 @@ class UserUsageStatsService {
private final UnixCalendar mDailyExpiryDate;
private final StatsUpdatedListener mListener;
private final String mLogPrefix;
+ private final int mUserId;
interface StatsUpdatedListener {
void onStatsUpdated();
@@ -73,6 +77,7 @@ class UserUsageStatsService {
mCurrentStats = new IntervalStats[UsageStatsManager.INTERVAL_COUNT];
mListener = listener;
mLogPrefix = "User[" + Integer.toString(userId) + "] ";
+ mUserId = userId;
}
void init(final long currentTimeMillis) {
@@ -128,6 +133,35 @@ class UserUsageStatsService {
stat.updateConfigurationStats(null, stat.lastTimeSaved);
}
+
+ if (mDatabase.isNewUpdate()) {
+ initializeDefaultsForApps(currentTimeMillis, mDatabase.isFirstUpdate());
+ }
+ }
+
+ /**
+ * If any of the apps don't have a last-used entry, add one now.
+ * @param currentTimeMillis the current time
+ * @param firstUpdate if it is the first update, touch all installed apps, otherwise only
+ * touch the system apps
+ */
+ private void initializeDefaultsForApps(long currentTimeMillis, boolean firstUpdate) {
+ PackageManager pm = mContext.getPackageManager();
+ List<PackageInfo> packages = pm.getInstalledPackages(0, mUserId);
+ final int packageCount = packages.size();
+ for (int i = 0; i < packageCount; i++) {
+ final PackageInfo pi = packages.get(i);
+ String packageName = pi.packageName;
+ if (pi.applicationInfo != null && (firstUpdate || pi.applicationInfo.isSystemApp())
+ && getLastPackageAccessTime(packageName) == -1) {
+ for (IntervalStats stats : mCurrentStats) {
+ stats.update(packageName, currentTimeMillis, Event.INTERACTION);
+ mStatsChanged = true;
+ }
+ }
+ }
+ // Persist the new OTA-related access stats.
+ persistActiveStats();
}
void onTimeChanged(long oldTime, long newTime) {