Merge "Store work lock type even it uses unified lock" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 70ea1c5..f9e1d58 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2024,6 +2024,8 @@
field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+ field public static final int TextAppearance_Material_Widget_Button_Borderless_Colored = 16974559; // 0x10302df
+ field public static final int TextAppearance_Material_Widget_Button_Colored = 16974558; // 0x10302de
field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974548; // 0x10302d4
field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
@@ -6455,7 +6457,7 @@
public class NetworkStatsManager {
method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+ method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -23624,7 +23626,6 @@
method public boolean isConnected();
method public boolean isConnectedOrConnecting();
method public boolean isFailover();
- method public boolean isMetered();
method public boolean isRoaming();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -28267,7 +28268,7 @@
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
field public static final int M = 23; // 0x17
- field public static final int N = 10000; // 0x2710
+ field public static final int N = 24; // 0x18
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -34569,7 +34570,7 @@
package android.service.notification {
- public class Condition implements android.os.Parcelable {
+ public final class Condition implements android.os.Parcelable {
ctor public Condition(android.net.Uri, java.lang.String, int);
ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
ctor public Condition(android.os.Parcel);
@@ -34606,7 +34607,7 @@
method public void onRequestConditions(int);
method public abstract void onSubscribe(android.net.Uri);
method public abstract void onUnsubscribe(android.net.Uri);
- field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
+ field public static final java.lang.String EXTRA_RULE_ID = "android.service.notification.extra.RULE_ID";
field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
@@ -36608,11 +36609,9 @@
package android.telephony {
public class CarrierConfigManager {
- method public android.os.PersistableBundle getConfig(int);
method public android.os.PersistableBundle getConfig();
- method public deprecated android.os.PersistableBundle getConfigForSubId(int);
- method public void notifyConfigChanged(int);
- method public deprecated void notifyConfigChangedForSubId(int);
+ method public android.os.PersistableBundle getConfigForSubId(int);
+ method public void notifyConfigChangedForSubId(int);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
@@ -37763,7 +37762,7 @@
ctor public MockApplication();
}
- public deprecated class MockContentProvider extends android.content.ContentProvider {
+ public class MockContentProvider extends android.content.ContentProvider {
ctor protected MockContentProvider();
ctor public MockContentProvider(android.content.Context);
ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -37775,13 +37774,13 @@
method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
}
- public deprecated class MockContentResolver extends android.content.ContentResolver {
+ public class MockContentResolver extends android.content.ContentResolver {
ctor public MockContentResolver();
ctor public MockContentResolver(android.content.Context);
method public void addProvider(java.lang.String, android.content.ContentProvider);
}
- public deprecated class MockContext extends android.content.Context {
+ public class MockContext extends android.content.Context {
ctor public MockContext();
method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
method public int checkCallingOrSelfPermission(java.lang.String);
@@ -42501,6 +42500,7 @@
method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
method public boolean performAccessibilityAction(int, android.os.Bundle);
method public boolean performClick();
+ method public boolean performContextClick(float, float);
method public boolean performContextClick();
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
diff --git a/api/removed.txt b/api/removed.txt
index 42c64ea..0ff2476 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -31,37 +31,6 @@
}
-package android.app.usage {
-
- public class DataUsagePolicy {
- field public final int networkType;
- field public final java.lang.String[] subscriberIds;
- field public final long thresholdInBytes;
- field public final int[] uids;
- }
-
- public static class DataUsagePolicy.Builder {
- ctor public DataUsagePolicy.Builder();
- method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
- method public android.app.usage.DataUsagePolicy.Builder addUid(int);
- method public android.app.usage.DataUsagePolicy build();
- method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
- method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
- }
-
- public class NetworkStatsManager {
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
- method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
- }
-
- public static abstract class NetworkStatsManager.DataUsageCallback {
- ctor public NetworkStatsManager.DataUsageCallback();
- method public deprecated void onLimitReached();
- }
-
-}
-
package android.content {
public abstract class Context {
diff --git a/api/system-current.txt b/api/system-current.txt
index a6f612d..24ed720 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2136,6 +2136,8 @@
field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+ field public static final int TextAppearance_Material_Widget_Button_Borderless_Colored = 16974559; // 0x10302df
+ field public static final int TextAppearance_Material_Widget_Button_Colored = 16974558; // 0x10302de
field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974548; // 0x10302d4
field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
@@ -6736,7 +6738,7 @@
public class NetworkStatsManager {
method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+ method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -25446,7 +25448,6 @@
method public boolean isConnected();
method public boolean isConnectedOrConnecting();
method public boolean isFailover();
- method public boolean isMetered();
method public boolean isRoaming();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -30706,7 +30707,7 @@
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
field public static final int M = 23; // 0x17
- field public static final int N = 10000; // 0x2710
+ field public static final int N = 24; // 0x18
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -37292,7 +37293,7 @@
field public static final java.lang.String NEEDS_AUTOGROUPING_KEY = "autogroup_needed";
}
- public class Condition implements android.os.Parcelable {
+ public final class Condition implements android.os.Parcelable {
ctor public Condition(android.net.Uri, java.lang.String, int);
ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
ctor public Condition(android.os.Parcel);
@@ -37329,7 +37330,7 @@
method public void onRequestConditions(int);
method public abstract void onSubscribe(android.net.Uri);
method public abstract void onUnsubscribe(android.net.Uri);
- field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
+ field public static final java.lang.String EXTRA_RULE_ID = "android.service.notification.extra.RULE_ID";
field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
@@ -39539,12 +39540,10 @@
package android.telephony {
public class CarrierConfigManager {
- method public android.os.PersistableBundle getConfig(int);
method public android.os.PersistableBundle getConfig();
- method public deprecated android.os.PersistableBundle getConfigForSubId(int);
+ method public android.os.PersistableBundle getConfigForSubId(int);
method public static android.os.PersistableBundle getDefaultConfig();
- method public void notifyConfigChanged(int);
- method public deprecated void notifyConfigChangedForSubId(int);
+ method public void notifyConfigChangedForSubId(int);
method public void updateConfigForPhoneId(int, java.lang.String);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
@@ -40749,7 +40748,7 @@
ctor public MockApplication();
}
- public deprecated class MockContentProvider extends android.content.ContentProvider {
+ public class MockContentProvider extends android.content.ContentProvider {
ctor protected MockContentProvider();
ctor public MockContentProvider(android.content.Context);
ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -40761,13 +40760,13 @@
method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
}
- public deprecated class MockContentResolver extends android.content.ContentResolver {
+ public class MockContentResolver extends android.content.ContentResolver {
ctor public MockContentResolver();
ctor public MockContentResolver(android.content.Context);
method public void addProvider(java.lang.String, android.content.ContentProvider);
}
- public deprecated class MockContext extends android.content.Context {
+ public class MockContext extends android.content.Context {
ctor public MockContext();
method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
method public int checkCallingOrSelfPermission(java.lang.String);
@@ -45499,6 +45498,7 @@
method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
method public boolean performAccessibilityAction(int, android.os.Bundle);
method public boolean performClick();
+ method public boolean performContextClick(float, float);
method public boolean performContextClick();
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 4873605..715312f 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -29,37 +29,6 @@
}
-package android.app.usage {
-
- public class DataUsagePolicy {
- field public final int networkType;
- field public final java.lang.String[] subscriberIds;
- field public final long thresholdInBytes;
- field public final int[] uids;
- }
-
- public static class DataUsagePolicy.Builder {
- ctor public DataUsagePolicy.Builder();
- method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
- method public android.app.usage.DataUsagePolicy.Builder addUid(int);
- method public android.app.usage.DataUsagePolicy build();
- method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
- method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
- }
-
- public class NetworkStatsManager {
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
- method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
- }
-
- public static abstract class NetworkStatsManager.DataUsageCallback {
- ctor public NetworkStatsManager.DataUsageCallback();
- method public deprecated void onLimitReached();
- }
-
-}
-
package android.content {
public abstract class Context {
diff --git a/api/test-current.txt b/api/test-current.txt
index 37bc7af..b6ebf8a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2024,6 +2024,8 @@
field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+ field public static final int TextAppearance_Material_Widget_Button_Borderless_Colored = 16974559; // 0x10302df
+ field public static final int TextAppearance_Material_Widget_Button_Colored = 16974558; // 0x10302de
field public static final int TextAppearance_Material_Widget_Button_Inverse = 16974548; // 0x10302d4
field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
@@ -6461,7 +6463,7 @@
public class NetworkStatsManager {
method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+ method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -23693,7 +23695,6 @@
method public boolean isConnected();
method public boolean isConnectedOrConnecting();
method public boolean isFailover();
- method public boolean isMetered();
method public boolean isRoaming();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -28336,7 +28337,7 @@
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
field public static final int M = 23; // 0x17
- field public static final int N = 10000; // 0x2710
+ field public static final int N = 24; // 0x18
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -34646,7 +34647,7 @@
package android.service.notification {
- public class Condition implements android.os.Parcelable {
+ public final class Condition implements android.os.Parcelable {
ctor public Condition(android.net.Uri, java.lang.String, int);
ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
ctor public Condition(android.os.Parcel);
@@ -34683,7 +34684,7 @@
method public void onRequestConditions(int);
method public abstract void onSubscribe(android.net.Uri);
method public abstract void onUnsubscribe(android.net.Uri);
- field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
+ field public static final java.lang.String EXTRA_RULE_ID = "android.service.notification.extra.RULE_ID";
field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
@@ -36685,11 +36686,9 @@
package android.telephony {
public class CarrierConfigManager {
- method public android.os.PersistableBundle getConfig(int);
method public android.os.PersistableBundle getConfig();
- method public deprecated android.os.PersistableBundle getConfigForSubId(int);
- method public void notifyConfigChanged(int);
- method public deprecated void notifyConfigChangedForSubId(int);
+ method public android.os.PersistableBundle getConfigForSubId(int);
+ method public void notifyConfigChangedForSubId(int);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
@@ -37840,7 +37839,7 @@
ctor public MockApplication();
}
- public deprecated class MockContentProvider extends android.content.ContentProvider {
+ public class MockContentProvider extends android.content.ContentProvider {
ctor protected MockContentProvider();
ctor public MockContentProvider(android.content.Context);
ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -37852,13 +37851,13 @@
method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
}
- public deprecated class MockContentResolver extends android.content.ContentResolver {
+ public class MockContentResolver extends android.content.ContentResolver {
ctor public MockContentResolver();
ctor public MockContentResolver(android.content.Context);
method public void addProvider(java.lang.String, android.content.ContentProvider);
}
- public deprecated class MockContext extends android.content.Context {
+ public class MockContext extends android.content.Context {
ctor public MockContext();
method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
method public int checkCallingOrSelfPermission(java.lang.String);
@@ -42580,6 +42579,7 @@
method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
method public boolean performAccessibilityAction(int, android.os.Bundle);
method public boolean performClick();
+ method public boolean performContextClick(float, float);
method public boolean performContextClick();
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 42c64ea..0ff2476 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -31,37 +31,6 @@
}
-package android.app.usage {
-
- public class DataUsagePolicy {
- field public final int networkType;
- field public final java.lang.String[] subscriberIds;
- field public final long thresholdInBytes;
- field public final int[] uids;
- }
-
- public static class DataUsagePolicy.Builder {
- ctor public DataUsagePolicy.Builder();
- method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
- method public android.app.usage.DataUsagePolicy.Builder addUid(int);
- method public android.app.usage.DataUsagePolicy build();
- method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
- method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
- }
-
- public class NetworkStatsManager {
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
- method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
- method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
- }
-
- public static abstract class NetworkStatsManager.DataUsageCallback {
- ctor public NetworkStatsManager.DataUsageCallback();
- method public deprecated void onLimitReached();
- }
-
-}
-
package android.content {
public abstract class Context {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 30753c1..7198146b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5007,8 +5007,11 @@
return;
}
}
- throw new AssertionError("chosen locale " + bestLocale + " must be present in LocaleList: "
- + newLocaleList.toLanguageTags());
+
+ // The app may have overridden the LocaleList with its own Locale
+ // (not present in the available list). Push the chosen Locale
+ // to the front of the list.
+ LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
}
private void handleBindApplication(AppBindData data) {
diff --git a/core/java/android/app/usage/DataUsagePolicy.java b/core/java/android/app/usage/DataUsagePolicy.java
deleted file mode 100644
index ee6b60c..0000000
--- a/core/java/android/app/usage/DataUsagePolicy.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Copyright (C) 2016 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.usage;
-
-import android.net.ConnectivityManager;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.IntArray;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Defines a policy for data usage callbacks, made through {@link DataUsagePolicy.Builder} and used
- * to be notified on data usage via {@link NetworkStatsManager#registerDataUsageCallback}.
- * @removed
- */
-public class DataUsagePolicy {
-
- /**
- * Network type to be monitored, as defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} etc.
- */
- public final int networkType;
-
- /**
- * Set of subscriber ids to be monitored for the given network type. May be empty if not
- * applicable.
- * <p>Should not be modified once created.
- */
- public final String[] subscriberIds;
-
- /**
- * Set of UIDs of which to monitor data usage.
- *
- * <p>If not {@code null}, the caller will be notified when any of the uids exceed
- * the given threshold. If empty all uids for which the calling process has access
- * to stats will be monitored.
- * <p>Should not be modified once created.
- */
- public final int[] uids;
-
- /**
- * Threshold in bytes to be notified on.
- */
- public final long thresholdInBytes;
-
- /**
- * @hide
- */
- DataUsagePolicy(int networkType, String[] subscriberIds, int[] uids,
- long thresholdInBytes) {
- this.networkType = networkType;
- this.subscriberIds = subscriberIds;
- this.uids = uids;
- this.thresholdInBytes = thresholdInBytes;
- }
-
- /**
- * Builder used to create {@link DataUsagePolicy} objects.
- */
- public static class Builder {
- private static final int INVALID_NETWORK_TYPE = -1;
- private int mNetworkType = INVALID_NETWORK_TYPE;
- private List<String> mSubscriberList = new ArrayList<>();
- private IntArray mUids = new IntArray();
- private long mThresholdInBytes;
-
- /**
- * Default constructor for Builder.
- */
- public Builder() {}
-
- /**
- * Build {@link DataUsagePolicy} given the current policies.
- */
- public DataUsagePolicy build() {
- if (mNetworkType == INVALID_NETWORK_TYPE) {
- throw new IllegalArgumentException(
- "DataUsagePolicy requires a valid network type to be set");
- }
- return new DataUsagePolicy(mNetworkType,
- mSubscriberList.toArray(new String[mSubscriberList.size()]),
- mUids.toArray(), mThresholdInBytes);
- }
-
- /**
- * Specifies that the given {@code subscriberId} should be monitored.
- *
- * @param subscriberId the subscriber id of the network interface.
- */
- public Builder addSubscriberId(String subscriberId) {
- mSubscriberList.add(subscriberId);
- return this;
- }
-
- /**
- * Specifies that the given {@code uid} should be monitored.
- */
- public Builder addUid(int uid) {
- mUids.add(uid);
- return this;
- }
-
- /**
- * Specifies that the callback should monitor the given network. It is mandatory
- * to set one.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE},
- * {@link ConnectivityManager#TYPE_WIFI}, etc.
- */
- public Builder setNetworkType(int networkType) {
- mNetworkType = networkType;
- return this;
- }
-
- /**
- * Sets the threshold in bytes on which the listener should be called. The framework may
- * impose a minimum threshold to avoid too many notifications to be triggered.
- */
- public Builder setThreshold(long thresholdInBytes) {
- mThresholdInBytes = thresholdInBytes;
- return this;
- }
- }
-
- @Override
- public String toString() {
- return "DataUsagePolicy [ networkType=" + networkType
- + ", subscriberIds=" + Arrays.toString(subscriberIds)
- + ", uids=" + Arrays.toString(uids)
- + ", thresholdInBytes=" + thresholdInBytes + " ]";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof DataUsagePolicy == false) return false;
- DataUsagePolicy that = (DataUsagePolicy) obj;
- return that.networkType == this.networkType
- && Arrays.deepEquals(that.subscriberIds, this.subscriberIds)
- && Arrays.equals(that.uids, this.uids)
- && that.thresholdInBytes == this.thresholdInBytes;
- }
-
- @Override
- public int hashCode() {
- // Start with a non-zero constant.
- int result = 17;
-
- // Include a hash for each field.
- result = 31 * result + networkType;
- result = 31 * result + Arrays.deepHashCode(subscriberIds);
- result = 31 * result + Arrays.hashCode(uids);
- result = 31 * result + (int) (thresholdInBytes ^ (thresholdInBytes >>> 32));
-
- return result;
- }
-}
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 4a28117..720c84a 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -240,18 +240,13 @@
* {@link java.lang.System#currentTimeMillis}.
* @param uid UID of app
* @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for no tags.
- * @return Statistics object or null if permissions are insufficient or error happened during
- * statistics collection.
+ * @return Statistics object or null if an error happened during statistics collection.
+ * @throws SecurityException if permissions are insufficient to read network statistics.
*/
public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId,
- long startTime, long endTime, int uid, int tag) {
+ long startTime, long endTime, int uid, int tag) throws SecurityException {
NetworkTemplate template;
- try {
- template = createTemplate(networkType, subscriberId);
- } catch (IllegalArgumentException e) {
- if (DBG) Log.e(TAG, "Cannot create template", e);
- return null;
- }
+ template = createTemplate(networkType, subscriberId);
NetworkStats result;
try {
@@ -303,17 +298,6 @@
return result;
}
- /** @removed */
- public void registerDataUsageCallback(DataUsagePolicy policy, DataUsageCallback callback,
- @Nullable Handler handler) {}
-
- /** @removed */
- public void registerDataUsageCallback(DataUsagePolicy policy, UsageCallback callback,
- @Nullable Handler handler) {}
-
- /** @removed */
- public void unregisterDataUsageCallback(DataUsageCallback callback) {}
-
/**
* Registers to receive notifications about data usage on specified networks.
*
@@ -396,13 +380,6 @@
}
}
- /** @removed */
- public static abstract class DataUsageCallback {
- /** @removed */
- @Deprecated
- public void onLimitReached() {}
- }
-
/**
* Base class for usage callbacks. Should be extended by applications wanting notifications.
*/
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a43d06e..b758868 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1415,6 +1415,8 @@
* this context. This is typically used to migrate data between storage
* locations after an upgrade, such as migrating to device protected
* storage.
+ * <p>
+ * The database must be closed before being moved.
*
* @param sourceContext The source context which contains the existing
* database to move.
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index b6c5c6f..42f5feb 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -334,6 +334,7 @@
*
* @return {@code true} if large transfers should be avoided, otherwise
* {@code false}.
+ * @hide
*/
public boolean isMetered() {
synchronized (this) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7e1fc15..dc7be6b 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -671,7 +671,7 @@
/**
* N is for ¯\_(ツ)_/¯.
*/
- public static final int N = CUR_DEVELOPMENT;
+ public static final int N = 24;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cbe98f7..0bc514e 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2219,19 +2219,37 @@
* @param outConfig Where to place the configuration settings.
*/
public static void getConfiguration(ContentResolver cr, Configuration outConfig) {
- getConfigurationForUser(cr, outConfig, UserHandle.myUserId());
+ adjustConfigurationForUser(cr, outConfig, UserHandle.myUserId(),
+ false /* updateSettingsIfEmpty */);
}
/** @hide */
- public static void getConfigurationForUser(ContentResolver cr, Configuration outConfig,
- int userHandle) {
+ public static void adjustConfigurationForUser(ContentResolver cr, Configuration outConfig,
+ int userHandle, boolean updateSettingsIfEmpty) {
outConfig.fontScale = Settings.System.getFloatForUser(
cr, FONT_SCALE, DEFAULT_FONT_SCALE, userHandle);
if (outConfig.fontScale < 0) {
outConfig.fontScale = DEFAULT_FONT_SCALE;
}
- outConfig.setLocales(LocaleList.forLanguageTags(
- Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle)));
+
+ final String localeValue =
+ Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle);
+ if (localeValue != null) {
+ outConfig.setLocales(LocaleList.forLanguageTags(localeValue));
+ } else {
+ // Do not update configuration with emtpy settings since we need to take over the
+ // locale list of previous user if the settings value is empty. This happens when a
+ // new user is created.
+
+ if (updateSettingsIfEmpty) {
+ // Make current configuration persistent. This is necessary the first time a
+ // user log in. At the first login, the configuration settings are empty, so we
+ // need to store the adjusted configuration as the initial settings.
+ Settings.System.putStringForUser(
+ cr, SYSTEM_LOCALES, outConfig.getLocales().toLanguageTags(),
+ userHandle);
+ }
+ }
}
/**
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index 0163b47..447afe6 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -33,7 +33,7 @@
* {@link ConditionProviderService} that owns the rule. Used to tell the system to enter Do Not
* Disturb mode and request that the system exit Do Not Disturb mode.
*/
-public class Condition implements Parcelable {
+public final class Condition implements Parcelable {
@SystemApi
public static final String SCHEME = "condition";
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 44c3887..9d4b0a4 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -95,7 +95,7 @@
/**
* A String rule id extra passed to {@link #META_DATA_CONFIGURATION_ACTIVITY}.
*/
- public static final String EXTRA_RULE_ID = "android.content.automatic.ruleId";
+ public static final String EXTRA_RULE_ID = "android.service.notification.extra.RULE_ID";
/**
* Called when this service is connected.
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 7b01267..b4131b4 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -46,7 +46,7 @@
boolean allLayers, boolean useIdentityTransform);
private static native void nativeOpenTransaction();
- private static native void nativeCloseTransaction();
+ private static native void nativeCloseTransaction(boolean sync);
private static native void nativeSetAnimationTransaction();
private static native void nativeSetLayer(long nativeObject, int zorder);
@@ -372,7 +372,11 @@
/** end a transaction */
public static void closeTransaction() {
- nativeCloseTransaction();
+ nativeCloseTransaction(false);
+ }
+
+ public static void closeTransactionSync() {
+ nativeCloseTransaction(true);
}
public void deferTransactionUntil(IBinder handle, long frame) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2269282..f1f4964 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5698,6 +5698,18 @@
/**
* Call this view's OnContextClickListener, if it is defined.
*
+ * @param x the x coordinate of the context click
+ * @param y the y coordinate of the context click
+ * @return True if there was an assigned OnContextClickListener that consumed the event, false
+ * otherwise.
+ */
+ public boolean performContextClick(float x, float y) {
+ return performContextClick();
+ }
+
+ /**
+ * Call this view's OnContextClickListener, if it is defined.
+ *
* @return True if there was an assigned OnContextClickListener that consumed the event, false
* otherwise.
*/
@@ -10044,7 +10056,7 @@
if (isContextClickable() && !mInContextButtonPress && !mHasPerformedLongPress
&& (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY
|| actionButton == MotionEvent.BUTTON_SECONDARY)) {
- if (performContextClick()) {
+ if (performContextClick(event.getX(), event.getY())) {
mInContextButtonPress = true;
setPressed(true, event.getX(), event.getY());
removeTapCallback();
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index d0d4507..52f35de 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -16,6 +16,7 @@
package android.view.accessibility;
+import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -101,8 +102,9 @@
/**
* Gets the title of the window.
*
- * @return The title.
+ * @return The title of the window, or {@code null} if none is available.
*/
+ @Nullable
public CharSequence getTitle() {
return mTitle;
}
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 66896ab..ac44033 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.annotation.AttrRes;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -27,17 +29,16 @@
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.icu.util.Calendar;
+import android.icu.util.TimeZone;
import android.util.AttributeSet;
import android.util.Log;
-import com.android.internal.R;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
-import java.util.TimeZone;
/**
* This class is a calendar widget for displaying and selecting dates. The
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index f540479..2b91713 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -27,6 +27,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.icu.util.Calendar;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -37,7 +38,6 @@
import android.view.View;
import android.view.ViewGroup;
-import java.util.Calendar;
import java.util.Locale;
import libcore.icu.LocaleData;
diff --git a/core/java/android/widget/CalendarViewMaterialDelegate.java b/core/java/android/widget/CalendarViewMaterialDelegate.java
index 0ed75d5..07b2000 100644
--- a/core/java/android/widget/CalendarViewMaterialDelegate.java
+++ b/core/java/android/widget/CalendarViewMaterialDelegate.java
@@ -18,11 +18,10 @@
import android.annotation.StyleRes;
import android.content.Context;
+import android.icu.util.Calendar;
import android.util.AttributeSet;
import android.widget.DayPickerView.OnDaySelectedListener;
-import java.util.Calendar;
-
class CalendarViewMaterialDelegate extends CalendarView.AbstractCalendarViewDelegate {
private final DayPickerView mDayPickerView;
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 0c5edc5..8613f99 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -16,11 +16,15 @@
package android.widget;
+import com.android.internal.R;
+
import android.annotation.Nullable;
import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.icu.util.Calendar;
+import android.icu.util.TimeZone;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -28,11 +32,7 @@
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
-import com.android.internal.R;
-
-import java.util.Calendar;
import java.util.Locale;
-import java.util.TimeZone;
/**
* Provides a widget for selecting a date.
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 0a23b34..2fd52b5 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -26,6 +26,7 @@
import android.content.res.TypedArray;
import android.icu.text.DisplayContext;
import android.icu.text.SimpleDateFormat;
+import android.icu.util.Calendar;
import android.os.Parcelable;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
@@ -40,7 +41,6 @@
import android.widget.DayPickerView.OnDaySelectedListener;
import android.widget.YearPickerView.OnYearSelectedListener;
-import java.util.Calendar;
import java.util.Locale;
/**
@@ -432,7 +432,8 @@
public void setMinDate(long minDate) {
mTempDate.setTimeInMillis(minDate);
if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+ && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) {
+ // Same day, no-op.
return;
}
if (mCurrentDate.before(mTempDate)) {
@@ -453,7 +454,8 @@
public void setMaxDate(long maxDate) {
mTempDate.setTimeInMillis(maxDate);
if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+ && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+ // Same day, no-op.
return;
}
if (mCurrentDate.after(mTempDate)) {
diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java
index d8a3c56..1a6d351 100644
--- a/core/java/android/widget/DatePickerSpinnerDelegate.java
+++ b/core/java/android/widget/DatePickerSpinnerDelegate.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.icu.util.Calendar;
import android.os.Parcelable;
import android.text.InputType;
import android.text.TextUtils;
@@ -37,7 +38,6 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
-import java.util.Calendar;
import java.util.Locale;
import libcore.icu.ICU;
@@ -288,7 +288,8 @@
public void setMinDate(long minDate) {
mTempDate.setTimeInMillis(minDate);
if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+ && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) {
+ // Same day, no-op.
return;
}
mMinDate.setTimeInMillis(minDate);
@@ -311,7 +312,8 @@
public void setMaxDate(long maxDate) {
mTempDate.setTimeInMillis(maxDate);
if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+ && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+ // Same day, no-op.
return;
}
mMaxDate.setTimeInMillis(maxDate);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 97936e7..9f02b44 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -25,14 +25,13 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.icu.util.Calendar;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleMonthView.OnDayClickListener;
-import java.util.Calendar;
-
/**
* An adapter for a list of {@link android.widget.SimpleMonthView} items.
*/
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index dc772fb..ab89c1f 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.icu.util.Calendar;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -31,7 +32,6 @@
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
-import java.util.Calendar;
import java.util.Locale;
import libcore.icu.LocaleData;
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 97d834a..588425f 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -32,6 +32,7 @@
import android.graphics.Typeface;
import android.icu.text.DisplayContext;
import android.icu.text.SimpleDateFormat;
+import android.icu.util.Calendar;
import android.os.Bundle;
import android.text.TextPaint;
import android.text.format.DateFormat;
@@ -48,7 +49,6 @@
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import java.text.NumberFormat;
-import java.util.Calendar;
import java.util.Locale;
import libcore.icu.LocaleData;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fc120eb..3711b94 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6983,14 +6983,19 @@
return false;
}
- private static int desired(Layout layout) {
+ private static int desired(Layout layout, int maxLines) {
int n = layout.getLineCount();
CharSequence text = layout.getText();
float max = 0;
+ // if maxLines is set, and the text length is greater that the length of the text in the
+ // layout, it means that there is a cut-off and we cannot use it.
+ if (maxLines != -1 && text.length() > layout.getLineEnd(n - 1)) {
+ return -1;
+ }
+
// if any line was wrapped, we can't use it.
// but it's ok for the last line not to have a newline
-
for (int i = 0; i < n - 1; i++) {
if (text.charAt(layout.getLineEnd(i) - 1) != '\n')
return -1;
@@ -7063,7 +7068,7 @@
width = widthSize;
} else {
if (mLayout != null && mEllipsize == null) {
- des = desired(mLayout);
+ des = desired(mLayout, getMaxLines());
}
if (des < 0) {
@@ -7095,7 +7100,7 @@
int hintWidth;
if (mHintLayout != null && mEllipsize == null) {
- hintDes = desired(mHintLayout);
+ hintDes = desired(mHintLayout, getMaxLines());
}
if (hintDes < 0) {
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 96624d2..a3f5a67 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -16,18 +16,17 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.Resources;
+import android.icu.util.Calendar;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
-import java.util.Calendar;
-
-import com.android.internal.R;
-
/**
* Displays a selectable list of years.
*/
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 5bb8969..4f15ece 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -521,16 +521,22 @@
@Override
public void setTitle(CharSequence title) {
+ setTitle(title, true);
+ }
+
+ public void setTitle(CharSequence title, boolean updateAccessibilityTitle) {
if (mTitleView != null) {
mTitleView.setText(title);
} else if (mDecorContentParent != null) {
mDecorContentParent.setWindowTitle(title);
}
mTitle = title;
- WindowManager.LayoutParams params = getAttributes();
- if (!TextUtils.equals(title, params.accessibilityTitle)) {
- params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
- dispatchWindowAttributesChanged(getAttributes());
+ if (updateAccessibilityTitle) {
+ WindowManager.LayoutParams params = getAttributes();
+ if (!TextUtils.equals(title, params.accessibilityTitle)) {
+ params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
+ dispatchWindowAttributesChanged(getAttributes());
+ }
}
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 864a0bf..a9ed9dc 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -223,8 +223,9 @@
SurfaceComposerClient::openGlobalTransaction();
}
-static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
- SurfaceComposerClient::closeGlobalTransaction();
+
+static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
+ SurfaceComposerClient::closeGlobalTransaction(sync);
}
static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
@@ -649,7 +650,7 @@
(void*)nativeScreenshot },
{"nativeOpenTransaction", "()V",
(void*)nativeOpenTransaction },
- {"nativeCloseTransaction", "()V",
+ {"nativeCloseTransaction", "(Z)V",
(void*)nativeCloseTransaction },
{"nativeSetAnimationTransaction", "()V",
(void*)nativeSetAnimationTransaction },
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 30e23f5..e190bd1 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -22,296 +22,120 @@
<!-- Do not translate. These are all of the drawable resources that should be preloaded by
the zygote process before it starts forking application processes. -->
<array name="preloaded_drawables">
- <item>@drawable/toast_frame</item>
- <item>@drawable/btn_check_on_pressed_holo_light</item>
- <item>@drawable/btn_check_on_pressed_holo_dark</item>
- <item>@drawable/btn_check_on_holo_light</item>
- <item>@drawable/btn_check_on_holo_dark</item>
- <item>@drawable/btn_check_on_focused_holo_light</item>
- <item>@drawable/btn_check_on_focused_holo_dark</item>
- <item>@drawable/btn_check_on_disabled_holo_light</item>
- <item>@drawable/btn_check_on_disabled_holo_dark</item>
- <item>@drawable/btn_check_on_disabled_focused_holo_light</item>
- <item>@drawable/btn_check_on_disabled_focused_holo_dark</item>
- <item>@drawable/btn_check_off_pressed_holo_light</item>
- <item>@drawable/btn_check_off_pressed_holo_dark</item>
- <item>@drawable/btn_check_off_holo_light</item>
- <item>@drawable/btn_check_off_holo_dark</item>
- <item>@drawable/btn_check_off_focused_holo_light</item>
- <item>@drawable/btn_check_off_focused_holo_dark</item>
- <item>@drawable/btn_check_off_disabled_holo_light</item>
- <item>@drawable/btn_check_off_disabled_holo_dark</item>
- <item>@drawable/btn_check_off_disabled_focused_holo_light</item>
- <item>@drawable/btn_check_off_disabled_focused_holo_dark</item>
- <item>@drawable/btn_check_holo_light</item>
- <item>@drawable/btn_check_holo_dark</item>
- <item>@drawable/btn_radio_on_pressed_holo_light</item>
- <item>@drawable/btn_radio_on_pressed_holo_dark</item>
- <item>@drawable/btn_radio_on_holo_light</item>
- <item>@drawable/btn_radio_on_holo_dark</item>
- <item>@drawable/btn_radio_on_focused_holo_light</item>
- <item>@drawable/btn_radio_on_focused_holo_dark</item>
- <item>@drawable/btn_radio_on_disabled_holo_light</item>
- <item>@drawable/btn_radio_on_disabled_holo_dark</item>
- <item>@drawable/btn_radio_on_disabled_focused_holo_light</item>
- <item>@drawable/btn_radio_on_disabled_focused_holo_dark</item>
- <item>@drawable/btn_radio_off_pressed_holo_light</item>
- <item>@drawable/btn_radio_off_pressed_holo_dark</item>
- <item>@drawable/btn_radio_off_holo_light</item>
- <item>@drawable/btn_radio_off_holo_dark</item>
- <item>@drawable/btn_radio_off_focused_holo_light</item>
- <item>@drawable/btn_radio_off_focused_holo_dark</item>
- <item>@drawable/btn_radio_off_disabled_holo_light</item>
- <item>@drawable/btn_radio_off_disabled_holo_dark</item>
- <item>@drawable/btn_radio_off_disabled_focused_holo_light</item>
- <item>@drawable/btn_radio_off_disabled_focused_holo_dark</item>
- <item>@drawable/btn_default_pressed_holo_light</item>
- <item>@drawable/btn_default_pressed_holo_dark</item>
- <item>@drawable/btn_default_normal_holo_light</item>
- <item>@drawable/btn_default_normal_holo_dark</item>
- <item>@drawable/btn_default_focused_holo_light</item>
- <item>@drawable/btn_default_focused_holo_dark</item>
- <item>@drawable/btn_default_disabled_holo_light</item>
- <item>@drawable/btn_default_disabled_holo_dark</item>
- <item>@drawable/btn_default_disabled_focused_holo_light</item>
- <item>@drawable/btn_default_disabled_focused_holo_dark</item>
- <item>@drawable/btn_default_holo_dark</item>
- <item>@drawable/btn_default_holo_light</item>
- <item>@drawable/edit_text_holo_light</item>
- <item>@drawable/edit_text_holo_dark</item>
- <item>@drawable/text_cursor_holo_light</item>
- <item>@drawable/text_cursor_holo_dark</item>
- <item>@drawable/text_edit_paste_window</item>
- <item>@drawable/expander_close_holo_dark</item>
- <item>@drawable/expander_close_holo_light</item>
- <item>@drawable/expander_group_holo_dark</item>
- <item>@drawable/expander_group_holo_light</item>
- <item>@drawable/list_selector_holo_dark</item>
- <item>@drawable/list_selector_holo_light</item>
- <item>@drawable/list_section_divider_holo_light</item>
- <item>@drawable/list_section_divider_holo_dark</item>
- <item>@drawable/menu_dropdown_panel_holo_light</item>
- <item>@drawable/menu_dropdown_panel_holo_dark</item>
- <item>@drawable/menu_panel_holo_light</item>
- <item>@drawable/menu_panel_holo_dark</item>
- <item>@drawable/spinner_16_outer_holo</item>
- <item>@drawable/spinner_16_inner_holo</item>
- <item>@drawable/spinner_48_outer_holo</item>
- <item>@drawable/spinner_48_inner_holo</item>
- <item>@drawable/progress_bg_holo_dark</item>
- <item>@drawable/progress_bg_holo_light</item>
- <item>@drawable/progress_horizontal_holo_dark</item>
- <item>@drawable/progress_horizontal_holo_light</item>
- <item>@drawable/progress_large_holo</item>
- <item>@drawable/progress_medium_holo</item>
- <item>@drawable/progress_primary_holo_dark</item>
- <item>@drawable/progress_primary_holo_light</item>
- <item>@drawable/progress_secondary_holo_dark</item>
- <item>@drawable/progress_secondary_holo_light</item>
- <item>@drawable/progress_small_holo</item>
- <item>@drawable/scrubber_progress_horizontal_holo_dark</item>
- <item>@drawable/scrubber_progress_horizontal_holo_light</item>
- <item>@drawable/background_holo_light</item>
- <item>@drawable/background_holo_dark</item>
- <item>@drawable/screen_background_dark</item>
- <item>@drawable/screen_background_dark_transparent</item>
- <item>@drawable/screen_background_light</item>
- <item>@drawable/screen_background_light_transparent</item>
- <item>@drawable/screen_background_selector_dark</item>
- <item>@drawable/screen_background_selector_light</item>
- <item>@drawable/scrollbar_handle_holo_dark</item>
- <item>@drawable/scrollbar_handle_holo_light</item>
- <item>@drawable/spinner_background_holo_dark</item>
- <item>@drawable/spinner_background_holo_light</item>
- <item>@drawable/spinner_ab_default_holo_dark</item>
- <item>@drawable/spinner_ab_default_holo_light</item>
- <item>@drawable/spinner_ab_disabled_holo_dark</item>
- <item>@drawable/spinner_ab_disabled_holo_light</item>
- <item>@drawable/spinner_ab_focused_holo_dark</item>
- <item>@drawable/spinner_ab_focused_holo_light</item>
- <item>@drawable/spinner_ab_pressed_holo_dark</item>
- <item>@drawable/spinner_ab_pressed_holo_light</item>
- <item>@drawable/spinner_ab_holo_dark</item>
- <item>@drawable/spinner_ab_holo_light</item>
- <item>@drawable/spinner_default_holo_dark</item>
- <item>@drawable/spinner_default_holo_light</item>
- <item>@drawable/spinner_disabled_holo_dark</item>
- <item>@drawable/spinner_disabled_holo_light</item>
- <item>@drawable/spinner_focused_holo_dark</item>
- <item>@drawable/spinner_focused_holo_light</item>
- <item>@drawable/spinner_pressed_holo_dark</item>
- <item>@drawable/spinner_pressed_holo_light</item>
- <item>@drawable/cab_background_bottom_holo_dark</item>
- <item>@drawable/cab_background_top_holo_light</item>
- <item>@drawable/cab_background_bottom_holo_light</item>
- <item>@drawable/ic_cab_done_holo_dark</item>
- <item>@drawable/cab_background_top_holo_dark</item>
- <item>@drawable/ic_cab_done_holo_light</item>
- <item>@drawable/btn_cab_done_default_holo_dark</item>
- <item>@drawable/btn_cab_done_focused_holo_light</item>
- <item>@drawable/btn_cab_done_default_holo_light</item>
- <item>@drawable/btn_cab_done_pressed_holo_dark</item>
- <item>@drawable/btn_cab_done_focused_holo_dark</item>
- <item>@drawable/btn_cab_done_pressed_holo_light</item>
- <item>@drawable/btn_cab_done_holo_light</item>
- <item>@drawable/btn_cab_done_holo_dark</item>
- <item>@drawable/ic_menu_close_clear_cancel</item>
- <item>@drawable/ic_menu_copy_holo_dark</item>
- <item>@drawable/ic_menu_copy_holo_light</item>
- <item>@drawable/ic_menu_cut_holo_dark</item>
- <item>@drawable/ic_menu_cut_holo_light</item>
- <item>@drawable/ic_menu_more</item>
- <item>@drawable/ic_menu_moreoverflow_holo_dark</item>
- <item>@drawable/ic_menu_moreoverflow_holo_light</item>
- <item>@drawable/ic_menu_paste_holo_dark</item>
- <item>@drawable/ic_menu_paste_holo_light</item>
- <item>@drawable/ic_menu_selectall_holo_light</item>
- <item>@drawable/ic_menu_selectall_holo_dark</item>
- <item>@drawable/ic_clear</item>
- <item>@drawable/ic_clear_disabled</item>
- <item>@drawable/ic_clear_normal</item>
- <item>@drawable/ic_search_api_holo_dark</item>
- <item>@drawable/ic_search_api_holo_light</item>
- <item>@drawable/ic_go</item>
- <item>@drawable/ic_voice_search_api_holo_dark</item>
- <item>@drawable/ic_voice_search_api_holo_light</item>
- <item>@drawable/dialog_bottom_holo_dark</item>
- <item>@drawable/dialog_bottom_holo_light</item>
- <item>@drawable/dialog_middle_holo_dark</item>
- <item>@drawable/dialog_middle_holo_light</item>
- <item>@drawable/dialog_top_holo_dark</item>
- <item>@drawable/dialog_top_holo_light</item>
- <item>@drawable/ic_dialog_alert_holo_dark</item>
- <item>@drawable/ic_dialog_alert_holo_light</item>
- <item>@drawable/list_divider_holo_dark</item>
- <item>@drawable/list_divider_holo_light</item>
- <item>@drawable/list_divider_holo_light</item>
- <item>@drawable/ab_transparent_dark_holo</item>
- <item>@drawable/ab_stacked_transparent_dark_holo</item>
- <item>@drawable/ab_bottom_transparent_dark_holo</item>
- <item>@drawable/ab_solid_dark_holo</item>
- <item>@drawable/ab_stacked_solid_dark_holo</item>
- <item>@drawable/ab_bottom_solid_dark_holo</item>
- <item>@drawable/ab_transparent_light_holo</item>
- <item>@drawable/ab_stacked_transparent_light_holo</item>
- <item>@drawable/ab_bottom_transparent_light_holo</item>
- <item>@drawable/ab_solid_light_holo</item>
- <item>@drawable/ab_stacked_solid_light_holo</item>
- <item>@drawable/ab_bottom_solid_light_holo</item>
- <item>@drawable/ab_solid_shadow_holo</item>
- <item>@drawable/item_background_holo_dark</item>
- <item>@drawable/item_background_holo_light</item>
- <item>@drawable/fastscroll_thumb_holo</item>
- <item>@drawable/fastscroll_thumb_pressed_holo</item>
- <item>@drawable/fastscroll_thumb_default_holo</item>
- <item>@drawable/fastscroll_track_holo_dark</item>
- <item>@drawable/fastscroll_track_pressed_holo_dark</item>
- <item>@drawable/fastscroll_track_default_holo_dark</item>
- <item>@drawable/fastscroll_track_holo_light</item>
- <item>@drawable/fastscroll_track_pressed_holo_light</item>
- <item>@drawable/fastscroll_track_default_holo_light</item>
- <item>@drawable/editbox_dropdown_background_dark</item>
- <item>@drawable/textfield_searchview_holo_dark</item>
- <item>@drawable/textfield_searchview_right_holo_dark</item>
- <item>@drawable/textfield_searchview_holo_light</item>
- <item>@drawable/textfield_searchview_right_holo_light</item>
- <item>@drawable/textfield_search_selected_holo_dark</item>
- <item>@drawable/textfield_search_default_holo_dark</item>
- <item>@drawable/textfield_search_right_selected_holo_dark</item>
- <item>@drawable/textfield_search_right_default_holo_dark</item>
- <item>@drawable/textfield_search_selected_holo_light</item>
- <item>@drawable/textfield_search_default_holo_light</item>
- <item>@drawable/textfield_search_right_selected_holo_light</item>
- <item>@drawable/textfield_search_right_default_holo_light</item>
- <item>@drawable/tab_indicator_holo</item>
- <item>@drawable/tab_unselected_holo</item>
- <item>@drawable/tab_selected_holo</item>
- <item>@drawable/tab_unselected_focused_holo</item>
- <item>@drawable/tab_selected_focused_holo</item>
- <item>@drawable/tab_unselected_pressed_holo</item>
- <item>@drawable/tab_selected_pressed_holo</item>
- <item>@drawable/quickcontact_badge_overlay_dark</item>
- <item>@drawable/quickcontact_badge_overlay_normal_dark</item>
- <item>@drawable/quickcontact_badge_overlay_pressed_dark</item>
- <item>@drawable/quickcontact_badge_overlay_light</item>
- <item>@drawable/quickcontact_badge_overlay_normal_light</item>
- <item>@drawable/quickcontact_badge_overlay_pressed_light</item>
-
- <!-- Material assets -->
- <item>@drawable/ab_share_pack_material</item>
- <item>@drawable/ab_solid_shadow_material</item>
- <item>@drawable/activated_background_material</item>
- <item>@drawable/btn_borderless_material</item>
- <item>@drawable/btn_check_material_anim</item>
- <item>@drawable/btn_default_material</item>
- <item>@drawable/btn_radio_material_anim</item>
- <item>@drawable/btn_star_material</item>
- <item>@drawable/btn_toggle_material</item>
- <item>@drawable/cab_background_bottom_material</item>
- <item>@drawable/cab_background_top_material</item>
- <item>@drawable/dialog_background_material</item>
- <item>@drawable/edit_text_material</item>
- <item>@drawable/expander_group_material</item>
- <item>@drawable/fastscroll_label_left_material</item>
- <item>@drawable/fastscroll_label_right_material</item>
- <item>@drawable/fastscroll_thumb_material</item>
- <item>@drawable/fastscroll_track_material</item>
- <item>@drawable/floating_popup_background_dark</item>
- <item>@drawable/floating_popup_background_light</item>
- <item>@drawable/ic_ab_back_material</item>
- <item>@drawable/ic_ab_back_material_dark</item>
- <item>@drawable/ic_ab_back_material_light</item>
- <item>@drawable/ic_clear_material</item>
- <item>@drawable/ic_commit_search_api_material</item>
- <item>@drawable/ic_dialog_alert_material</item>
- <item>@drawable/ic_find_next_material</item>
- <item>@drawable/ic_find_previous_material</item>
- <item>@drawable/ic_go_search_api_material</item>
- <item>@drawable/ic_media_route_connecting_material</item>
- <item>@drawable/ic_media_route_material</item>
- <item>@drawable/ic_menu_copy_material</item>
- <item>@drawable/ic_menu_cut_material</item>
- <item>@drawable/ic_menu_find_material</item>
- <item>@drawable/ic_menu_moreoverflow_material</item>
- <item>@drawable/ic_menu_paste_material</item>
- <item>@drawable/ic_menu_search_material</item>
- <item>@drawable/ic_menu_selectall_material</item>
- <item>@drawable/ic_menu_share_material</item>
- <item>@drawable/ic_search_api_material</item>
- <item>@drawable/ic_voice_search_api_material</item>
- <item>@drawable/item_background_borderless_material</item>
- <item>@drawable/item_background_borderless_material_dark</item>
- <item>@drawable/item_background_borderless_material_light</item>
- <item>@drawable/item_background_material</item>
- <item>@drawable/item_background_material_dark</item>
- <item>@drawable/item_background_material_light</item>
- <item>@drawable/list_divider_material</item>
- <item>@drawable/list_section_divider_material</item>
- <item>@drawable/notification_material_action_background</item>
- <item>@drawable/notification_material_media_action_background</item>
- <item>@drawable/popup_background_material</item>
- <item>@drawable/progress_horizontal_material</item>
- <item>@drawable/progress_indeterminate_horizontal_material</item>
- <item>@drawable/progress_large_material</item>
- <item>@drawable/progress_medium_material</item>
- <item>@drawable/progress_small_material</item>
- <item>@drawable/ratingbar_material</item>
- <item>@drawable/ratingbar_small_material</item>
- <item>@drawable/ratingbar_indicator_material</item>
- <item>@drawable/scrollbar_handle_material</item>
- <item>@drawable/seekbar_thumb_material_anim</item>
- <item>@drawable/seekbar_track_material</item>
- <item>@drawable/spinner_background_material</item>
- <item>@drawable/spinner_textfield_background_material</item>
- <item>@drawable/switch_thumb_material_anim</item>
- <item>@drawable/switch_track_material</item>
- <item>@drawable/tab_indicator_material</item>
- <item>@drawable/text_cursor_material</item>
- <item>@drawable/textfield_search_material</item>
- <item>@drawable/text_select_handle_left_material</item>
- <item>@drawable/text_select_handle_middle_material</item>
- <item>@drawable/text_select_handle_right_material</item>
- <item>@drawable/ic_account_circle</item>
+ <item>@drawable/ab_share_pack_material</item>
+ <item>@drawable/ab_solid_shadow_material</item>
+ <item>@drawable/action_bar_item_background_material</item>
+ <item>@drawable/activated_background_material</item>
+ <item>@drawable/btn_borderless_material</item>
+ <item>@drawable/btn_check_material_anim</item>
+ <item>@drawable/btn_colored_material</item>
+ <item>@drawable/btn_default_material</item>
+ <item>@drawable/btn_group_holo_dark</item>
+ <item>@drawable/btn_group_holo_light</item>
+ <item>@drawable/btn_radio_material_anim</item>
+ <item>@drawable/btn_star_material</item>
+ <item>@drawable/btn_toggle_material</item>
+ <item>@drawable/button_inset</item>
+ <item>@drawable/cab_background_bottom_material</item>
+ <item>@drawable/cab_background_top_material</item>
+ <item>@drawable/control_background_32dp_material</item>
+ <item>@drawable/control_background_40dp_material</item>
+ <item>@drawable/dialog_background_material</item>
+ <item>@drawable/editbox_dropdown_background_dark</item>
+ <item>@drawable/edit_text_material</item>
+ <item>@drawable/expander_group_material</item>
+ <item>@drawable/fastscroll_label_left_material</item>
+ <item>@drawable/fastscroll_label_right_material</item>
+ <item>@drawable/fastscroll_thumb_material</item>
+ <item>@drawable/fastscroll_track_material</item>
+ <item>@drawable/floating_popup_background_dark</item>
+ <item>@drawable/floating_popup_background_light</item>
+ <item>@drawable/gallery_item_background</item>
+ <item>@drawable/ic_ab_back_material</item>
+ <item>@drawable/ic_ab_back_material_dark</item>
+ <item>@drawable/ic_ab_back_material_light</item>
+ <item>@drawable/ic_account_circle</item>
+ <item>@drawable/ic_arrow_drop_right_black_24dp</item>
+ <item>@drawable/ic_clear</item>
+ <item>@drawable/ic_clear_disabled</item>
+ <item>@drawable/ic_clear_material</item>
+ <item>@drawable/ic_clear_normal</item>
+ <item>@drawable/ic_commit_search_api_material</item>
+ <item>@drawable/ic_dialog_alert_material</item>
+ <item>@drawable/ic_find_next_material</item>
+ <item>@drawable/ic_find_previous_material</item>
+ <item>@drawable/ic_go</item>
+ <item>@drawable/ic_go_search_api_material</item>
+ <item>@drawable/ic_media_route_connecting_material</item>
+ <item>@drawable/ic_media_route_material</item>
+ <item>@drawable/ic_menu_close_clear_cancel</item>
+ <item>@drawable/ic_menu_copy_material</item>
+ <item>@drawable/ic_menu_cut_material</item>
+ <item>@drawable/ic_menu_find_material</item>
+ <item>@drawable/ic_menu_more</item>
+ <item>@drawable/ic_menu_moreoverflow_material</item>
+ <item>@drawable/ic_menu_paste_material</item>
+ <item>@drawable/ic_menu_search_material</item>
+ <item>@drawable/ic_menu_selectall_material</item>
+ <item>@drawable/ic_menu_share_material</item>
+ <item>@drawable/ic_search_api_material</item>
+ <item>@drawable/ic_voice_search_api_material</item>
+ <item>@drawable/indicator_check_mark_dark</item>
+ <item>@drawable/indicator_check_mark_light</item>
+ <item>@drawable/item_background_borderless_material</item>
+ <item>@drawable/item_background_borderless_material_dark</item>
+ <item>@drawable/item_background_borderless_material_light</item>
+ <item>@drawable/item_background_material</item>
+ <item>@drawable/item_background_material_dark</item>
+ <item>@drawable/item_background_material_light</item>
+ <item>@drawable/list_choice_background_material</item>
+ <item>@drawable/list_divider_material</item>
+ <item>@drawable/list_section_divider_material</item>
+ <item>@drawable/menu_background_fill_parent_width</item>
+ <item>@drawable/notification_material_action_background</item>
+ <item>@drawable/notification_material_media_action_background</item>
+ <item>@drawable/number_picker_divider_material</item>
+ <item>@drawable/popup_background_material</item>
+ <item>@drawable/popup_inline_error_above_holo_dark</item>
+ <item>@drawable/popup_inline_error_above_holo_light</item>
+ <item>@drawable/popup_inline_error_holo_dark</item>
+ <item>@drawable/popup_inline_error_holo_light</item>
+ <item>@drawable/progress_horizontal_material</item>
+ <item>@drawable/progress_indeterminate_horizontal_material</item>
+ <item>@drawable/progress_large_material</item>
+ <item>@drawable/progress_medium_material</item>
+ <item>@drawable/progress_small_material</item>
+ <item>@drawable/quickcontact_badge_overlay_dark</item>
+ <item>@drawable/quickcontact_badge_overlay_light</item>
+ <item>@drawable/quickcontact_badge_overlay_normal_dark</item>
+ <item>@drawable/quickcontact_badge_overlay_normal_light</item>
+ <item>@drawable/quickcontact_badge_overlay_pressed_dark</item>
+ <item>@drawable/quickcontact_badge_overlay_pressed_light</item>
+ <item>@drawable/ratingbar_indicator_material</item>
+ <item>@drawable/ratingbar_material</item>
+ <item>@drawable/ratingbar_small_material</item>
+ <item>@drawable/screen_background_dark</item>
+ <item>@drawable/screen_background_dark_transparent</item>
+ <item>@drawable/screen_background_light</item>
+ <item>@drawable/screen_background_light_transparent</item>
+ <item>@drawable/screen_background_selector_dark</item>
+ <item>@drawable/screen_background_selector_light</item>
+ <item>@drawable/scrollbar_handle_material</item>
+ <item>@drawable/seekbar_thumb_material_anim</item>
+ <item>@drawable/seekbar_tick_mark_material</item>
+ <item>@drawable/seekbar_track_material</item>
+ <item>@drawable/spinner_background_material</item>
+ <item>@drawable/spinner_textfield_background_material</item>
+ <item>@drawable/switch_thumb_material_anim</item>
+ <item>@drawable/switch_track_material</item>
+ <item>@drawable/tab_indicator_material</item>
+ <item>@drawable/text_cursor_material</item>
+ <item>@drawable/text_edit_paste_window</item>
+ <item>@drawable/textfield_search_material</item>
+ <item>@drawable/text_select_handle_left_material</item>
+ <item>@drawable/text_select_handle_middle_material</item>
+ <item>@drawable/text_select_handle_right_material</item>
+ <item>@drawable/toast_frame</item>
</array>
<!-- Do not translate. These are all of the color state list resources that should be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8e9e978..fee2469 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2726,6 +2726,8 @@
<public type="style" name="Widget.Material.Light.CompoundButton.Switch" />
<public type="style" name="Widget.Material.NumberPicker" />
<public type="style" name="Widget.Material.Light.NumberPicker" />
+ <public type="style" name="TextAppearance.Material.Widget.Button.Colored" />
+ <public type="style" name="TextAppearance.Material.Widget.Button.Borderless.Colored" />
<public type="id" name="accessibilityActionSetProgress" />
<public type="id" name="icon_frame" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 45ee778..2232942 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4318,6 +4318,6 @@
<string name="audit_safemode_notification_details">Touch to learn more.</string>
<!-- Accessibilty string added to a widget that has been suspended [CHAR LIMIT=20] -->
- <string name="suspended_widget_accessibility">Suspended <xliff:g id="label" example="Calendar">%1$s</xliff:g></string>
+ <string name="suspended_widget_accessibility">Disabled <xliff:g id="label" example="Calendar">%1$s</xliff:g></string>
</resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 3ed8daa..bb07834 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -298,6 +298,14 @@
<item name="textColor">?attr/textColorPrimaryInverse</item>
</style>
+ <style name="TextAppearance.Material.Widget.Button.Colored">
+ <item name="textColor">@color/btn_colored_text_material</item>
+ </style>
+
+ <style name="TextAppearance.Material.Widget.Button.Borderless.Colored" parent="TextAppearance.Material.Widget.Button">
+ <item name="textColor">@color/btn_colored_borderless_text_material</item>
+ </style>
+
<style name="TextAppearance.Material.Widget.EditText">
<item name="textColor">?attr/textColorPrimaryInverse</item>
<item name="textColorHint">?attr/textColorHintInverse</item>
@@ -485,8 +493,7 @@
<!-- Colored bordered ink button -->
<style name="Widget.Material.Button.Colored">
<item name="background">@drawable/btn_colored_material</item>
- <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Inverse</item>
- <item name="textColor">@color/btn_colored_text_material</item>
+ <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Colored</item>
</style>
<!-- Small bordered ink button -->
@@ -503,7 +510,7 @@
<!-- Colored borderless ink button -->
<style name="Widget.Material.Button.Borderless.Colored">
- <item name="textColor">@color/btn_colored_borderless_text_material</item>
+ <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Borderless.Colored</item>
</style>
<!-- Alert dialog button bar button -->
diff --git a/docs/html-intl/intl/es/preview/setup-sdk.jd b/docs/html-intl/intl/es/preview/setup-sdk.jd
index 769121d..39e84a8 100644
--- a/docs/html-intl/intl/es/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/es/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
y <a href="{@docRoot}preview/api-overview.html">API y funciones de Android N
</a>.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/in/preview/setup-sdk.jd b/docs/html-intl/intl/in/preview/setup-sdk.jd
index c6e43f1..2502d7d 100644
--- a/docs/html-intl/intl/in/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/in/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
dan <a href="{@docRoot}preview/api-overview.html">Android N API
dan Fiturnya</a>.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ja/preview/setup-sdk.jd b/docs/html-intl/intl/ja/preview/setup-sdk.jd
index 4331641..36c2144 100644
--- a/docs/html-intl/intl/ja/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ja/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ko/preview/setup-sdk.jd b/docs/html-intl/intl/ko/preview/setup-sdk.jd
index 91f17c1..d04acef 100644
--- a/docs/html-intl/intl/ko/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ko/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
및 기능</a>에서 Android N 플랫폼에
대해 자세히 알아봅니다.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/pt-br/preview/setup-sdk.jd b/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
index 9035e50..a917da3 100644
--- a/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
e <a href="{@docRoot}preview/api-overview.html">Recursos de APIs do
Android N</a>.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ru/preview/setup-sdk.jd b/docs/html-intl/intl/ru/preview/setup-sdk.jd
index 582fe9f..6ae86e9 100644
--- a/docs/html-intl/intl/ru/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ru/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
и в описании <a href="{@docRoot}preview/api-overview.html">API-интерфейсов и возможностей Android N</a>.
</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/vi/preview/index.jd b/docs/html-intl/intl/vi/preview/index.jd
index 25289e0..bd64b25 100644
--- a/docs/html-intl/intl/vi/preview/index.jd
+++ b/docs/html-intl/intl/vi/preview/index.jd
@@ -31,7 +31,7 @@
<strong>thông báo trả lời trực tiếp</strong> và nhiều tính năng khác.
</p>
- <a href="http://factoryberlin.com" target="_new">
+ <a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
<span class="dac-sprite dac-auto-chevron"></span>
Bắt đầu
</a><!--<br>
@@ -61,19 +61,19 @@
</a>
<ul class="dac-actions">
<li class="dac-action">
- <a href="http://factoryberlin.com" target="_new">
+ <a class="dac-action-link" href="https://developer.android.com/preview/bug">
<i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
Báo cáo vấn đề
</a>
</li>
<li class="dac-action">
- <a href="http://factoryberlin.com" target="_new">
+ <a class="dac-action-link" href="{@docRoot}preview/support.html">
<i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
Xem ghi chú phát hành
</a>
</li>
<li class="dac-action">
- <a href="http://factoryberlin.com" target="_new">
+ <a class="dac-action-link" href="{@docRoot}preview/dev-community">
<i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
Tham gia cộng đồng nhà phát triển
</a>
@@ -86,15 +86,15 @@
<div class="wrap dac-offset-parent">
<div class="actions">
- <div><a href="http://factoryberlin.com" target="_new">
+ <div><a href="https://developer.android.com/preview/bug">
<span class="dac-sprite dac-auto-chevron-large"></span>
Báo cáo vấn đề
</a></div>
- <div><a href="http://factoryberlin.com" target="_new">
+ <div><a href="{@docRoot}preview/support.html">
<span class="dac-sprite dac-auto-chevron-large"></span>
Xem ghi chú phát hành
</a></div>
- <div><a href="http://factoryberlin.com" target="_new">
+ <div><a href="{@docRoot}preview/dev-community">
<span class="dac-sprite dac-auto-chevron-large"></span>
Tham gia cộng đồng nhà phát triển
</a></div>
diff --git a/docs/html-intl/intl/vi/preview/setup-sdk.jd b/docs/html-intl/intl/vi/preview/setup-sdk.jd
index 6f6cd20..bdba713 100644
--- a/docs/html-intl/intl/vi/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/vi/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
và<a href="{@docRoot}preview/api-overview.html">API Android N
và Các tính năng</a>.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd b/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
index eaef7a1..69971d8 100644
--- a/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1:6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd b/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
index 7a46aca..b486ed4 100644
--- a/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
SHA-1:6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
</td>
</tr>
-<table>
+</table>
@@ -221,4 +221,3 @@
</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 4211c6f..42c8889 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -127,6 +127,8 @@
to: https://developers.google.com/mobile-ads-sdk/
- from: /google/play-services/wallet.html
to: https://developers.google.com/wallet/instant-buy/
+- from: /google/play-services/id.html
+ to: https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
- from: /google/play/safetynet/...
to: /training/safetynet/index.html
- from: /google/gcm/...
diff --git a/docs/html/google/_book.yaml b/docs/html/google/_book.yaml
index 92357e9..885ad7a 100644
--- a/docs/html/google/_book.yaml
+++ b/docs/html/google/_book.yaml
@@ -63,9 +63,6 @@
- title: Google Play Developer API
path: /google/play/developer-api.html
-- title: Advertising ID
- path: /google/play-services/id.html
-
- title: Multiple APK Support
path: /google/play/publishing/multiple-apks.html
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
deleted file mode 100644
index 2f0664c..0000000
--- a/docs/html/google/play-services/id.jd
+++ /dev/null
@@ -1,193 +0,0 @@
-page.title=Advertising ID
-page.tags=Ads,Advertising ID,ID
-
-@jd:body
-<div class="landing-banner">
-
-<div class="col-8">
-<p itemprop="description">
- The advertising ID is a user-specific, unique, resettable ID for advertising,
- provided by Google Play services. It gives users better controls and provides
- developers with a simple, standard system to continue to monetize your apps.
- It is an anonymous identifier for advertising purposes and enables users to
- reset their identifier or opt out of interest-based ads within Google Play
- apps.
-</p>
-<p>
- The advertising ID is accessible through a straightforward API that you can
- implement in your apps. For details, take a look at the <a href=
- "#get_started">overview</a> and the <a href=
- "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/package-summary">
- advertising ID API reference</a>.
-</p>
-</div>
-</div>
-<div class="landing-docs">
- <div class="col-6 normal-links">
- <h3 style="clear:left">Key Developer Features</h3>
- <h4>Standard, simple ID</h4>
- <p>The advertising ID is a part of a standard, simple system for serving ads and performing analytics.</p>
- <h4>Giving users control</h4>
- <p>Users can reset their advertising ID or opt out of interest-based ads at any time, right from the Google Settings app.
- Their preferences apply across all ad companies that use the advertising ID.</p>
-
- </div>
- <div class="col-6 normal-links">
- <h3 style="clear:left">Getting Started</h3>
- <h4>1. Get the Google Play services SDK</h4>
- <p>The advertising ID APIs are part of the Google Play services platform.</p>
- <p>To get started, <a href="https://developers.google.com/android/guides/setup">set up
- the Google Play services SDK</a>. </p>
- <h4>2. Read the docs and example code</h4>
- <p>Once you've installed the Google Play services package, review the <a href="#get_started">overview</a>
- below, as well as the <a href="#example">example</a>.</p>
- <p>
- For detailed documentation, take a look at the <a href=
- "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/package-summary">
- advertising ID API reference documentation</a>.
- </p>
- </div>
-</div>
-<p class="caution" style=
-"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
- As a reminder, please note that starting <strong>1 August 2014</strong>, new
- apps and app updates distributed through Google Play must use the advertising
- ID in lieu of any other persistent identifiers for any advertising purposes,
- on devices that support the advertising ID.<br>
- <br>
- To learn how to check your app's compliance through the Developer Console, or
- for details on the associated developer policy changes, please see the
- <a href=
- "https://support.google.com/googleplay/android-developer/answer/6048248">Advertising
- ID topic</a> in the Google Play developer help center.
-</p>
-<h2 id="get_started">Using the Advertising ID</h2>
-<p>
- The <strong>advertising ID</strong> is a unique but
- user-resettable string identifier that lets ad networks and other apps anonymously
- identify a user. The user's advertising ID is made available to apps through APIs
- provided in Google Play services.
-</p>
-<p>
- Users can reset their advertising ID at any time, right from the Ads section of the
- Google Settings app on their devices. From the same app, users can also
- opt-out of targeted advertising based on the advertising ID by setting the appropriate
- <strong style="white-space:nowrap">ad tracking preference</strong>. When the
- user opts-out of targeted ads, this ad tracking preference is made available
- to apps through a Google Play services API.
-</p>
-<p>
- Apps making use of the advertising ID <strong>must check for and respect</strong> the
- user's ad tracking preference. Also please note that any use of the advertising ID
- must abide by the terms of the <a class="external-link"
- href="http://play.google.com/about/developer-content-policy.html#ADID">Google Play
- Developer Content Policies</a>.
-</p>
-<h3 id="format">Format of the Advertising ID</h3>
-<p>
- Google Play services APIs expose the user's advertising ID as a string format of UUID,
- with values similar to this:
-</p>
-<p style="margin-left:1.5em;"><code>"38400000-8cf0-11bd-b23e-10b96e40000d"</code></p>
-<h3 id="requirements">Requirements</h3>
-<ul>
- <li>The advertising ID APIs are supported in Google Play services 4.0+</li>
- <li>Support for the advertising ID on specific devices is based on their installed versions
- of Google Play services</li>
-</ul>
-<h3 id="obtaining">Obtaining the user's advertising ID and ad tracking preference</h3>
-<p>
- If you want to use the advertising ID in your app, you must first install the Google
- Play services SDK. As noted in the requirements above, you should install the
- SDK for Google Play services 4.0 or higher if you will develop using the advertising ID
- APIs. For information about how to get started, see <a href=
- "https://developers.google.com/android/guides/setup">Setting Up Google Play services</a>.
-</p>
-<p>
- The advertising ID APIs are available in the <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
- <code>com.google.android.gms.ads.identifier</code></a> package in the Google
- Play Services library. To obtain the user's advertising ID and tracking preference,
- call the method
- <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html#getAdvertisingIdInfo(android.content.Context)">
- <code>getAdvertisingIdInfo()</code></a>, which returns an <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
- <code>AdvertisingIdClient.Info</code></a> encapsulating the user's current Advertising ID
- and tracking preference.
-</p>
-<p class="note">
- <strong>Note:</strong> The
- <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html#getAdvertisingIdInfo(android.content.Context)"><code>getAdvertisingIdInfo()</code></a>
- method is a blocking call, so you must not call it on the main (UI) thread.
- If called on the main thread, the method throws
- {@link java.lang.IllegalStateException}.
-</p>
-<p>
- Once you've retrieved the
- <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
- <code>AdvertisingIdClient.Info</code></a>
- object, you can use its <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#getId()">
- <code>getId()</code></a> and <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">
- <code>isLimitAdTrackingEnabled()</code></a> methods to access the advertising ID and
- ad tracking preference.
-</p>
-<table>
-<tr>
-<th>Method</th>
-<th>Description</th>
-</tr>
-<tr>
-<td><code>public String <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#getId()">getId()</a></code></td>
-<td style="white-space:nowrap;">Retrieves the advertising ID.</td>
-</tr>
-<tr>
-<td style="white-space:nowrap;"><code>public boolean <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">isLimitAdTrackingEnabled()</a></code></td>
-<td>Retrieves whether the user has limit ad tracking enabled or not.</td>
-</tr>
-</table>
-<p>
- The advertising ID APIs do not include a "reset" method. Only users can initiate a
- reset of their own advertising IDs, through the Google Settings application.
-</p>
-<p>
- For more information about the advertising ID APIs, see the <a href=
- "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
- reference documentation</a>.
-</p>
-<h3 id="example">Example implementation</h3>
-<p>
- Here's a basic illustration of how you can retrieve the user's advertising ID and ad
- tracking preference in your app:
-</p>
-<pre>
-import com.google.android.gms.ads.identifier.AdvertisingIdClient;
-import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
-import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
-import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
-import java.io.IOException;
-...
-// Do not call this function from the main thread. Otherwise,
-// an IllegalStateException will be thrown.
-public void getIdThread() {
- Info adInfo = null;
- try {
- adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext.getApplicationContext());
- } catch (IOException e) {
- // Unrecoverable error connecting to Google Play services (e.g.,
- // the old version of the service doesn't support getting AdvertisingId).
-
- } catch (GooglePlayServicesAvailabilityException e) {
- // Encountered a recoverable error connecting to Google Play services.
- } catch (GooglePlayServicesNotAvailableException e) {
- // Google Play services is not available entirely.
- }
- final String id = adInfo.getId();
- final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
-}</pre>
diff --git a/docs/html/license.jd b/docs/html/license.jd
index 0f671e2..4f4036b 100644
--- a/docs/html/license.jd
+++ b/docs/html/license.jd
@@ -29,7 +29,9 @@
documentation (code comments) extracted from a source code module that
is licensed under GPLv2 or other license. In those cases, the license
covering the source code module will apply to the documentation
-extracted from it. </p>
+extracted from it. Source code modules that are used in the generation
+of documentation and have licenses that require attribution can be
+found in the <a href="#doclicenses">Documentation Licences section</a> below.</p>
<p>Third-party components of this site such as JavaScript libraries are included in the Android
Open Source Project under the licenses specified by their authors. For information about these
@@ -144,4 +146,102 @@
written attribution in the spirit of the messages above.
</p>
+<h2 id="doclicenses">Documentation Licenses</h2>
+<h3 id="icu">ICU License</h3>
+<p>The Android public API documentation incorporates text from the following source code libraries under the ICU License:</p>
+<ul>
+<li><a href="{@docRoot}reference/android/icu/lang/package-summary.html">android.icu.lang</a></li>
+<li><a href="{@docRoot}reference/android/icu/math/package-summary.html">android.icu.math</a></li>
+<li><a href="{@docRoot}reference/android/icu/text/package-summary.html">android.icu.text</a></li>
+<li><a href="{@docRoot}reference/android/icu/util/package-summary.html">android.icu.util</a></li>
+</ul>
+
+<div class="aside" style="overflow:scroll; height:250px;">
+<p>COPYRIGHT AND PERMISSION NOTICE</p>
+
+<p>
+Copyright (c) 1995-2015 International Business Machines Corporation and others
+</p>
+<p>
+All rights reserved.
+</p>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies
+of the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+</p>
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM,
+OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+USE OR PERFORMANCE OF THIS SOFTWARE.
+</p>
+<p>
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization of the copyright holder.
+</p>
+</div>
+
+<h3 id="w3c_license">W3C Software and Document Notice and License</h3>
+<p>The Android public API documentation incorporates text from the following source code libraries under the W3C Software and Document Notice and License:</p>
+<ul>
+<li><a href="{@docRoot}reference/org/w3c/dom/package-summary.html">org.w3c.dom</a></li>
+<li><a href="{@docRoot}reference/org/w3c/dom/ls/package-summary.html">org.w3c.dom.ls</a></li>
+</ul>
+
+<div class="aside" style="overflow:scroll; height:250px;">
+<p>This work is being provided by the copyright holders under the following license.</p>
+<h5>License</h5>
+<p>
+ By obtaining and/or copying this work, you (the licensee) agree that you have read, understood,
+ and will comply with the following terms and conditions.
+</p>
+<p>
+ Permission to copy, modify, and distribute this work, with or without modification, for any
+ purpose and without fee or royalty is hereby granted, provided that you include the following on
+ ALL copies of the work or portions thereof, including modifications:
+</p>
+<ul>
+<li>
+ The full text of this NOTICE in a location viewable to users of the redistributed or
+ derivative work.
+</li>
+<li>
+ Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none
+ exist, the W3C Software and Document Short Notice should be included.
+</li>
+<li>
+ Notice of any changes or modifications, through a copyright statement on the new code or document
+ such as "This software or document includes material copied from or derived from [title and URI of
+ the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)."
+</li>
+</ul>
+<h5>Disclaimers</h5>
+<p>
+ THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY
+ PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+</p>
+<p>
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES
+ ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT.
+</p>
+<p>
+ The name and trademarks of copyright holders may NOT be used in advertising or publicity
+ pertaining to the work without specific, written prior permission. Title to copyright in this work
+ will at all times remain with copyright holders.
+</p>
+</div>
</div>
diff --git a/docs/html/preview/features/security-config.jd b/docs/html/preview/features/security-config.jd
index 633c0e5..2706ced 100644
--- a/docs/html/preview/features/security-config.jd
+++ b/docs/html/preview/features/security-config.jd
@@ -18,7 +18,7 @@
</ol>
</li>
<li><a href="#TrustingDebugCa">Debugging-only CAs</a></li>
- <li><a href="#UsesCleartextTraffic">Opting Out of Cleartext Traffic</a></li>
+ <li><a href="#CleartextTrafficPermitted">Opting Out of Cleartext Traffic</a></li>
<li><a href="#CertificatePinning">Pinning Certificates</a></li>
<li><a href="#ConfigInheritance">Configuration Inheritance Behavior</a></li>
<li><a href="#FileFormat">Configuration File Format</a></li>
@@ -72,9 +72,8 @@
<pre>
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
- <application ... >
- <meta-data android:name="android.security.net.config"
- android:resource="@xml/network_security_config" />
+ <application android:networkSecurityConfig="@xml/network_security_config"
+ ... >
...
</application>
</manifest>
@@ -240,7 +239,7 @@
</p>
-<h2 id="UsesCleartextTraffic">Opting Out of Cleartext Traffic</h2>
+<h2 id="CleartextTrafficPermitted">Opting Out of Cleartext Traffic</h2>
<p>
Applications intending to connect to destinations using only secure
@@ -263,7 +262,7 @@
<pre>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
- <domain-config usesCleartextTraffic="false">
+ <domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">secure.example.com</domain>
</domain-config>
</network-security-config>
@@ -436,7 +435,7 @@
<pre class="stx">
<base-config <a href=
-"#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]>
+"#CleartextTrafficPermitted">cleartextTrafficPermitted</a>=["true" | "false"]>
...
</base-config>
</pre>
@@ -463,7 +462,7 @@
</p>
<pre>
-<base-config usesCleartextTraffic="true">
+<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
@@ -471,7 +470,7 @@
</pre>
The default configuration for apps targeting API level 23 and below is:
<pre>
-<base-config usesCleartextTraffic="true">
+<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
@@ -486,7 +485,7 @@
<dl class="xml">
<dt>syntax:</dt>
<dd>
-<pre class="stx"><domain-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]>
+<pre class="stx"><domain-config <a href="#CleartextTrafficPermitted">cleartextTrafficPermitted</a>=["true" | "false"]>
...
</domain-config></pre>
</dd>
diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd
index ebeae74..3b479e2 100644
--- a/docs/html/preview/setup-sdk.jd
+++ b/docs/html/preview/setup-sdk.jd
@@ -98,7 +98,7 @@
SHA-1: 9224bd4445cd7f653c4c294d362ccb195a2101e7
</td>
</tr>
-<table>
+</table>
@@ -189,4 +189,3 @@
and <a href="{@docRoot}preview/api-overview.html">Android N APIs
and Features</a>.</li>
</ul>
-<div class="end-content-title"></div>
diff --git a/docs/html/topic/instant-apps/faqs.jd b/docs/html/topic/instant-apps/faqs.jd
index 0a1f571..bf37241 100644
--- a/docs/html/topic/instant-apps/faqs.jd
+++ b/docs/html/topic/instant-apps/faqs.jd
@@ -63,7 +63,9 @@
<strong>How can developers get involved?</strong>
<br/>
Developers interested in upgrading their Android apps can visit
- <a class="external-link" href="g.co/InstantApps">g.co/InstantApps</a> to
+ <a class="external-link"
+ href="http://g.co/InstantApps">
+ g.co/InstantApps</a> to
sign up. We will be reaching out to interested
developers in the coming months.
</p>
\ No newline at end of file
diff --git a/docs/html/topic/instant-apps/index.jd b/docs/html/topic/instant-apps/index.jd
index d8de0b5..e2da9c5 100644
--- a/docs/html/topic/instant-apps/index.jd
+++ b/docs/html/topic/instant-apps/index.jd
@@ -12,17 +12,8 @@
<!-- Hero section -->
<section class="dac-expand dac-hero dac-section-light">
<div class="wrap">
- <div class="cols dac-hero-content">
-
- <div class="col-1of2 col-push-1of2 dac-hero-figure">
- <div class="dev-bytes-video">
- <iframe width="560" height="350" src=
- "https://www.youtube.com/embed/cosqlfqrpFA" frameborder="0"
- allowfullscreen=""></iframe>
- </div>
- </div>
-
- <div class="col-1of2 col-pull-1of2" style="margin-bottom:40px">
+ <div class="dac-hero-content">
+ <div style="margin-bottom:40px">
<h1>
Android Instant Apps
</h1>
@@ -47,6 +38,11 @@
<a class="landing-button green download-bundle-button" href=
"https://docs.google.com/a/google.com/forms/d/1S3MzsMVIlchLCqyNLaFbv64llxWaf90QSeYLeswco90/viewform"
target="_blank">I'M INTERESTED IN ANDROID INSTANT APPS<br></a>
+ <a class="dac-hero-cta dev-bytes"
+ href="https://www.youtube.com/watch?v=cosqlfqrpFA">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Watch a video about Instant Apps
+ </a>
</p>
</div>
@@ -56,7 +52,7 @@
<!-- Second section -->
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
<div class="cols dac-hero-content">
<div class="col-1of2 dac-hero-figure">
<img src="/images/topic/instant-apps/instant-apps-section-2.png">
@@ -64,7 +60,7 @@
<div class="col-1of2">
<div class="dac-hero-tag"></div>
- <h2 id="section-2">Run Android Apps Without Installation</h2>
+ <h2 id="section-2" class="norule">Run Android Apps Without Installation</h2>
<p class="dac-hero-description">
Android Instant Apps lets you experience beautiful and immersive
apps, with material design and smooth animations, without installing them
@@ -77,9 +73,9 @@
<!-- Third section -->
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
- <h2 id="section-3">Access Apps From Anywhere</h2>
+ <h2 id="section-3" class="norule">Access Apps From Anywhere</h2>
<p>
Get people to your flagship Android experience from links that would
@@ -126,7 +122,7 @@
<!-- Fourth section -->
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
<div class="cols dac-hero-content">
<div class="col-1of2 dac-hero-figure">
<img src="/images/topic/instant-apps/instant-apps-section-4.png">
@@ -134,9 +130,10 @@
<div class="col-1of2">
<div class="dac-hero-tag"></div>
- <h2 id="section-4">Built On Google Play Services</h2>
+ <h2 id="section-4" class="norule">Built On Google Play Services</h2>
<p class="dac-hero-description">
- Take advantage of Google Play services features — like location, identity,
+ Take advantage of Google Play services features — like location,
+ identity,
payments, and Firebase — which are built right in for a seamless user
experience.
</p>
@@ -147,17 +144,16 @@
<!-- Fifth section -->
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
<div class="cols dac-hero-content">
<div class="col-1of2 col-push-1of2 dac-hero-figure">
<img src="/images/topic/instant-apps/instant-apps-section-5.png">
</div>
<div class="col-1of2 col-pull-1of2">
<div class="dac-hero-tag"></div>
- <h2 id="section-5">Works On Most Android Devices</h2>
+ <h2 id="section-5" class="norule">Works On Most Android Devices</h2>
<p class="dac-hero-description">
-
Android Instant Apps can work on Android devices running Android 4.1+
(API Level 16) or higher with Google Play services.
</p>
@@ -168,7 +164,7 @@
<!-- Sixth section -->
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
<div class="cols dac-hero-content">
<div class="col-1of2 dac-hero-figure">
<img src="/images/topic/instant-apps/upgrade-your-app-2x.png">
@@ -176,7 +172,7 @@
<div class="col-1of2">
<div class="dac-hero-tag"></div>
- <h2 id="section-6">Upgrade Your Existing App</h2>
+ <h2 id="section-6" class="norule">Upgrade Your Existing App</h2>
<p class="dac-hero-description">
Android Instant Apps functionality is an upgrade to your existing Android
app, not a new, separate app. It's the same Android APIs, the same
@@ -192,18 +188,18 @@
<!-- Seventh section -->
-<div class="wrap" style="margin-top:60px" id="section-7">
- <h2 id="sign-up-docs" style="margin-bottom: 0px;">
+<div class="wrap sub-section" id="section-7">
+ <h2 id="sign-up-docs" class="dac-section-title norule" style="margin-bottom: 0px;">
Sign up for access to Android Instant Apps documentation
</h2>
- <p>
+ <p class="dac-section-subtitle" style="margin-top:0px">
We’ll let you know if you’re selected for early access
to Android Instant
Apps.
</p>
- <p>
+ <p class="dac-section-subtitle">
<a class="landing-button green download-bundle-button"
href="https://docs.google.com/forms/d/1S3MzsMVIlchLCqyNLaFbv64llxWaf90QSeYLeswco90/viewform"
target="_blank">
@@ -211,7 +207,7 @@
</a>
</p>
- <p style="margin-top:24px">
+ <p class="dac-section-subtitle" style="margin-top:24px">
Check out our <a href="faqs.html">frequently asked questions</a> to find out
more about Android Instant Apps.
</p>
@@ -230,28 +226,14 @@
background: #B0BEC5;
}
- /* Styling and layout for video. */
- .dev-bytes-video {
- margin-top: 30px;
- position: relative;
- padding-bottom: 56.25%; /* 16:9 */
- padding-top: 30px;
- height: 0;
- }
-
- .dev-bytes-video iframe,
- .dev-bytes-video object,
- .dev-bytes-video embed {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- }
-
/* Increase top margin for sections */
- .wrap {
- margin-top: 1.5em;
+ .sub-section {
+ margin-top: 2em;
+ }
+
+ a.dev-bytes {
+ padding-top: 1em;
+ padding-left: 1em;
}
#section-3, #sign-up-docs {
@@ -259,11 +241,6 @@
border-top: 0px;
}
- /* Align the seventh section in the center. */
- #section-7 {
- text-align: center;
- }
-
/* GIF section styling */
.figure-caption {
text-align: center;
diff --git a/docs/html/training/volley/request.jd b/docs/html/training/volley/request.jd
index a2b2ecd..97efc17 100644
--- a/docs/html/training/volley/request.jd
+++ b/docs/html/training/volley/request.jd
@@ -38,7 +38,7 @@
<p>If your expected response is one of these types, you probably won't have to implement a
custom request. This lesson describes how to use these standard request types. For
-information on how to implement your own custom request, see <a href="requests-custom.html">
+information on how to implement your own custom request, see <a href="request-custom.html">
Implementing a Custom Request</a>.</p>
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index c67b008..1864206 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -104,6 +104,9 @@
private Rect mHotspotBounds;
private boolean mMutated;
+ private boolean mSuspendChildInvalidation;
+ private boolean mChildRequestedInvalidation;
+
/**
* Creates a new layer drawable with the list of specified layers.
*
@@ -944,9 +947,37 @@
return mLayerState.mPaddingMode;
}
+ /**
+ * Temporarily suspends child invalidation.
+ *
+ * @see #resumeChildInvalidation()
+ */
+ private void suspendChildInvalidation() {
+ mSuspendChildInvalidation = true;
+ }
+
+ /**
+ * Resumes child invalidation after suspension, immediately performing an
+ * invalidation if one was requested by a child during suspension.
+ *
+ * @see #suspendChildInvalidation()
+ */
+ private void resumeChildInvalidation() {
+ mSuspendChildInvalidation = false;
+
+ if (mChildRequestedInvalidation) {
+ mChildRequestedInvalidation = false;
+ invalidateSelf();
+ }
+ }
+
@Override
public void invalidateDrawable(@NonNull Drawable who) {
- invalidateSelf();
+ if (mSuspendChildInvalidation) {
+ mChildRequestedInvalidation = true;
+ } else {
+ invalidateSelf();
+ }
}
@Override
@@ -1482,6 +1513,15 @@
}
private void updateLayerBounds(Rect bounds) {
+ try {
+ suspendChildInvalidation();
+ updateLayerBoundsInternal(bounds);
+ } finally {
+ resumeChildInvalidation();
+ }
+ }
+
+ private void updateLayerBoundsInternal(Rect bounds) {
int paddingL = 0;
int paddingT = 0;
int paddingR = 0;
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 746e99a..cb8e55f 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -878,11 +878,49 @@
restoreForLayer();
+ // saveLayer will clip & translate the draw contents, so we need
+ // to translate the drawLayer by how much the contents was translated
+ // TODO: Unify this with beginLayerOp so we don't have to calculate this
+ // twice
+ uint32_t layerWidth = (uint32_t) beginLayerOp.unmappedBounds.getWidth();
+ uint32_t layerHeight = (uint32_t) beginLayerOp.unmappedBounds.getHeight();
+
+ auto previous = mCanvasState.currentSnapshot();
+ Vector3 lightCenter = previous->getRelativeLightCenter();
+
+ // Combine all transforms used to present saveLayer content:
+ // parent content transform * canvas transform * bounds offset
+ Matrix4 contentTransform(*(previous->transform));
+ contentTransform.multiply(beginLayerOp.localMatrix);
+ contentTransform.translate(beginLayerOp.unmappedBounds.left,
+ beginLayerOp.unmappedBounds.top);
+
+ Matrix4 inverseContentTransform;
+ inverseContentTransform.loadInverse(contentTransform);
+
+ // map the light center into layer-relative space
+ inverseContentTransform.mapPoint3d(lightCenter);
+
+ // Clip bounds of temporary layer to parent's clip rect, so:
+ Rect saveLayerBounds(layerWidth, layerHeight);
+ // 1) transform Rect(width, height) into parent's space
+ // note: left/top offsets put in contentTransform above
+ contentTransform.mapRect(saveLayerBounds);
+ // 2) intersect with parent's clip
+ saveLayerBounds.doIntersect(previous->getRenderTargetClip());
+ // 3) and transform back
+ inverseContentTransform.mapRect(saveLayerBounds);
+ saveLayerBounds.doIntersect(Rect(layerWidth, layerHeight));
+ saveLayerBounds.roundOut();
+
+ Matrix4 localMatrix(beginLayerOp.localMatrix);
+ localMatrix.translate(saveLayerBounds.left, saveLayerBounds.top);
+
// record the draw operation into the previous layer's list of draw commands
// uses state from the associated beginLayerOp, since it has all the state needed for drawing
LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(
beginLayerOp.unmappedBounds,
- beginLayerOp.localMatrix,
+ localMatrix,
beginLayerOp.localClip,
beginLayerOp.paint,
&(mLayerBuilders[finishedLayerIndex]->offscreenBuffer));
diff --git a/libs/hwui/OpDumper.cpp b/libs/hwui/OpDumper.cpp
index cab93e8..ec9ffde 100644
--- a/libs/hwui/OpDumper.cpp
+++ b/libs/hwui/OpDumper.cpp
@@ -45,5 +45,9 @@
}
}
+const char* OpDumper::opName(const RecordedOp& op) {
+ return sOpNameLut[op.opId];
+}
+
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/OpDumper.h b/libs/hwui/OpDumper.h
index c99b517..a82289c 100644
--- a/libs/hwui/OpDumper.h
+++ b/libs/hwui/OpDumper.h
@@ -26,6 +26,7 @@
class OpDumper {
public:
static void dump(const RecordedOp& op, std::ostream& output, int level = 0);
+ static const char* opName(const RecordedOp& op);
};
}; // namespace uirenderer
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 0f16b15..af1fbd8 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -2025,6 +2025,7 @@
uint32_t layerHeight = 0;
Rect rectClippedBounds;
Matrix4 rectMatrix;
+ Matrix4 drawLayerMatrix;
};
/**
* Constructs a view to hit the temporary layer alpha property implementation:
@@ -2060,6 +2061,7 @@
}
void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
EXPECT_EQ(3, mIndex++);
+ mOutData->drawLayerMatrix = state.computedState.transform;
}
void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
EXPECT_EQ(4, mIndex++);
@@ -2108,6 +2110,9 @@
expected.loadTranslate(0, -2000, 0);
EXPECT_MATRIX_APPROX_EQ(expected, observedData.rectMatrix)
<< "expect content to be translated as part of being clipped";
+ expected.loadTranslate(10, 0, 0);
+ EXPECT_MATRIX_APPROX_EQ(expected, observedData.drawLayerMatrix)
+ << "expect drawLayer to be translated as part of being clipped";
}
RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) {
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 87c6d88..349d67e 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -567,6 +567,34 @@
return false;
}
}
+
+ Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
+ Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL);
+
+ if (profile != null) {
+ if (!supportsProfileLevel(profile, level)) {
+ return false;
+ }
+
+ // If we recognize this profile, check that this format is supported by the
+ // highest level supported by the codec for that profile. (Ignore specified
+ // level beyond the above profile/level check as level is only used as a
+ // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
+ // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
+ // 1080p format is not supported even if codec supports Main Profile Level High,
+ // as Simple Profile does not support 1080p.
+ CodecCapabilities levelCaps = null;
+ int maxLevel = 0;
+ for (CodecProfileLevel pl : profileLevels) {
+ if (pl.profile == profile && pl.level > maxLevel) {
+ maxLevel = pl.level;
+ }
+ }
+ levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
+ if (levelCaps != null && !levelCaps.isFormatSupported(format)) {
+ return false;
+ }
+ }
if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
return false;
}
@@ -579,6 +607,57 @@
return true;
}
+ private static boolean supportsBitrate(
+ Range<Integer> bitrateRange, MediaFormat format) {
+ Map<String, Object> map = format.getMap();
+
+ // consider max bitrate over average bitrate for support
+ Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE);
+ Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE);
+ if (bitrate == null) {
+ bitrate = maxBitrate;
+ } else if (maxBitrate != null) {
+ bitrate = Math.max(bitrate, maxBitrate);
+ }
+
+ if (bitrate != null && bitrate > 0) {
+ return bitrateRange.contains(bitrate);
+ }
+
+ return true;
+ }
+
+ private boolean supportsProfileLevel(int profile, Integer level) {
+ for (CodecProfileLevel pl: profileLevels) {
+ if (pl.profile != profile) {
+ continue;
+ }
+
+ // AAC does not use levels
+ if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+ return true;
+ }
+
+ // H.263 levels are not completely ordered:
+ // Level45 support only implies Level10 support
+ if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
+ if (pl.level != level && pl.level == CodecProfileLevel.H263Level45
+ && level > CodecProfileLevel.H263Level10) {
+ continue;
+ }
+ }
+ if (pl.level >= level) {
+ // if we recognize the listed profile/level, we must also recognize the
+ // profile/level arguments.
+ if (createFromProfileLevel(mMime, profile, pl.level) != null) {
+ return createFromProfileLevel(mMime, profile, level) != null;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
// errors while reading profile levels - accessed from sister capabilities
int mError;
@@ -1004,10 +1083,15 @@
Map<String, Object> map = format.getMap();
Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
+
if (!supports(sampleRate, channels)) {
return false;
}
+ if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+ return false;
+ }
+
// nothing to do for:
// KEY_CHANNEL_MASK: codecs don't get this
// KEY_IS_ADTS: required feature for all AAC decoders
@@ -1310,8 +1394,7 @@
return supports(width, height, null);
}
- private boolean supports(
- Integer width, Integer height, Number rate) {
+ private boolean supports(Integer width, Integer height, Number rate) {
boolean ok = true;
if (ok && width != null) {
@@ -1353,9 +1436,16 @@
Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE);
- // we ignore color-format for now as it is not reliably reported by codec
+ if (!supports(width, height, rate)) {
+ return false;
+ }
- return supports(width, height, rate);
+ if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+ return false;
+ }
+
+ // we ignore color-format for now as it is not reliably reported by codec
+ return true;
}
/* no public constructor */
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 93c595f..33e3957 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -185,12 +185,20 @@
public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
/**
- * A key describing the bitrate in bits/sec.
+ * A key describing the average bitrate in bits/sec.
* The associated value is an integer
*/
public static final String KEY_BIT_RATE = "bitrate";
/**
+ * A key describing the max bitrate in bits/sec.
+ * This is usually over a one-second sliding window (e.g. over any window of one second).
+ * The associated value is an integer
+ * @hide
+ */
+ public static final String KEY_MAX_BIT_RATE = "max-bitrate";
+
+ /**
* A key describing the color format of the content in a video format.
* Constants are declared in {@link android.media.MediaCodecInfo.CodecCapabilities}.
*/
diff --git a/packages/PrintRecommendationService/res/values/donottranslate.xml b/packages/PrintRecommendationService/res/values/donottranslate.xml
index 68effbf..86027cd 100644
--- a/packages/PrintRecommendationService/res/values/donottranslate.xml
+++ b/packages/PrintRecommendationService/res/values/donottranslate.xml
@@ -32,8 +32,15 @@
<item>Hewlett Packard</item>
</string-array>
+ <string-array name="known_print_vendor_info_for_samsung" translatable="false">
+ <item>com.sec.app.samsungprintservice</item>
+ <item>Samsung Electronics</item>
+ <item>Samsung</item>
+ </string-array>
+
<array name="known_print_plugin_vendors" translatable="false">
<item>@array/known_print_vendor_info_for_mopria</item>
<item>@array/known_print_vendor_info_for_hp</item>
+ <item>@array/known_print_vendor_info_for_samsung</item>
</array>
</resources>
diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml
index 97281de..348fcac 100644
--- a/packages/PrintRecommendationService/res/values/strings.xml
+++ b/packages/PrintRecommendationService/res/values/strings.xml
@@ -23,7 +23,7 @@
<string name="plugin_vendor_brother">Brother</string>
<string name="plugin_vendor_canon">Canon</string>
<string name="plugin_vendor_xerox">Xerox</string>
- <string name="plugin_vendor_samsung">Samsung Electronics</string>
+ <string name="plugin_vendor_samsung">Samsung</string>
<string name="plugin_vendor_epson">Epson</string>
<string name="plugin_vendor_konica_minolta">Konica Minolta</string>
<string name="plugin_vendor_fuji">Fuji</string>
diff --git a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
index b7925df..108ea66 100644
--- a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
+++ b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
@@ -51,14 +51,6 @@
</vendor>
<vendor>
- <name>@string/plugin_vendor_samsung</name>
- <package>com.sec.app.samsungprintservice</package>
- <mdns-names>
- <mdns-name>Samsung</mdns-name>
- </mdns-names>
- </vendor>
-
- <vendor>
<name>@string/plugin_vendor_epson</name>
<package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
<mdns-names>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
index 4b4b470..d95654f 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
@@ -25,6 +25,7 @@
import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin;
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
+import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
@@ -74,6 +75,14 @@
" plugin", e);
}
+ try {
+ mPlugins.add(new RemotePrintServicePlugin(new SamsungRecommendationPlugin(this), this,
+ false));
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_samsung) +
+ " plugin", e);
+ }
+
final int numPlugins = mPlugins.size();
for (int i = 0; i < numPlugins; i++) {
try {
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java
new file mode 100644
index 0000000..963e09b
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+import java.util.Map;
+
+public class MDnsUtils {
+ public static final String ATTRIBUTE__TY = "ty";
+ public static final String ATTRIBUTE__PRODUCT = "product";
+ public static final String ATTRIBUTE__USB_MFG = "usb_MFG";
+ public static final String ATTRIBUTE__MFG = "mfg";
+
+ public static String getString(byte[] value) {
+ if (value != null) return new String(value,StandardCharsets.UTF_8);
+ return null;
+ }
+
+ public static boolean isVendorPrinter(NsdServiceInfo networkDevice, String[] vendorValues) {
+
+ Map<String,byte[]> attributes = networkDevice.getAttributes();
+ String product = getString(attributes.get(ATTRIBUTE__PRODUCT));
+ String ty = getString(attributes.get(ATTRIBUTE__TY));
+ String usbMfg = getString(attributes.get(ATTRIBUTE__USB_MFG));
+ String mfg = getString(attributes.get(ATTRIBUTE__MFG));
+ return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues);
+
+ }
+
+ public static String getVendor(NsdServiceInfo networkDevice) {
+ String vendor;
+
+ Map<String,byte[]> attributes = networkDevice.getAttributes();
+ vendor = getString(attributes.get(ATTRIBUTE__MFG));
+ if (!TextUtils.isEmpty(vendor)) return vendor;
+ vendor = getString(attributes.get(ATTRIBUTE__USB_MFG));
+ if (!TextUtils.isEmpty(vendor)) return vendor;
+
+ return null;
+ }
+
+ private static boolean containsVendor(String container, String[] vendorValues) {
+ if ((container == null) || (vendorValues == null)) return false;
+ for (String value : vendorValues) {
+ if (containsString(container, value)
+ || containsString(container.toLowerCase(Locale.US), value.toLowerCase(Locale.US))
+ || containsString(container.toUpperCase(Locale.US), value.toUpperCase(Locale.US)))
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean containsString(String container, String contained) {
+ return (container != null) && (contained != null) && (container.equalsIgnoreCase(contained) || container.contains(contained + " "));
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java
new file mode 100644
index 0000000..032fe22
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdServiceInfo;
+
+import java.util.HashMap;
+
+final class PrinterHashMap extends HashMap<String, NsdServiceInfo> {
+ public static String getKey(NsdServiceInfo serviceInfo) {
+ return serviceInfo.getServiceName();
+ }
+ public NsdServiceInfo addPrinter(NsdServiceInfo device) {
+ return put(getKey(device), device);
+ }
+ public NsdServiceInfo removePrinter(NsdServiceInfo device) {
+ return remove(getKey(device));
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java
new file mode 100644
index 0000000..e5b8a0f
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java
@@ -0,0 +1,102 @@
+/*
+(c) Copyright 2016 Samsung Electronics..
+
+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.printservice.recommendation.plugin.samsung;
+
+import android.content.Context;
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+
+import java.util.Locale;
+import java.util.Map;
+
+import com.android.printservice.recommendation.R;
+
+public class SamsungRecommendationPlugin extends ServiceRecommendationPlugin {
+
+ private static final String TAG = "SamsungRecommendation";
+
+ private static final String ATTR_USB_MFG = "usb_MFG";
+ private static final String ATTR_MFG = "mfg";
+ private static final String ATTR_USB_MDL = "usb_MDL";
+ private static final String ATTR_MDL = "mdl";
+ private static final String ATTR_PRODUCT = "product";
+ private static final String ATTR_TY = "ty";
+
+ private static String[] mNotSupportedDevices = new String[]{
+ "SCX-5x15",
+ "SF-555P",
+ "CF-555P",
+ "SCX-4x16",
+ "SCX-4214F",
+ "CLP-500",
+ "CJX-",
+ "MJC-"
+ };
+
+ private static boolean isSupportedModel(String model) {
+ if (!TextUtils.isEmpty(model)) {
+ String modelToUpper = model.toUpperCase(Locale.US);
+ for (String unSupportedPrinter : mNotSupportedDevices) {
+ if (modelToUpper.contains(unSupportedPrinter)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public SamsungRecommendationPlugin(Context context) {
+ super(context, R.string.plugin_vendor_samsung, new VendorInfo(context.getResources(), R.array.known_print_vendor_info_for_samsung), new String[]{"_pdl-datastream._tcp"});
+ }
+
+ @Override
+ public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) {
+ if (!TextUtils.equals(vendor, mVendorInfo.mVendorID)) return false;
+
+ String modelName = getModelName(nsdServiceInfo);
+ if (modelName != null) {
+ return (isSupportedModel(modelName));
+ }
+ return false;
+ }
+
+ private String getModelName(NsdServiceInfo resolvedDevice) {
+ Map<String,byte[]> attributes = resolvedDevice.getAttributes();
+ String usb_mfg = MDnsUtils.getString(attributes.get(ATTR_USB_MFG));
+ if (TextUtils.isEmpty(usb_mfg)) {
+ usb_mfg = MDnsUtils.getString(attributes.get(ATTR_MFG));
+ }
+
+ String usb_mdl = MDnsUtils.getString(attributes.get(ATTR_USB_MDL));
+ if (TextUtils.isEmpty(usb_mdl)) {
+ usb_mdl = MDnsUtils.getString(attributes.get(ATTR_MDL));
+ }
+
+ String modelName = null;
+ if (!TextUtils.isEmpty(usb_mfg) && !TextUtils.isEmpty(usb_mdl)) {
+ modelName = usb_mfg.trim() + " " + usb_mdl.trim();
+ } else {
+ modelName = MDnsUtils.getString(attributes.get(ATTR_PRODUCT));
+ if (TextUtils.isEmpty(modelName)) {
+ modelName = MDnsUtils.getString(attributes.get(ATTR_TY));
+ }
+ }
+
+ return modelName;
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java
new file mode 100644
index 0000000..7bb83c9
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.printservice.recommendation.R;
+import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
+
+public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
+
+ private final NsdManager mNSDManager;
+ private final Map<String, VendorInfo> mVendorInfoHashMap;
+ private final String[] mServiceType;
+ private final Observer mObserver;
+ private final ServiceResolveQueue mResolveQueue;
+ private List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
+ public HashMap<String, PrinterHashMap> mVendorHashMap = new HashMap<>();
+
+ public interface Observer {
+ boolean matchesCriteria(String vendor, NsdServiceInfo serviceInfo);
+ void dataSetChanged();
+ }
+
+ public ServiceListener(Context context, Observer observer, String[] serviceTypes) {
+ mObserver = observer;
+ mServiceType = serviceTypes;
+ mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
+ mResolveQueue = ServiceResolveQueue.getInstance(mNSDManager);
+
+ Map<String, VendorInfo> vendorInfoMap = new HashMap<>();
+ TypedArray testArray = context.getResources().obtainTypedArray(R.array.known_print_plugin_vendors);
+ for(int i = 0; i < testArray.length(); i++) {
+ int arrayID = testArray.getResourceId(i, 0);
+ if (arrayID != 0) {
+ VendorInfo info = new VendorInfo(context.getResources(), arrayID);
+ vendorInfoMap.put(info.mVendorID, info);
+ vendorInfoMap.put(info.mPackageName, info);
+ }
+ }
+ testArray.recycle();
+ mVendorInfoHashMap = vendorInfoMap;
+ }
+
+ @Override
+ public void serviceResolved(NsdServiceInfo nsdServiceInfo) {
+ printerFound(nsdServiceInfo);
+ }
+
+ private synchronized void printerFound(NsdServiceInfo nsdServiceInfo) {
+ if (nsdServiceInfo == null) return;
+ if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
+ String vendor = MDnsUtils.getVendor(nsdServiceInfo);
+ if (vendor == null) vendor = "";
+ for(Map.Entry<String,VendorInfo> entry : mVendorInfoHashMap.entrySet()) {
+ for(String vendorValues : entry.getValue().mDNSValues) {
+ if (vendor.equalsIgnoreCase(vendorValues)) {
+ vendor = entry.getValue().mVendorID;
+ break;
+ }
+ }
+ // intentional pointer check
+ //noinspection StringEquality
+ if ((vendor != entry.getValue().mVendorID) &&
+ MDnsUtils.isVendorPrinter(nsdServiceInfo, entry.getValue().mDNSValues)) {
+ vendor = entry.getValue().mVendorID;
+ }
+ // intentional pointer check
+ //noinspection StringEquality
+ if (vendor == entry.getValue().mVendorID) break;
+ }
+
+ if (TextUtils.isEmpty(vendor)) {
+ return;
+ }
+
+ if (!mObserver.matchesCriteria(vendor, nsdServiceInfo))
+ return;
+ boolean mapsChanged;
+
+ PrinterHashMap vendorHash = mVendorHashMap.get(vendor);
+ if (vendorHash == null) {
+ vendorHash = new PrinterHashMap();
+ }
+ mapsChanged = (vendorHash.addPrinter(nsdServiceInfo) == null);
+ mVendorHashMap.put(vendor, vendorHash);
+
+ if (mapsChanged) {
+ mObserver.dataSetChanged();
+ }
+ }
+
+ private synchronized void printerRemoved(NsdServiceInfo nsdServiceInfo) {
+ boolean wasRemoved = false;
+ Set<String> vendors = mVendorHashMap.keySet();
+ for(String vendor : vendors) {
+ PrinterHashMap map = mVendorHashMap.get(vendor);
+ wasRemoved |= (map.removePrinter(nsdServiceInfo) != null);
+ if (map.isEmpty()) wasRemoved |= (mVendorHashMap.remove(vendor) != null);
+ }
+ if (wasRemoved) {
+ mObserver.dataSetChanged();
+ }
+ }
+
+ public void start() {
+ stop();
+ for(final String service :mServiceType) {
+ NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
+ @Override
+ public void onStartDiscoveryFailed(String s, int i) {
+
+ }
+
+ @Override
+ public void onStopDiscoveryFailed(String s, int i) {
+
+ }
+
+ @Override
+ public void onDiscoveryStarted(String s) {
+
+ }
+
+ @Override
+ public void onDiscoveryStopped(String s) {
+
+ }
+
+ @Override
+ public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
+ mResolveQueue.queueRequest(nsdServiceInfo, ServiceListener.this);
+ }
+
+ @Override
+ public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
+ mResolveQueue.removeRequest(nsdServiceInfo, ServiceListener.this);
+ printerRemoved(nsdServiceInfo);
+ }
+ };
+ DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
+ mListeners.add(listener);
+ }
+ }
+
+ public void stop() {
+ for(NsdManager.DiscoveryListener listener : mListeners) {
+ DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
+ }
+ mVendorHashMap.clear();
+ mListeners.clear();
+ }
+
+ public Pair<Integer, Integer> getCount() {
+ int count = 0;
+ for (PrinterHashMap map : mVendorHashMap.values()) {
+ count += map.size();
+ }
+ return Pair.create(mVendorHashMap.size(), count);
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java
new file mode 100644
index 0000000..9d15f30
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.annotation.NonNull;
+import android.text.TextUtils;
+import com.android.printservice.recommendation.PrintServicePlugin;
+
+public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, ServiceListener.Observer {
+
+ protected static final String PDL_ATTRIBUTE = "pdl";
+
+ protected final Object mLock = new Object();
+ protected PrinterDiscoveryCallback mCallback = null;
+ protected final ServiceListener mListener;
+ protected final NsdManager mNSDManager;
+ protected final VendorInfo mVendorInfo;
+ private final int mVendorStringID;
+
+ protected ServiceRecommendationPlugin(Context context, int vendorStringID, VendorInfo vendorInfo, String[] services) {
+ mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
+ mVendorStringID = vendorStringID;
+ mVendorInfo = vendorInfo;
+ mListener = new ServiceListener(context, this, services);
+ }
+
+ @Override
+ public int getName() {
+ return mVendorStringID;
+ }
+
+ @NonNull
+ @Override
+ public CharSequence getPackageName() {
+ return mVendorInfo.mPackageName;
+ }
+
+ @Override
+ public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception {
+ synchronized (mLock) {
+ mCallback = callback;
+ }
+ mListener.start();
+ }
+
+ @Override
+ public void stop() throws Exception {
+ synchronized (mLock) {
+ mCallback = null;
+ }
+ mListener.stop();
+ }
+
+ @Override
+ public void dataSetChanged() {
+ synchronized (mLock) {
+ if (mCallback != null) mCallback.onChanged(getCount());
+ }
+ }
+
+ @Override
+ public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) {
+ return TextUtils.equals(vendor, mVendorInfo.mVendorID);
+ }
+
+ public int getCount() {
+ return mListener.getCount().second;
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java
new file mode 100644
index 0000000..e5691b7
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Pair;
+import com.android.printservice.recommendation.util.NsdResolveQueue;
+
+import java.util.LinkedList;
+
+final class ServiceResolveQueue {
+
+ private final NsdManager mNsdManager;
+ private final LinkedList<Pair<NsdServiceInfo, ResolveCallback>> mQueue = new LinkedList<>();
+ private final Object mLock = new Object();
+
+ private static Object sLock = new Object();
+ private static ServiceResolveQueue sInstance = null;
+ private final NsdResolveQueue mNsdResolveQueue;
+ private Pair<NsdServiceInfo, ResolveCallback> mCurrentRequest = null;
+
+ public static void createInstance(NsdManager nsdManager) {
+ if (sInstance == null) sInstance = new ServiceResolveQueue(nsdManager);
+ }
+
+ public static ServiceResolveQueue getInstance(NsdManager nsdManager) {
+ synchronized (sLock) {
+ createInstance(nsdManager);
+ return sInstance;
+ }
+ }
+
+ public static void destroyInstance() {
+ sInstance = null;
+ }
+
+ public interface ResolveCallback {
+ void serviceResolved(NsdServiceInfo nsdServiceInfo);
+ }
+
+ public ServiceResolveQueue(NsdManager nsdManager) {
+ mNsdManager = nsdManager;
+ mNsdResolveQueue = NsdResolveQueue.getInstance();
+ }
+
+ public void queueRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) {
+ synchronized (mLock) {
+ Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback);
+ if (mQueue.contains(newRequest)) return;
+ mQueue.add(newRequest);
+ makeNextRequest();
+ }
+ }
+
+ public void removeRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) {
+ synchronized (mLock) {
+ Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback);
+ mQueue.remove(newRequest);
+ if ((mCurrentRequest != null) && newRequest.equals(mCurrentRequest)) mCurrentRequest = null;
+ }
+ }
+
+ private void makeNextRequest() {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) return;
+ if (mQueue.isEmpty()) return;
+ mCurrentRequest = mQueue.removeFirst();
+ mNsdResolveQueue.resolve(mNsdManager, mCurrentRequest.first,
+ new NsdManager.ResolveListener() {
+ @Override
+ public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
+ makeNextRequest();
+ }
+ }
+
+ @Override
+ public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) {
+ mCurrentRequest.second.serviceResolved(nsdServiceInfo);
+ mCurrentRequest = null;
+ }
+ makeNextRequest();
+ }
+ }
+ });
+
+ }
+ }
+
+
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java
new file mode 100644
index 0000000..0ebb4e4
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.printservice.recommendation.plugin.samsung;
+
+import android.content.res.Resources;
+
+import java.util.Arrays;
+
+public final class VendorInfo {
+
+ public final String mPackageName;
+ public final String mVendorID;
+ public final String[] mDNSValues;
+ public final int mID;
+
+ public VendorInfo(Resources resources, int vendor_info_id) {
+ mID = vendor_info_id;
+ String[] data = resources.getStringArray(vendor_info_id);
+ if ((data == null) || (data.length < 2)) {
+ data = new String[] { null, null };
+ }
+ mPackageName = data[0];
+ mVendorID = data[1];
+ mDNSValues = (data.length > 2) ? Arrays.copyOfRange(data, 2, data.length) : new String[]{};
+ }
+}
diff --git a/packages/PrintSpooler/res/layout/add_printer_list_header.xml b/packages/PrintSpooler/res/layout/add_printer_list_header.xml
index 9eee0c4..488b3ab 100644
--- a/packages/PrintSpooler/res/layout/add_printer_list_header.xml
+++ b/packages/PrintSpooler/res/layout/add_printer_list_header.xml
@@ -24,6 +24,7 @@
android:gravity="start|center_vertical">
<TextView android:id="@+id/text"
- style="?android:attr/listSeparatorTextViewStyle" />
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:textAlignment="viewStart" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-television/recents_on_tv.xml b/packages/SystemUI/res/layout-television/recents_on_tv.xml
index 1dbd1b3..82b9f8c 100644
--- a/packages/SystemUI/res/layout-television/recents_on_tv.xml
+++ b/packages/SystemUI/res/layout-television/recents_on_tv.xml
@@ -40,4 +40,16 @@
android:focusable="true"
android:visibility="visible" />
+ <!-- Placeholder to dismiss during talkback. -->
+ <ImageView
+ android:id="@+id/dismiss_placeholder"
+ android:layout_width="@dimen/recents_tv_dismiss_icon_size"
+ android:layout_height="@dimen/recents_tv_dismiss_icon_size"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="50dp"
+ android:src="@drawable/ic_cancel_white_24dp"
+ android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
+ android:focusable="true"
+ android:visibility="gone" />
+
</com.android.systemui.recents.tv.views.RecentsTvView>
diff --git a/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml b/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
index 36df924..201f47d 100644
--- a/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
+++ b/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
@@ -19,7 +19,6 @@
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
- android:contentDescription="@string/status_bar_recent_inspect_item_title"
android:layout_gravity="center"
android:layout_centerInParent="true"
android:clipToPadding="false"
@@ -50,7 +49,6 @@
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/recents_tv_dismiss_icon_top_margin"
android:layout_marginBottom="@dimen/recents_tv_dismiss_icon_bottom_margin"
- android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
android:alpha="@integer/dismiss_unselected_alpha"
android:src="@drawable/recents_tv_dismiss_icon" />
<TextView
diff --git a/packages/SystemUI/res/layout/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
index 6438564..ca0248e 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel_content.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
@@ -35,6 +35,7 @@
android:importantForAccessibility="no" />
<View
+ android:id="@+id/nav_bar_background"
android:layout_width="match_parent"
android:layout_height="@dimen/navigation_bar_size"
android:layout_gravity="bottom"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 61933b4..4bf85c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -19,6 +19,7 @@
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
+import android.content.res.Configuration;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
@@ -103,6 +104,17 @@
mRecyclerView.setItemAnimator(animator);
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ View navBackdrop = findViewById(R.id.nav_bar_background);
+ if (navBackdrop != null) {
+ boolean shouldShow = newConfig.smallestScreenWidthDp >= 600
+ || newConfig.orientation != Configuration.ORIENTATION_LANDSCAPE;
+ navBackdrop.setVisibility(shouldShow ? View.VISIBLE : View.GONE);
+ }
+ }
+
public void setHost(QSTileHost host) {
mHost = host;
mPhoneStatusBar = host.getPhoneStatusBar();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 61a92b4..60c24d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -286,10 +286,11 @@
private void selectPosition(int position, View v) {
// Remove the placeholder.
mAccessibilityMoving = false;
- move(mAccessibilityFromIndex, position, v);
- mTiles.remove(mEditIndex);
+ mTiles.remove(mEditIndex--);
notifyItemRemoved(mEditIndex - 1);
+ move(mAccessibilityFromIndex, position, v);
updateDividerLocations();
+ notifyDataSetChanged();
saveSpecs(mHost);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 212f179..16b1158 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -81,6 +81,8 @@
private IQSService mService;
private boolean mUnbindImmediate;
private TileChangeListener mChangeListener;
+ // Return value from bindServiceAsUser, determines whether safe to call unbind.
+ private boolean mIsBound;
public TileLifecycleManager(Handler handler, Context context, Intent intent, UserHandle user) {
mContext = context;
@@ -132,7 +134,7 @@
}
if (DEBUG) Log.d(TAG, "Binding service " + mIntent + " " + mUser);
mBindTryCount++;
- mContext.bindServiceAsUser(mIntent, this,
+ mIsBound = mContext.bindServiceAsUser(mIntent, this,
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
mUser);
} else {
@@ -140,7 +142,10 @@
// Give it another chance next time it needs to be bound, out of kindness.
mBindTryCount = 0;
mWrapper = null;
- mContext.unbindService(this);
+ if (mIsBound) {
+ mContext.unbindService(this);
+ mIsBound = false;
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index ecb64f6..1a55958 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -388,6 +388,26 @@
mTaskStackHorizontalGridView.setSelectedPosition(0);
}
+ View dismissPlaceholder = findViewById(R.id.dismiss_placeholder);
+ if (ssp.isTouchExplorationEnabled()) {
+ dismissPlaceholder.setAccessibilityTraversalBefore(R.id.task_list);
+ dismissPlaceholder.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
+ mTaskStackHorizontalGridView.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
+ mTaskStackHorizontalGridView.setAccessibilityTraversalBefore(R.id.pip);
+ dismissPlaceholder.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mTaskStackHorizontalGridView.requestFocus();
+ mTaskStackHorizontalGridView.
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ Task focusedTask = mTaskStackHorizontalGridView.getFocusedTask();
+ if (focusedTask != null) {
+ mTaskStackViewAdapter.removeTask(focusedTask);
+ EventBus.getDefault().send(new DeleteTaskDataEvent(focusedTask));
+ }
+ }
+ });
+ }
updatePipUI();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index b082658..06b2441 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -54,6 +54,7 @@
private TaskStack mStack;
private TaskStackHorizontalGridView mTaskStackHorizontalView;
private View mEmptyView;
+ private View mDismissPlaceholder;
private RecentsRowFocusAnimationHolder mEmptyViewFocusAnimationHolder;
private boolean mAwaitingFirstLayout = true;
private Rect mSystemInsets = new Rect();
@@ -86,6 +87,12 @@
mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler);
}
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mDismissPlaceholder = findViewById(R.id.dismiss_placeholder);
+ }
+
public void setTaskStack(TaskStack stack) {
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
@@ -198,6 +205,9 @@
public void showEmptyView() {
mEmptyView.setVisibility(View.VISIBLE);
mTaskStackHorizontalView.setVisibility(View.GONE);
+ if (Recents.getSystemServices().isTouchExplorationEnabled()) {
+ mDismissPlaceholder.setVisibility(View.GONE);
+ }
}
/**
@@ -206,6 +216,9 @@
public void hideEmptyView() {
mEmptyView.setVisibility(View.GONE);
mTaskStackHorizontalView.setVisibility(View.VISIBLE);
+ if (Recents.getSystemServices().isTouchExplorationEnabled()) {
+ mDismissPlaceholder.setVisibility(View.VISIBLE);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index bd85748..758f93a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -88,22 +88,10 @@
R.dimen.recents_task_view_rounded_corners_radius);
mRecentsRowFocusAnimationHolder = new RecentsRowFocusAnimationHolder(this, title);
SystemServicesProxy ssp = Recents.getSystemServices();
- if (ssp.isTouchExplorationEnabled()) {
- mDismissIconView.setFocusable(true);
- mDismissIconView.setFocusableInTouchMode(true);
- mDismissIconView.setOnFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- setDismissState(true);
- } else {
- setDismissState(false);
- }
- }
- });
+ if (!ssp.isTouchExplorationEnabled()) {
+ mDismissIconView.setVisibility(VISIBLE);
} else {
- mDismissIconView.setFocusable(false);
- mDismissIconView.setFocusableInTouchMode(false);
+ mDismissIconView.setVisibility(GONE);
}
mViewFocusAnimator = new ViewFocusAnimator(this);
}
@@ -113,6 +101,7 @@
mTitleTextView.setText(task.title);
mBadgeView.setImageDrawable(task.icon);
setThumbnailView();
+ setContentDescription(task.titleDescription);
}
public Task getTask() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 32b61cd..f3c666f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -263,6 +263,7 @@
invalidateOutline();
selectLayout(false /* animate */, mForceSelectNextLayout /* force */);
mForceSelectNextLayout = false;
+ updateExpandButtons(mExpandable);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 4e643f0..7d3da1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -463,9 +463,7 @@
mTransformedView.animate().cancel();
mTransformedView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
mTransformedView.setAlpha(visible ? 1.0f : 0.0f);
- if (visible) {
- resetTransformedView();
- }
+ resetTransformedView();
}
public void prepareFadeIn() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6a37099..522f250 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -220,6 +220,20 @@
super.onFinishInflate();
mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
+ mClockView = (TextView) findViewById(R.id.clock_view);
+
+ mNotificationContainerParent = (NotificationsQuickSettingsContainer)
+ findViewById(R.id.notification_container_parent);
+ mNotificationStackScroller = (NotificationStackScrollLayout)
+ findViewById(R.id.notification_stack_scroller);
+ mNotificationStackScroller.setOnHeightChangedListener(this);
+ mNotificationStackScroller.setOverscrollTopChangedListener(this);
+ mNotificationStackScroller.setOnEmptySpaceClickListener(this);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
+ mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
+ mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
+ mLastOrientation = getResources().getConfiguration().orientation;
+
mQsAutoReinflateContainer =
(AutoReinflateContainer) findViewById(R.id.qs_auto_reinflate_container);
mQsAutoReinflateContainer.addInflateListener(new InflateListener() {
@@ -229,32 +243,20 @@
mQsContainer.setPanelView(NotificationPanelView.this);
mQsContainer.getHeader().findViewById(R.id.expand_indicator)
.setOnClickListener(NotificationPanelView.this);
- }
- });
- mClockView = (TextView) findViewById(R.id.clock_view);
- mNotificationContainerParent = (NotificationsQuickSettingsContainer)
- findViewById(R.id.notification_container_parent);
- mNotificationStackScroller = (NotificationStackScrollLayout)
- findViewById(R.id.notification_stack_scroller);
- mNotificationStackScroller.setOnHeightChangedListener(this);
- mNotificationStackScroller.setOverscrollTopChangedListener(this);
- mNotificationStackScroller.setOnEmptySpaceClickListener(this);
- mNotificationStackScroller.setQsContainer(mQsContainer);
- mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
- mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
- mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
- mLastOrientation = getResources().getConfiguration().orientation;
- // recompute internal state when qspanel height changes
- mQsContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- final int height = bottom - top;
- final int oldHeight = oldBottom - oldTop;
- if (height != oldHeight) {
- onQsHeightChanged();
- }
+ // recompute internal state when qspanel height changes
+ mQsContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ final int height = bottom - top;
+ final int oldHeight = oldBottom - oldTop;
+ if (height != oldHeight) {
+ onQsHeightChanged();
+ }
+ }
+ });
+ mNotificationStackScroller.setQsContainer(mQsContainer);
}
});
}
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 3cc991c..ecba245 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -648,7 +648,16 @@
* @param policyFlags The policy flags associated with the event.
*/
private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) {
- final int pointerIdBits = (1 << mDraggingPointerId);
+ int pointerIdBits = 0;
+ // Clear the dragging pointer id if it's no longer valid.
+ if (event.findPointerIndex(mDraggingPointerId) == -1) {
+ Slog.e(LOG_TAG, "mDraggingPointerId doesn't match any pointers on current event. " +
+ "mDraggingPointerId: " + Integer.toString(mDraggingPointerId) +
+ ", Event: " + event);
+ mDraggingPointerId = INVALID_POINTER_ID;
+ } else {
+ pointerIdBits = (1 << mDraggingPointerId);
+ }
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
throw new IllegalStateException("Dragging state can be reached only if two "
@@ -664,6 +673,9 @@
sendDownForAllNotInjectedPointers(event, policyFlags);
} break;
case MotionEvent.ACTION_MOVE: {
+ if (mDraggingPointerId == INVALID_POINTER_ID) {
+ break;
+ }
switch (event.getPointerCount()) {
case 1: {
// do nothing
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2f2d8a4..5118b3f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3228,9 +3228,6 @@
@Override
public LegacyVpnInfo getLegacyVpnInfo(int userId) {
enforceCrossUserPermission(userId);
- if (mLockdownEnabled) {
- return null;
- }
synchronized(mVpns) {
return mVpns.get(userId).getLegacyVpnInfo();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a8a8553..5400e0d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17520,13 +17520,13 @@
final boolean killProcess =
!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
final boolean fullUninstall = removed && !replacing;
- if (killProcess) {
- forceStopPackageLocked(ssp, UserHandle.getAppId(
- intent.getIntExtra(Intent.EXTRA_UID, -1)),
- false, true, true, false, fullUninstall, userId,
- removed ? "pkg removed" : "pkg changed");
- }
if (removed) {
+ if (killProcess) {
+ forceStopPackageLocked(ssp, UserHandle.getAppId(
+ intent.getIntExtra(Intent.EXTRA_UID, -1)),
+ false, true, true, false, fullUninstall, userId,
+ removed ? "pkg removed" : "pkg changed");
+ }
final int cmd = killProcess
? IApplicationThread.PACKAGE_REMOVED
: IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
@@ -17543,6 +17543,12 @@
mBatteryStatsService.notePackageUninstalled(ssp);
}
} else {
+ if (killProcess) {
+ killPackageProcessesLocked(ssp, UserHandle.getAppId(
+ intent.getIntExtra(Intent.EXTRA_UID, -1)),
+ userId, ProcessList.INVALID_ADJ,
+ false, true, true, false, "change " + ssp);
+ }
cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
@@ -18300,8 +18306,8 @@
void updateUserConfigurationLocked() {
Configuration configuration = new Configuration(mConfiguration);
- Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
- mUserController.getCurrentUserIdLocked());
+ Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
+ mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
updateConfigurationLocked(configuration, null, false);
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index b4df10f..def6828 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -88,6 +88,9 @@
*/
private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
+ // There is some accuracy error in wifi reports so allow some slop in the results.
+ private static final long MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS = 750;
+
private static IBatteryStats sService;
final BatteryStatsImpl mStats;
@@ -1338,32 +1341,33 @@
} else {
final long totalActiveTimeMs = txTimeMs + rxTimeMs;
long maxExpectedIdleTimeMs;
- // Active time can never be greater than the total time, the stats received seem
- // to be corrupt.
if (totalActiveTimeMs > timePeriodMs) {
- maxExpectedIdleTimeMs = timePeriodMs;
- StringBuilder sb = new StringBuilder();
- sb.append("Total Active time ");
- TimeUtils.formatDuration(totalActiveTimeMs, sb);
- sb.append(" is longer than sample period ");
- TimeUtils.formatDuration(timePeriodMs, sb);
- sb.append(".\n");
- sb.append("Previous WiFi snapshot: ").append("idle=");
- TimeUtils.formatDuration(lastIdleMs, sb);
- sb.append(" rx=");
- TimeUtils.formatDuration(lastRxMs, sb);
- sb.append(" tx=");
- TimeUtils.formatDuration(lastTxMs, sb);
- sb.append(" e=").append(lastEnergy);
- sb.append("\n");
- sb.append("Current WiFi snapshot: ").append("idle=");
- TimeUtils.formatDuration(latest.mControllerIdleTimeMs, sb);
- sb.append(" rx=");
- TimeUtils.formatDuration(latest.mControllerRxTimeMs, sb);
- sb.append(" tx=");
- TimeUtils.formatDuration(latest.mControllerTxTimeMs, sb);
- sb.append(" e=").append(latest.mControllerEnergyUsed);
- Slog.wtf(TAG, sb.toString());
+ // Cap the max idle time at zero since the active time consumed the whole time
+ maxExpectedIdleTimeMs = 0;
+ if (totalActiveTimeMs > timePeriodMs + MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Total Active time ");
+ TimeUtils.formatDuration(totalActiveTimeMs, sb);
+ sb.append(" is longer than sample period ");
+ TimeUtils.formatDuration(timePeriodMs, sb);
+ sb.append(".\n");
+ sb.append("Previous WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(lastIdleMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(lastRxMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(lastTxMs, sb);
+ sb.append(" e=").append(lastEnergy);
+ sb.append("\n");
+ sb.append("Current WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(latest.mControllerIdleTimeMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(latest.mControllerRxTimeMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(latest.mControllerTxTimeMs, sb);
+ sb.append(" e=").append(latest.mControllerEnergyUsed);
+ Slog.wtf(TAG, sb.toString());
+ }
} else {
maxExpectedIdleTimeMs = timePeriodMs - totalActiveTimeMs;
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 2103cce..1b2ccd7 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,9 +20,11 @@
import android.accounts.Account;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
@@ -296,11 +298,12 @@
final int callingUserHandle = UserHandle.getCallingUserId();
// Registering an observer for any user other than the calling user requires uri grant or
// cross user permission
- if (callingUserHandle != userHandle &&
- mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
- != PackageManager.PERMISSION_GRANTED) {
- enforceCrossUserPermission(userHandle,
- "no permission to observe other users' provider view");
+ if (callingUserHandle != userHandle) {
+ if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle)
+ != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle,
+ "no permission to observe other users' provider view");
+ }
}
if (userHandle < 0) {
@@ -360,10 +363,11 @@
final int pid = Binder.getCallingPid();
final int callingUserHandle = UserHandle.getCallingUserId();
// Notify for any user other than the caller requires uri grant or cross user permission
- if (callingUserHandle != userHandle &&
- mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
- != PackageManager.PERMISSION_GRANTED) {
- enforceCrossUserPermission(userHandle, "no permission to notify other users");
+ if (callingUserHandle != userHandle) {
+ if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ userHandle) != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle, "no permission to notify other users");
+ }
}
// We passed the permission check; resolve pseudouser targets as appropriate
@@ -389,9 +393,18 @@
for (int i=0; i<numCalls; i++) {
ObserverCall oc = calls.get(i);
try {
- oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
+ // If the uri does not belong to the same user as the observer: we must add
+ // the userId to the uri. Otherewise the observer would think the uri belongs
+ // to his user.
+ final Uri tempUri;
+ if (oc.mObserverUserId != userHandle) {
+ tempUri = ContentProvider.maybeAddUserId(uri, userHandle);
+ } else {
+ tempUri = uri;
+ }
+ oc.mObserver.onChange(oc.mSelfChange, tempUri, userHandle);
if (DEBUG) Slog.d(TAG, "Notified " + oc.mObserver + " of " + "update at "
- + uri);
+ + tempUri);
} catch (RemoteException ex) {
synchronized (mRootNode) {
Log.w(TAG, "Found dead observer, removing");
@@ -427,6 +440,15 @@
}
}
+ private int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, int userHandle) {
+ try {
+ return ActivityManagerNative.getDefault().checkUriPermission(
+ uri, pid, uid, modeFlags, userHandle, null);
+ } catch (RemoteException e) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ }
+
public void notifyChange(Uri uri, IContentObserver observer,
boolean observerWantsSelfNotifications, boolean syncToNetwork) {
notifyChange(uri, observer, observerWantsSelfNotifications,
@@ -444,11 +466,13 @@
final ObserverNode mNode;
final IContentObserver mObserver;
final boolean mSelfChange;
+ final int mObserverUserId;
- ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange) {
+ ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange, int observerUserId) {
mNode = node;
mObserver = observer;
mSelfChange = selfChange;
+ mObserverUserId = observerUserId;
}
}
@@ -1361,7 +1385,8 @@
if (DEBUG) Slog.d(TAG, "Reporting to " + entry.observer + ": leaf=" + leaf
+ " flags=" + Integer.toHexString(flags)
+ " desc=" + entry.notifyForDescendants);
- calls.add(new ObserverCall(this, entry.observer, selfChange));
+ calls.add(new ObserverCall(this, entry.observer, selfChange,
+ UserHandle.getUserId(entry.uid)));
}
}
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsObservers.java b/services/core/java/com/android/server/net/NetworkStatsObservers.java
index 230c2e9..ea36170 100644
--- a/services/core/java/com/android/server/net/NetworkStatsObservers.java
+++ b/services/core/java/com/android/server/net/NetworkStatsObservers.java
@@ -190,11 +190,9 @@
private void handleUpdateStats(StatsContext statsContext) {
if (mDataUsageRequests.size() == 0) {
- if (LOGV) Slog.v(TAG, "No registered listeners of data usage");
return;
}
- if (LOGV) Slog.v(TAG, "Checking if any registered observer needs to be notified");
for (int i = 0; i < mDataUsageRequests.size(); i++) {
RequestInfo requestInfo = mDataUsageRequests.valueAt(i);
requestInfo.updateStats(statsContext);
@@ -371,9 +369,6 @@
NetworkStats stats = mCollection.getSummary(template,
Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
mAccessLevel, mCallingUid);
- if (LOGV) {
- Slog.v(TAG, "Netstats for " + template + ": " + stats);
- }
return stats.getTotalBytes();
}
}
@@ -391,11 +386,6 @@
for (int i = 0; i < uidsToMonitor.length; i++) {
long bytesSoFar = getTotalBytesForNetworkUid(mRequest.template, uidsToMonitor[i]);
-
- if (LOGV) {
- Slog.v(TAG, bytesSoFar + " bytes so far since notification for "
- + mRequest.template + " for uid=" + uidsToMonitor[i]);
- }
if (bytesSoFar > mRequest.thresholdInBytes) {
return true;
}
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 15a63ec..e3dcf14 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -36,6 +36,7 @@
import com.android.server.notification.NotificationManagerService.DumpFilter;
import java.io.PrintWriter;
+import java.util.Calendar;
import java.util.TimeZone;
/**
@@ -237,6 +238,14 @@
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction());
+ if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
+ for (Uri conditionId : mSubscriptions.keySet()) {
+ final ScheduleCalendar cal = mSubscriptions.get(conditionId);
+ if (cal != null) {
+ cal.setTimeZone(Calendar.getInstance().getTimeZone());
+ }
+ }
+ }
evaluateSubscriptions();
}
};
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5fdb1e8..0cafb93 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2589,8 +2589,15 @@
final PhoneWindow win = new PhoneWindow(context);
win.setIsStartingWindow(true);
+ final WindowManager.LayoutParams params = win.getAttributes();
final Resources r = context.getResources();
- win.setTitle(r.getText(labelRes, nonLocalizedLabel));
+ CharSequence label = r.getText(labelRes);
+ // Only change the accessibility title if the label is localized
+ if (label != null) {
+ win.setTitle(label, true);
+ } else {
+ win.setTitle(nonLocalizedLabel, false);
+ }
win.setType(
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
@@ -2624,7 +2631,6 @@
win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
- final WindowManager.LayoutParams params = win.getAttributes();
params.token = appToken;
params.packageName = packageName;
params.windowAnimations = win.getWindowStyle().getResourceId(
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 101f56f..8be5dfb 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1203,9 +1203,6 @@
window.layer = windowState.mLayer;
window.token = windowState.mClient.asBinder();
window.title = windowState.mAttrs.accessibilityTitle;
- if (window.title == null) {
- window.title = windowState.mAttrs.getTitle();
- }
window.accessibilityIdOfAnchor = windowState.mAttrs.accessibilityIdOfAnchor;
WindowState attachedWindow = windowState.mAttachedWindow;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index b773a4e..f57e83aa 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -451,6 +451,16 @@
destroySurfaces();
}
+ void markSavedSurfaceExiting() {
+ for (int i = allAppWindows.size() - 1; i >= 0; i--) {
+ final WindowState w = allAppWindows.get(i);
+ if (w.isAnimatingInvisibleWithSavedSurface()) {
+ w.mAnimatingExit = true;
+ w.mWinAnimator.mAnimating = true;
+ }
+ }
+ }
+
void restoreSavedSurfaces() {
if (!canRestoreSurfaces()) {
clearVisibleBeforeClientHidden();
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index f51fd8a..114d9be 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
@@ -380,6 +381,11 @@
}
private boolean updateBoundsAfterConfigChange() {
+ if (mDisplayContent == null) {
+ // If the stack is already detached we're not updating anything,
+ // as it's going away soon anyway.
+ return false;
+ }
final int newRotation = getDisplayInfo().rotation;
final int newDensity = getDisplayInfo().logicalDensityDpi;
@@ -403,6 +409,13 @@
snapDockedStackAfterRotation(mTmpRect2);
final int newDockSide = getDockSide(mTmpRect2);
if (oldDockSide != newDockSide) {
+ // Update the dock create mode and clear the dock create bounds, these
+ // might change after a rotation and the original values will be invalid.
+ mService.setDockedStackCreateStateLocked(
+ (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
+ ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
+ : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
+ null);
mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aaed8ca..c7148c1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2277,6 +2277,19 @@
}
}
+ private void setupWindowForRemoveOnExit(WindowState win) {
+ win.mRemoveOnExit = true;
+ win.setDisplayLayoutNeeded();
+ // Request a focus update as this window's input channel is already gone. Otherwise
+ // we could have no focused window in input manager.
+ final boolean focusChanged = updateFocusedWindowLocked(
+ UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
+ mWindowPlacerLocked.performSurfacePlacement();
+ if (focusChanged) {
+ mInputMonitor.updateInputWindowsLw(false /*force*/);
+ }
+ }
+
public void removeWindow(Session session, IWindow client) {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
@@ -2358,14 +2371,7 @@
// Do not set mAnimatingExit to true here, it will cause the surface to be hidden
// immediately after the enter animation is done. If the app is not yet drawn then
// it will show up as a flicker.
- win.mRemoveOnExit = true;
- // Request a focus update as this window's input channel is already gone. Otherwise
- // we could have no focused window in input manager.
- final boolean focusChanged = updateFocusedWindowLocked(
- UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
- if (focusChanged) {
- mInputMonitor.updateInputWindowsLw(false /*force*/);
- }
+ setupWindowForRemoveOnExit(win);
Binder.restoreCallingIdentity(origId);
return;
}
@@ -2417,17 +2423,10 @@
// The exit animation is running or should run... wait for it!
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Not removing " + win + " due to exit animation ");
- win.mRemoveOnExit = true;
- win.setDisplayLayoutNeeded();
- final boolean focusChanged = updateFocusedWindowLocked(
- UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
- mWindowPlacerLocked.performSurfacePlacement();
+ setupWindowForRemoveOnExit(win);
if (appToken != null) {
appToken.updateReportedVisibilityLocked();
}
- if (focusChanged) {
- mInputMonitor.updateInputWindowsLw(false /*force*/);
- }
Binder.restoreCallingIdentity(origId);
return;
}
@@ -4960,11 +4959,15 @@
public void setDockedStackCreateState(int mode, Rect bounds) {
synchronized (mWindowMap) {
- mDockedStackCreateMode = mode;
- mDockedStackCreateBounds = bounds;
+ setDockedStackCreateStateLocked(mode, bounds);
}
}
+ void setDockedStackCreateStateLocked(int mode, Rect bounds) {
+ mDockedStackCreateMode = mode;
+ mDockedStackCreateBounds = bounds;
+ }
+
/**
* Create a new TaskStack and place it on a DisplayContent.
* @param stackId The unique identifier of the new stack.
@@ -6387,6 +6390,11 @@
if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
"Taking screenshot while rotating");
+ // We force pending transactions to flush before taking
+ // the screenshot by pushing an empty synchronous transaction.
+ SurfaceControl.openTransaction();
+ SurfaceControl.closeTransactionSync();
+
bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
inRotation, rot);
if (bm == null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c15afb3..be27c82 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2111,7 +2111,9 @@
void clearHasSavedSurface() {
mSurfaceSaved = false;
mAnimatingWithSavedSurface = false;
- mWasVisibleBeforeClientHidden = false;
+ if (mWasVisibleBeforeClientHidden) {
+ mAppToken.destroySavedSurfaces();
+ }
}
boolean clearAnimatingWithSavedSurface() {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 308b24d..4148cd0 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1301,6 +1301,14 @@
appsCount = mService.mClosingApps.size();
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
+
+ // If we still have some windows animating with saved surfaces that's
+ // either invisible or already removed, mark them exiting so that they
+ // are disposed of after the exit animation. These are not supposed to
+ // be shown, or are delayed removal until app is actually drawn (in which
+ // case the window will be removed after the animation).
+ wtoken.markSavedSurfaceExiting();
+
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
appAnimator.clearThumbnail();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e306d89..eed4351 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -176,7 +176,7 @@
* visual content.
*/
private static final int DEFAULT_SYSTEM_THEME =
- com.android.internal.R.style.Theme_Material_Light_DarkActionBar;
+ com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar;
private final int mFactoryTestMode;
private Timer mProfilerSnapshotTimer;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 78efd05..613fae4 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -837,28 +837,9 @@
* @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
* @return A {@link PersistableBundle} containing the config for the given subId, or default
* values for an invalid subId.
- *
- * @deprecated use getConfig.
*/
@Nullable
public PersistableBundle getConfigForSubId(int subId) {
- return getConfig(subId);
- }
-
- /**
- * Gets the configuration values for a particular subscription, which is associated with a
- * specific SIM card. If an invalid subId is used, the returned config will contain default
- * values.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- *
- * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
- * @return A {@link PersistableBundle} containing the config for the given subId, or default
- * values for an invalid subId.
- */
- @Nullable
- public PersistableBundle getConfig(int subId) {
try {
ICarrierConfigLoader loader = getICarrierConfigLoader();
if (loader == null) {
@@ -880,11 +861,11 @@
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*
- * @return A {@link PersistableBundle} containing the config for the default subscription.
+ * @see #getConfigForSubId
*/
@Nullable
public PersistableBundle getConfig() {
- return getConfig(SubscriptionManager.getDefaultSubscriptionId());
+ return getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
}
/**
@@ -901,29 +882,8 @@
* {@link android.service.carrier.CarrierService#onLoadConfig} will be called from an
* arbitrary thread.
* </p>
- *
- * @deprecated use notifyConfigChanged.
*/
public void notifyConfigChangedForSubId(int subId) {
- notifyConfigChanged(subId);
- }
-
- /**
- * Calling this method triggers telephony services to fetch the current carrier configuration.
- * <p>
- * Normally this does not need to be called because the platform reloads config on its own.
- * This should be called by a carrier service app if it wants to update config at an arbitrary
- * moment.
- * </p>
- * <p>Requires that the calling app has carrier privileges.
- * @see #hasCarrierPrivileges
- * <p>
- * This method returns before the reload has completed, and
- * {@link android.service.carrier.CarrierService#onLoadConfig} will be called from an
- * arbitrary thread.
- * </p>
- */
- public void notifyConfigChanged(int subId) {
try {
ICarrierConfigLoader loader = getICarrierConfigLoader();
if (loader == null) {
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index 3743fb0..5ef71df 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -41,12 +41,7 @@
* Mock implementation of ContentProvider. All methods are non-functional and throw
* {@link java.lang.UnsupportedOperationException}. Tests can extend this class to
* implement behavior needed for tests.
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
-@Deprecated
public class MockContentProvider extends ContentProvider {
/*
* Note: if you add methods to ContentProvider, you must add similar methods to
diff --git a/test-runner/src/android/test/mock/MockContentResolver.java b/test-runner/src/android/test/mock/MockContentResolver.java
index 75c8335..d8e0977 100644
--- a/test-runner/src/android/test/mock/MockContentResolver.java
+++ b/test-runner/src/android/test/mock/MockContentResolver.java
@@ -49,12 +49,7 @@
* <p>For more information about application testing, read the
* <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
* </div>
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
-@Deprecated
public class MockContentResolver extends ContentResolver {
Map<String, ContentProvider> mProviders;
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index c7cbf97..b14fc41 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -55,12 +55,7 @@
* A mock {@link android.content.Context} class. All methods are non-functional and throw
* {@link java.lang.UnsupportedOperationException}. You can use this to inject other dependencies,
* mocks, or monitors into the classes you are testing.
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
-@Deprecated
public class MockContext extends Context {
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
index cbd0415..1afd90d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
@@ -23,6 +23,7 @@
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.bars.AppCompatActionBar;
import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.Config;
@@ -232,8 +233,10 @@
private BridgeActionBar createActionBar(@NonNull BridgeContext context,
@NonNull SessionParams params) {
+ boolean isMenu = "menu".equals(params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
+
BridgeActionBar actionBar;
- if (mBuilder.isThemeAppCompat()) {
+ if (mBuilder.isThemeAppCompat() && !isMenu) {
actionBar = new AppCompatActionBar(context, params);
} else {
actionBar = new FrameworkActionBar(context, params);