Merge "Fix Floating toolbar overflow width." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 2802062..376c2c3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3879,6 +3879,7 @@
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -3891,6 +3892,7 @@
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5615,8 +5617,8 @@
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -26424,6 +26426,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 5713af2..57f3a30 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3989,6 +3989,7 @@
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4001,6 +4002,7 @@
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -5736,8 +5738,8 @@
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearProfileOwner(android.content.ComponentName);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -28485,6 +28487,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8a61ec6..9faadd3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -229,8 +229,12 @@
public static final int OP_READ_CELL_BROADCASTS = 57;
/** @hide Inject mock location into the system. */
public static final int OP_MOCK_LOCATION = 58;
+ /** @hide Read external storage. */
+ public static final int OP_READ_EXTERNAL_STORAGE = 59;
+ /** @hide Write external storage. */
+ public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
/** @hide */
- public static final int _NUM_OP = 59;
+ public static final int _NUM_OP = 61;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -313,6 +317,12 @@
/** Inject mock location into the system. */
public static final String OPSTR_MOCK_LOCATION
= "android:mock_location";
+ /** Read external storage. */
+ public static final String OPSTR_READ_EXTERNAL_STORAGE
+ = "android:read_external_storage";
+ /** Write external storage. */
+ public static final String OPSTR_WRITE_EXTERNAL_STORAGE
+ = "android:write_external_storage";
/**
* This maps each operation to the operation that serves as the
@@ -381,7 +391,9 @@
OP_USE_FINGERPRINT,
OP_BODY_SENSORS,
OP_READ_CELL_BROADCASTS,
- OP_MOCK_LOCATION
+ OP_MOCK_LOCATION,
+ OP_READ_EXTERNAL_STORAGE,
+ OP_WRITE_EXTERNAL_STORAGE
};
/**
@@ -447,7 +459,9 @@
OPSTR_USE_FINGERPRINT,
OPSTR_BODY_SENSORS,
OPSTR_READ_CELL_BROADCASTS,
- OPSTR_MOCK_LOCATION
+ OPSTR_MOCK_LOCATION,
+ OPSTR_READ_EXTERNAL_STORAGE,
+ OPSTR_WRITE_EXTERNAL_STORAGE
};
/**
@@ -513,7 +527,9 @@
"USE_FINGERPRINT",
"BODY_SENSORS",
"READ_CELL_BROADCASTS",
- "MOCK_LOCATION"
+ "MOCK_LOCATION",
+ "OPSTR_READ_EXTERNAL_STORAGE",
+ "OPSTR_WRITE_EXTERNAL_STORAGE",
};
/**
@@ -579,7 +595,9 @@
Manifest.permission.USE_FINGERPRINT,
Manifest.permission.BODY_SENSORS,
Manifest.permission.READ_CELL_BROADCASTS,
- null
+ null,
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
/**
@@ -646,7 +664,9 @@
null, // USE_FINGERPRINT
null, // BODY_SENSORS
null, // READ_CELL_BROADCASTS
- null // MOCK_LOCATION
+ null, // MOCK_LOCATION
+ null, // READ_EXTERNAL_STORAGE
+ null // WRITE_EXTERNAL_STORAGE
};
/**
@@ -712,7 +732,9 @@
false, // USE_FINGERPRINT
false, // BODY_SENSORS
false, // READ_CELL_BROADCASTS
- false // MOCK_LOCATION
+ false, // MOCK_LOCATION
+ false, // READ_EXTERNAL_STORAGE
+ false // WRITE_EXTERNAL_STORAGE
};
/**
@@ -777,7 +799,9 @@
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ERRORED // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_ALLOWED
};
/**
@@ -846,6 +870,8 @@
false,
false,
false,
+ false,
+ false,
false
};
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 903411e..13030ca 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -717,6 +717,7 @@
break;
case OP_REPLACE: {
Fragment f = op.fragment;
+ int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
@@ -724,7 +725,7 @@
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
- if (f == null || old.mContainerId == f.mContainerId) {
+ if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d53157b..d28ff51 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3612,7 +3612,10 @@
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createUser(@NonNull ComponentName admin, String name) {
try {
return mService.createUser(admin, name);
@@ -3646,7 +3649,10 @@
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
try {
@@ -3962,24 +3968,27 @@
* <li>{@link Settings.Global#ADB_ENABLED}</li>
* <li>{@link Settings.Global#AUTO_TIME}</li>
* <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
- * <li>{@link Settings.Global#BLUETOOTH_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.bluetooth.BluetoothAdapter#enable()} and
- * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
* <li>{@link Settings.Global#DATA_ROAMING}</li>
- * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
- * <li>{@link Settings.Global#MODE_RINGER}</li>
- * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
* <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
- * <li>{@link Settings.Global#WIFI_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
* <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
- * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+ * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
* <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
* </ul>
+ * <p>Changing the following settings has no effect as of
+ * {@link android.os.Build.VERSION_CODES#MNC}:
+ * <ul>
+ * <li>{@link Settings.Global#BLUETOOTH_ON}.
+ * Use {@link android.bluetooth.BluetoothAdapter#enable()} and
+ * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
+ * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+ * <li>{@link Settings.Global#MODE_RINGER}.
+ * Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
+ * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
+ * <li>{@link Settings.Global#WIFI_ON}.
+ * Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
+ * </ul>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param setting The name of the setting to update.
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 369b692..24647f38 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -372,13 +372,4 @@
return new UsageEvents[size];
}
};
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- if (mParcel != null) {
- mParcel.recycle();
- mParcel = null;
- }
- }
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index d37dda0..6ede29b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1593,7 +1593,11 @@
@NonNull ContentObserver observer) {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(observer, "observer");
- registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId());
+ registerContentObserver(
+ ContentProvider.getUriWithoutUserId(uri),
+ notifyForDescendents,
+ observer,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/** @hide - designated user version */
@@ -1659,7 +1663,11 @@
public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
boolean syncToNetwork) {
Preconditions.checkNotNull(uri, "uri");
- notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
+ notifyChange(
+ ContentProvider.getUriWithoutUserId(uri),
+ observer,
+ syncToNetwork,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/**
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 31aedad..cfd5bf1 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -517,7 +517,7 @@
* Note that Http Proxies are only a hint - the system recommends their use, but it does
* not enforce it and applications may ignore them.
*
- * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+ * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
* @hide
*/
public void setHttpProxy(ProxyInfo proxy) {
@@ -774,6 +774,43 @@
}
/**
+ * Evaluate whether the {@link InetAddress} is considered reachable.
+ *
+ * @return {@code true} if the given {@link InetAddress} is considered reachable,
+ * {@code false} otherwise.
+ * @hide
+ */
+ public boolean isReachable(InetAddress ip) {
+ final List<RouteInfo> allRoutes = getAllRoutes();
+ // If we don't have a route to this IP address, it's not reachable.
+ final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
+ if (bestRoute == null) {
+ return false;
+ }
+
+ // TODO: better source address evaluation for destination addresses.
+
+ if (ip instanceof Inet4Address) {
+ // For IPv4, it suffices for now to simply have any address.
+ return hasIPv4Address();
+ } else if (ip instanceof Inet6Address) {
+ if (ip.isLinkLocalAddress()) {
+ // For now, just make sure link-local destinations have
+ // scopedIds set, since transmits will generally fail otherwise.
+ // TODO: verify it matches the ifindex of one of the interfaces.
+ return (((Inet6Address)ip).getScopeId() != 0);
+ } else {
+ // For non-link-local destinations check that either the best route
+ // is directly connected or that some global preferred address exists.
+ // TODO: reconsider all cases (disconnected ULA networks, ...).
+ return (!bestRoute.hasGateway() || hasGlobalIPv6Address());
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Compares this {@code LinkProperties} interface name against the target
*
* @param target LinkProperties to compare.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cc56969..e5afdde 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -562,6 +562,21 @@
"android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
/**
+ * Activity Action: Show settings to toggle permission to draw on top of
+ * other apps.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_OVERLAY_PERMISSION =
+ "android.settings.MANAGE_OVERLAY_PERMISSION";
+
+ /**
* Activity Action: Show screen of details about a particular application.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index b78eca7..6dc66ea 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -40,6 +40,7 @@
public static final int ACTION_BRIGHTNESS = 218;
public static final int ACTION_BRIGHTNESS_AUTO = 219;
public static final int BRIGHTNESS_DIALOG = 220;
+ public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
// Temporary constants go here, to await migration to MetricsConstants.
public static void visible(Context context, int category) throws IllegalArgumentException {
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index c869722..b2699f8 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -167,6 +167,7 @@
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
mFloatingToolbar.setContentRect(mContentRectOnWindow);
@@ -174,9 +175,9 @@
}
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mContentRectOnWindow.setEmpty();
}
- mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index bada791..bd9b014 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1414,7 +1414,7 @@
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="signature|system|appop" />
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 65da1f1..62131da 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -16,9 +16,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:pathData="M20,8H8c-2.2,0 -4,1.8 -4,4l0,24c0,2.2 1.8,4 4,4h32c2.2,0 4,-1.8 4,-4V16c0,-2.2 -1.8,-4 -4,-4H24L20,8z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M0,0h48v48H0z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M27,9c2.2,0 4,-1.8 4,-4s-1.8,-4 -4,-4 -4,1.8 -4,4 1.8,4 4,4zm-7.2,27.8l1.9,-8.8 4.3,4v12h4V28.9l-4.1,-4.1 1.2,-6C29.7,22 33.6,24 38,24v-4c-3.7,0 -6.9,-2 -8.7,-4.9l-1.9,-3.2c-0.7,-1.2 -2,-1.9 -3.4,-1.9 -0.5,0 -1,0.1 -1.5,0.3L12,14.6V24h4v-6.7l3.5,-1.4L16.4,32l-9.8,-1.9 -0.8,3.9s14,2.7 14,2.8z"/>
</vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4bc2205..451813c 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2258,4 +2258,7 @@
<!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
<bool name="config_eap_sim_based_auth_supported">true</bool>
+
+ <!-- How long history of previous vibrations should be kept for the dumpsys. -->
+ <integer name="config_previousVibrationsDumpLimit">20</integer>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ebbbc4c..01ecba8 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1708,6 +1708,7 @@
<java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
<java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
<java-symbol type="integer" name="config_notificationServiceArchiveSize" />
+ <java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
<java-symbol type="integer" name="config_radioScanningTimeout" />
<java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 5c55efb..ea444a4 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
package android.net;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
import android.net.RouteInfo;
@@ -26,6 +28,7 @@
import java.net.InetAddress;
import java.util.ArrayList;
+
public class LinkPropertiesTest extends TestCase {
private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
@@ -567,4 +570,80 @@
assertEquals(ProvisioningChange.STILL_PROVISIONED,
LinkProperties.compareProvisioning(v6lp, v6lp2));
}
+
+ @SmallTest
+ public void testIsReachable() {
+ final LinkProperties v4lp = new LinkProperties();
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Add an on-link route, making the on-link DNS server reachable,
+ // but there is still no IPv4 address.
+ assertTrue(v4lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding an IPv4 address (right now, any IPv4 address) means we use
+ // the routes to compute likely reachability.
+ assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertTrue(v4lp.isReachable(DNS2));
+
+ final LinkProperties v6lp = new LinkProperties();
+ final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
+ final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
+ final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local route, making the link-local DNS servers reachable. Because
+ // we assume the presence of an IPv6 link-local address, link-local DNS servers
+ // are considered reachable, but only those with a non-zero scope identifier.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local address--nothing changes.
+ assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global route on link, but no global address yet. DNS servers reachable
+ // via a route that doesn't require a gateway: give them the benefit of the
+ // doubt and hope the link-local source address suffices for communication.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global address; the on-link global address DNS server is (still)
+ // presumed reachable.
+ assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertTrue(v6lp.isReachable(DNS6));
+ }
}
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 1a6d34e..91e931d 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -50,6 +50,8 @@
android:layout_below="@id/volume_row_header"
android:layout_toEndOf="@id/volume_row_icon"
android:layout_toStartOf="@+id/volume_settings_button"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
android:paddingEnd="8dp"
android:paddingStart="8dp" />
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 81461bd..f432808 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -57,7 +57,7 @@
return mSelectedValue;
}
- public void setSelectedValue(Object value) {
+ public void setSelectedValue(Object value, boolean fromClick) {
if (Objects.equals(value, mSelectedValue)) return;
mSelectedValue = value;
for (int i = 0; i < getChildCount(); i++) {
@@ -67,7 +67,7 @@
c.setSelected(selected);
c.setTypeface(selected ? MEDIUM : REGULAR);
}
- fireOnSelected();
+ fireOnSelected(fromClick);
}
public void addButton(int labelResId, int contentDescriptionResId, Object value) {
@@ -100,9 +100,9 @@
}
}
- private void fireOnSelected() {
+ private void fireOnSelected(boolean fromClick) {
if (mCallback != null) {
- mCallback.onSelected(mSelectedValue);
+ mCallback.onSelected(mSelectedValue, fromClick);
}
}
@@ -115,11 +115,11 @@
private final View.OnClickListener mClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
- setSelectedValue(v.getTag());
+ setSelectedValue(v.getTag(), true /* fromClick */);
}
};
public interface Callback extends Interaction.Callback {
- void onSelected(Object value);
+ void onSelected(Object value, boolean fromClick);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 0ab0392..3964820 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -741,12 +741,7 @@
private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
if (isActive && mExpanded) {
- row.slider.setFocusable(true);
- row.slider.setFocusableInTouchMode(true);
row.slider.requestFocus();
- } else {
- row.slider.setFocusableInTouchMode(false);
- row.slider.setFocusable(false);
}
final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
: mInactiveSliderTint;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 8035cd3..3c9a7fc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -391,7 +391,7 @@
setExpanded(isShown());
mSessionZen = zen;
}
- mZenButtons.setSelectedValue(zen);
+ mZenButtons.setSelectedValue(zen, false /* fromClick */);
updateWidgets();
handleUpdateConditions();
if (mExpanded) {
@@ -968,10 +968,12 @@
private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
@Override
- public void onSelected(final Object value) {
+ public void onSelected(final Object value, boolean fromClick) {
if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
final int zen = (Integer) value;
- MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ if (fromClick) {
+ MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ }
if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
final Uri realConditionId = getRealConditionId(mSessionExitCondition);
AsyncTask.execute(new Runnable() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 47971a1..7f124dc 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -140,14 +140,12 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet4Address;
-import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -2713,7 +2711,10 @@
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
- if (nai == null) return;
+ if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
+ nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
+ return;
+ }
// Revalidate if the app report does not match our current validated state.
if (hasConnectivity == nai.lastValidated) return;
final int uid = Binder.getCallingUid();
@@ -4014,51 +4015,10 @@
return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
}
- // TODO: investigate moving this into LinkProperties, if only to make more accurate
- // the isProvisioned() checks.
- private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) {
- final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>();
- final List<RouteInfo> allRoutes = lp.getAllRoutes();
- for (InetAddress nameserver : lp.getDnsServers()) {
- // If the LinkProperties doesn't include a route to the nameserver, ignore it.
- final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver);
- if (bestRoute == null) {
- continue;
- }
-
- // TODO: better source address evaluation for destination addresses.
- if (nameserver instanceof Inet4Address) {
- if (!lp.hasIPv4Address()) {
- continue;
- }
- } else if (nameserver instanceof Inet6Address) {
- if (nameserver.isLinkLocalAddress()) {
- if (((Inet6Address)nameserver).getScopeId() == 0) {
- // For now, just make sure link-local DNS servers have
- // scopedIds set, since DNS lookups will fail otherwise.
- // TODO: verify the scopeId matches that of lp's interface.
- continue;
- }
- } else {
- if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) {
- // TODO: reconsider all corner cases (disconnected ULA networks, ...).
- continue;
- }
- }
- }
-
- dnsServers.add(nameserver);
- }
- return Collections.unmodifiableList(dnsServers);
- }
-
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
boolean flush, boolean useDefaultDns) {
- // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the
- // route to a DNS server has been removed (only really applicable in special cases
- // where there is no default route).
if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp);
+ Collection<InetAddress> dnses = newLp.getDnsServers();
if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
dnses = new ArrayList();
dnses.add(mDefaultDns);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ebbd9e5..42794e7 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -79,6 +79,7 @@
void setCredential(String credential, String savedCredential, int userId)
throws RemoteException;
byte[] toHash(String credential, int userId);
+ String adjustForKeystore(String credential);
}
public LockSettingsService(Context context) {
@@ -528,6 +529,11 @@
return LockPatternUtils.patternToHash(
LockPatternUtils.stringToPattern(pattern));
}
+
+ @Override
+ public String adjustForKeystore(String pattern) {
+ return LockPatternUtils.patternStringToBaseZero(pattern);
+ }
}
);
@@ -568,6 +574,11 @@
public byte[] toHash(String password, int userId) {
return mLockPatternUtils.passwordToHash(password, userId);
}
+
+ @Override
+ public String adjustForKeystore(String password) {
+ return password;
+ }
}
);
}
@@ -587,7 +598,7 @@
if (storedHash.version == CredentialHash.VERSION_LEGACY) {
byte[] hash = credentialUtil.toHash(credential, userId);
if (Arrays.equals(hash, storedHash.hash)) {
- unlockKeystore(credential, userId);
+ unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
// migrate credential to GateKeeper
credentialUtil.setCredential(credential, null, userId);
if (!hasChallenge) {
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 20f6f1c..30f4dce 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -47,7 +47,10 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
@@ -58,6 +61,8 @@
private static final boolean DEBUG = false;
private final LinkedList<Vibration> mVibrations;
+ private final LinkedList<VibrationInfo> mPreviousVibrations;
+ private final int mPreviousVibrationsLimit;
private Vibration mCurrentVibration;
private final WorkSource mTmpWorkSource = new WorkSource();
private final Handler mH = new Handler();
@@ -146,6 +151,47 @@
}
}
+ private static class VibrationInfo {
+ long timeout;
+ long startTime;
+ long[] pattern;
+ int repeat;
+ int usageHint;
+ int uid;
+ String opPkg;
+
+ public VibrationInfo(long timeout, long startTime, long[] pattern, int repeat,
+ int usageHint, int uid, String opPkg) {
+ this.timeout = timeout;
+ this.startTime = startTime;
+ this.pattern = pattern;
+ this.repeat = repeat;
+ this.usageHint = usageHint;
+ this.uid = uid;
+ this.opPkg = opPkg;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("timeout: ")
+ .append(timeout)
+ .append(", startTime: ")
+ .append(startTime)
+ .append(", pattern: ")
+ .append(Arrays.toString(pattern))
+ .append(", repeat: ")
+ .append(repeat)
+ .append(", usageHint: ")
+ .append(usageHint)
+ .append(", uid: ")
+ .append(uid)
+ .append(", opPkg: ")
+ .append(opPkg)
+ .toString();
+ }
+ }
+
VibratorService(Context context) {
// Reset the hardware to a default state, in case this is a runtime
// restart instead of a fresh boot.
@@ -161,7 +207,11 @@
mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
- mVibrations = new LinkedList<Vibration>();
+ mPreviousVibrationsLimit = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_previousVibrationsDumpLimit);
+
+ mVibrations = new LinkedList<>();
+ mPreviousVibrations = new LinkedList<>();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -252,6 +302,7 @@
removeVibrationLocked(token);
doCancelVibrateLocked();
mCurrentVibration = vib;
+ addToPreviousVibrationsLocked(vib);
startVibrationLocked(vib);
}
} finally {
@@ -315,6 +366,7 @@
mCurrentVibration = vib;
startVibrationLocked(vib);
}
+ addToPreviousVibrationsLocked(vib);
}
}
finally {
@@ -322,6 +374,14 @@
}
}
+ private void addToPreviousVibrationsLocked(Vibration vib) {
+ if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
+ mPreviousVibrations.removeFirst();
+ }
+ mPreviousVibrations.addLast(new VibratorService.VibrationInfo(vib.mTimeout, vib.mStartTime,
+ vib.mPattern, vib.mRepeat, vib.mUsageHint, vib.mUid, vib.mOpPkg));
+ }
+
@Override // Binder call
public void cancelVibrate(IBinder token) {
mContext.enforceCallingOrSelfPermission(
@@ -649,7 +709,6 @@
if (!mDone) {
// If this vibration finished naturally, start the next
// vibration.
- mVibrations.remove(mVibration);
unlinkVibration(mVibration);
startNextVibrationLocked();
}
@@ -685,4 +744,23 @@
}
}
};
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ pw.println("Permission Denial: can't dump vibrator service from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+ pw.println("Previous vibrations:");
+ synchronized (mVibrations) {
+ for (VibrationInfo info : mPreviousVibrations) {
+ pw.print(" ");
+ pw.println(info.toString());
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 93ed2ee..2c57833 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -23,12 +23,14 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
+import android.content.Intent;
import android.content.ISyncStatusObserver;
import android.content.PeriodicSync;
import android.content.SyncAdapterType;
import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
@@ -161,8 +163,9 @@
* Register a content observer tied to a specific user's view of the provider.
* @param userHandle the user whose view of the provider is to be observed. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly handled; all other pseudousers are forbidden.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
+ * are forbidden.
*/
@Override
public void registerContentObserver(Uri uri, boolean notifyForDescendants,
@@ -171,8 +174,17 @@
throw new IllegalArgumentException("You must pass a valid uri and observer");
}
- enforceCrossUserPermission(userHandle,
- "no permission to observe other users' provider view");
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ 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 (userHandle < 0) {
if (userHandle == UserHandle.USER_CURRENT) {
@@ -185,7 +197,7 @@
synchronized (mRootNode) {
mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
- Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
+ uid, pid, userHandle);
if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
" with notifyForDescendants " + notifyForDescendants);
}
@@ -211,8 +223,9 @@
* Notify observers of a particular user's view of the provider.
* @param userHandle the user whose view of the provider is to be notified. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly interpreted; no other pseudousers are allowed.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
+ * allowed.
*/
@Override
public void notifyChange(Uri uri, IContentObserver observer,
@@ -223,11 +236,14 @@
+ " from observer " + observer + ", syncToNetwork " + syncToNetwork);
}
- // Notify for any user other than the caller's own requires permission.
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final int callingUserHandle = UserHandle.getCallingUserId();
- if (userHandle != callingUserHandle) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
- "no permission to notify other users");
+ // 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");
}
// We passed the permission check; resolve pseudouser targets as appropriate
@@ -240,7 +256,6 @@
}
}
- final int uid = Binder.getCallingUid();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
long identityToken = clearCallingIdentity();
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 751bae9..04dce3a 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -117,7 +117,7 @@
private static final Set<String> ACCOUNTS_PERMISSIONS = new ArraySet<>();
static {
- ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
+ //ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
}
private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d31c6e9..b41dd06 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,6 +51,7 @@
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.FactoryTest;
@@ -61,6 +62,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -267,6 +269,7 @@
SearchManager mSearchManager;
AccessibilityManager mAccessibilityManager;
BurnInProtectionHelper mBurnInProtectionHelper;
+ AppOpsManager mAppOpsManager;
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -1255,6 +1258,7 @@
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+ mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -1812,6 +1816,25 @@
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
if (permission != null) {
+ if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
+ final int callingUid = Binder.getCallingUid();
+ // check if this is a system uid first before bothering with
+ // obtaining package name
+ if (callingUid == Process.SYSTEM_UID) {
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
+ final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid,
+ attrs.packageName);
+ if (mode == AppOpsManager.MODE_DEFAULT) {
+ if (mContext.checkCallingPermission(permission) !=
+ PackageManager.PERMISSION_GRANTED) {
+ return WindowManagerGlobal.ADD_PERMISSION_DENIED;
+ }
+ }
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5cfbb40..0670cd2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -225,6 +225,7 @@
private static final Set<String> SECURE_SETTINGS_WHITELIST;
private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
+ private static final Set<String> GLOBAL_SETTINGS_DEPRECATED;
static {
SECURE_SETTINGS_WHITELIST = new HashSet();
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
@@ -240,13 +241,17 @@
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.MODE_RINGER);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.NETWORK_PREFERENCE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
+
+ GLOBAL_SETTINGS_DEPRECATED = new HashSet();
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.MODE_RINGER);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.NETWORK_PREFERENCE);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
}
// Keyguard features that when set of a profile will affect the profiles
@@ -5954,14 +5959,16 @@
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ // Some settings are no supported any more. However we do not want to throw a
+ // SecurityException to avoid breaking apps.
+ if (GLOBAL_SETTINGS_DEPRECATED.contains(setting)) {
+ Log.i(LOG_TAG, "Global setting no longer supported: " + setting);
+ return;
+ }
+
if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
- // BLUETOOTH_ON and WIFI_ON used to be supported but not any more. We do not want to
- // throw a SecurityException not to break apps.
- if (!Settings.Global.BLUETOOTH_ON.equals(setting)
- && !Settings.Global.WIFI_ON.equals(setting)) {
- throw new SecurityException(String.format(
- "Permission denial: device owners cannot update %1$s", setting));
- }
+ throw new SecurityException(String.format(
+ "Permission denial: device owners cannot update %1$s", setting));
}
if (Settings.Global.STAY_ON_WHILE_PLUGGED_IN.equals(setting)) {