diff options
51 files changed, 686 insertions, 190 deletions
diff --git a/api/current.txt b/api/current.txt index 049d790..058297a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -26099,6 +26099,7 @@ package android.provider { method public static boolean isDocumentUri(android.content.Context, android.net.Uri); method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String); field public static final java.lang.String EXTRA_ERROR = "error"; + field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; field public static final java.lang.String EXTRA_INFO = "info"; field public static final java.lang.String EXTRA_LOADING = "loading"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; @@ -26536,6 +26537,7 @@ package android.provider { field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS"; field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS"; field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS"; + field public static final java.lang.String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS"; diff --git a/api/system-current.txt b/api/system-current.txt index 8b3c181..ea2de6b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -28029,6 +28029,7 @@ package android.provider { method public static boolean isDocumentUri(android.content.Context, android.net.Uri); method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String); field public static final java.lang.String EXTRA_ERROR = "error"; + field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; field public static final java.lang.String EXTRA_INFO = "info"; field public static final java.lang.String EXTRA_LOADING = "loading"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; @@ -28568,6 +28569,7 @@ package android.provider { field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS"; field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS"; field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS"; + field public static final java.lang.String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS"; diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index b0a7dc7..bf3b455 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -305,11 +305,23 @@ public class Am extends BaseCommand { " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" + " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" + " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + + " (mutiple extras passed as Integer[])\n" + + " [--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + + " (mutiple extras passed as List<Integer>)\n" + " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + + " (mutiple extras passed as Long[])\n" + + " [--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + + " (mutiple extras passed as List<Long>)\n" + " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" + + " (mutiple extras passed as Float[])\n" + + " [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" + + " (mutiple extras passed as List<Float>)\n" + " [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" + - " (to embed a comma into a string escape it using \"\\,\")\n" + - " [-n <COMPONENT>] [-p <PACKAGE>] [-f <FLAGS>]\n" + + " (mutiple extras passed as String[]; to embed a comma into a string,\n" + + " escape it using \"\\,\")\n" + + " [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" + + " (mutiple extras passed as List<String>; to embed a comma into a string,\n" + + " escape it using \"\\,\")\n" + " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" + " [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" + " [--debug-log-resolution] [--exclude-stopped-packages]\n" + @@ -490,6 +502,15 @@ public class Am extends BaseCommand { list[i] = Integer.decode(strings[i]); } intent.putExtra(key, list); + } else if (opt.equals("--eial")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Integer> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Integer.decode(strings[i])); + } + intent.putExtra(key, list); } else if (opt.equals("--el")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -504,6 +525,16 @@ public class Am extends BaseCommand { } intent.putExtra(key, list); hasIntentInfo = true; + } else if (opt.equals("--elal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Long> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Long.valueOf(strings[i])); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--ef")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -519,6 +550,16 @@ public class Am extends BaseCommand { } intent.putExtra(key, list); hasIntentInfo = true; + } else if (opt.equals("--efal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Float> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Float.valueOf(strings[i])); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--esa")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -528,6 +569,19 @@ public class Am extends BaseCommand { String[] strings = value.split("(?<!\\\\),"); intent.putExtra(key, strings); hasIntentInfo = true; + } else if (opt.equals("--esal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + // Split on commas unless they are preceeded by an escape. + // The escape character must be escaped for the string and + // again for the regex, thus four escape characters become one. + String[] strings = value.split("(?<!\\\\),"); + ArrayList<String> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(strings[i]); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--ez")) { String key = nextArgRequired(); String value = nextArgRequired().toLowerCase(); diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index dbc35af..c469ae4 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -30,6 +30,7 @@ #include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> +#include <ui/DisplayInfo.h> #include <ui/PixelFormat.h> // TODO: Fix Skia. @@ -159,9 +160,35 @@ int main(int argc, char** argv) uint32_t w, s, h, f; size_t size = 0; + // Maps orientations from DisplayInfo to ISurfaceComposer + static const uint32_t ORIENTATION_MAP[] = { + ISurfaceComposer::eRotateNone, // 0 == DISPLAY_ORIENTATION_0 + ISurfaceComposer::eRotate270, // 1 == DISPLAY_ORIENTATION_90 + ISurfaceComposer::eRotate180, // 2 == DISPLAY_ORIENTATION_180 + ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270 + }; + ScreenshotClient screenshot; sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId); - if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) { + if (display == NULL) { + fprintf(stderr, "Unable to get handle for display %d\n", displayId); + return 1; + } + + Vector<DisplayInfo> configs; + SurfaceComposerClient::getDisplayConfigs(display, &configs); + int activeConfig = SurfaceComposerClient::getActiveConfig(display); + if (static_cast<size_t>(activeConfig) >= configs.size()) { + fprintf(stderr, "Active config %d not inside configs (size %zu)\n", + activeConfig, configs.size()); + return 1; + } + uint8_t displayOrientation = configs[activeConfig].orientation; + uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation]; + + status_t result = screenshot.update(display, Rect(), 0, 0, 0, -1U, + false, captureOrientation); + if (result == NO_ERROR) { base = screenshot.getPixels(); w = screenshot.getWidth(); h = screenshot.getHeight(); diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index bb45abb4..e110dcb 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -213,7 +213,7 @@ public class Presentation extends Dialog { // dismiss the presentation immediately. This case is expected // to be rare but surprising, so we'll write a log message about it. if (!isConfigurationStillValid()) { - Log.i(TAG, "Presentation is being immediately dismissed because the " + Log.i(TAG, "Presentation is being dismissed because the " + "display metrics have changed since it was created."); mHandler.sendEmptyMessage(MSG_CANCEL); } @@ -274,6 +274,8 @@ public class Presentation extends Dialog { // is invalid and the application must recreate the presentation to get // a new context. if (!isConfigurationStillValid()) { + Log.i(TAG, "Presentation is being dismissed because the " + + "display metrics have changed since it was created."); cancel(); } } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 3ab0e01..bf44746 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2275,7 +2275,7 @@ public class DevicePolicyManager { if (mService != null) { try { final String alias = getCaCertAlias(certBuffer); - mService.uninstallCaCert(admin, alias); + mService.uninstallCaCerts(admin, new String[] {alias}); } catch (CertificateException e) { Log.w(TAG, "Unable to parse certificate", e); } catch (RemoteException e) { @@ -2322,12 +2322,11 @@ public class DevicePolicyManager { */ public void uninstallAllUserCaCerts(@Nullable ComponentName admin) { if (mService != null) { - for (String alias : new TrustedCertificateStore().userAliases()) { - try { - mService.uninstallCaCert(admin, alias); - } catch (RemoteException re) { - Log.w(TAG, "Failed talking with device policy service", re); - } + try { + mService.uninstallCaCerts(admin, new TrustedCertificateStore().userAliases() + .toArray(new String[0])); + } catch (RemoteException re) { + Log.w(TAG, "Failed talking with device policy service", re); } } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 8c7b20a..a700806 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -128,7 +128,7 @@ interface IDevicePolicyManager { boolean hasUserSetupCompleted(); boolean installCaCert(in ComponentName admin, in byte[] certBuffer); - void uninstallCaCert(in ComponentName admin, in String alias); + void uninstallCaCerts(in ComponentName admin, in String[] aliases); void enforceCanManageCaCerts(in ComponentName admin); boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias); diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 82d40d3..c547b06 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -150,9 +150,17 @@ public abstract class CameraCaptureSession implements AutoCloseable { * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when this * capture session was created.</p> * - * <p>Multiple requests can be in progress at once. They are processed in - * first-in, first-out order, with minimal delays between each - * capture. Requests submitted through this method have higher priority than + * <p>Multiple regular and reprocess requests can be in progress at once. If there are only + * regular requests or reprocess requests in progress, they are processed in first-in, + * first-out order. If there are both regular and reprocess requests in progress, regular + * requests are processed in first-in, first-out order and reprocess requests are processed in + * first-in, first-out order, respectively. However, the processing order of a regular request + * and a reprocess request in progress is not specified. In other words, a regular request + * will always be processed before regular requets that are submitted later. A reprocess request + * will always be processed before reprocess requests that are submitted later. However, a + * regular request may not be processed before reprocess requests that are submitted later.<p> + * + * <p>Requests submitted through this method have higher priority than * those submitted through {@link #setRepeatingRequest} or * {@link #setRepeatingBurst}, and will be processed as soon as the current * repeat/repeatBurst processing completes.</p> @@ -207,10 +215,13 @@ public abstract class CameraCaptureSession implements AutoCloseable { * not be interleaved with requests submitted by other capture or repeat * calls. * - * <p>The requests will be captured in order, each capture producing one {@link CaptureResult} - * and image buffers for one or more target {@link android.view.Surface surfaces}. The target - * surfaces (set with {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces - * provided when this capture session was created.</p> + * <p>Regular and reprocess requests can be mixed together in a single burst. Regular requests + * will be captured in order and reprocess requests will be processed in order, respectively. + * However, the processing order between a regular request and a reprocess request is not + * specified. Each capture produces one {@link CaptureResult} and image buffers for one or more + * target {@link android.view.Surface surfaces}. The target surfaces (set with + * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when + * this capture session was created.</p> * * <p>The main difference between this method and simply calling * {@link #capture} repeatedly is that this method guarantees that no diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 881dc0f..31a6a96 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -85,6 +85,16 @@ interface IUsbManager /* Sets the current USB function. */ void setCurrentFunction(String function); + /* Sets whether USB data (for example, MTP exposed pictures) should be made + * available on the USB connection. Unlocking data should only be done with + * user involvement, since exposing pictures or other data could leak sensitive + * user information. + */ + void setUsbDataUnlocked(boolean unlock); + + /* Returns true iff sensitive user data is exposed on the USB connection. */ + boolean isUsbDataUnlocked(); + /* Allow USB debugging from the attached host. If alwaysAllow is true, add the * the public key to list of host keys that the user has approved. */ diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 000d41f..c83f466 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -142,6 +142,16 @@ public class UsbManager { public static final String USB_CONFIGURED = "configured"; /** + * Boolean extra indicating whether confidential user data, such as photos, should be + * made available on the USB connection. This variable will only be set when the user + * has explicitly asked for this data to be unlocked. + * Used in extras for the {@link #ACTION_USB_STATE} broadcast. + * + * {@hide} + */ + public static final String USB_DATA_UNLOCKED = "unlocked"; + + /** * Name of the USB mass storage USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * @@ -464,4 +474,34 @@ public class UsbManager { Log.e(TAG, "RemoteException in setCurrentFunction", e); } } + + /** + * Sets whether USB data (for example, MTP exposed pictures) should be made available + * on the USB connection. Unlocking usb data should only be done with user involvement, + * since exposing pictures or other data could leak sensitive user information. + * + * {@hide} + */ + public void setUsbDataUnlocked(boolean unlocked) { + try { + mService.setUsbDataUnlocked(unlocked); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in setUsbDataUnlocked", e); + } + } + + /** + * Returns {@code true} iff access to sensitive USB data is currently allowed. + * + * {@hide} + */ + public boolean isUsbDataUnlocked() { + try { + return mService.isUsbDataUnlocked(); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in isUsbDataUnlocked", e); + } + return false; + } + } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index c9609e5..a6efc58 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -3489,57 +3489,90 @@ public abstract class BatteryStats implements Parcelable { pw.println(); for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); + pw.print(prefix); switch (bs.drainType) { case IDLE: - pw.print(prefix); pw.print(" Idle: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Idle: "); break; case CELL: - pw.print(prefix); pw.print(" Cell standby: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Cell standby: "); break; case PHONE: - pw.print(prefix); pw.print(" Phone calls: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Phone calls: "); break; case WIFI: - pw.print(prefix); pw.print(" Wifi: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Wifi: "); break; case BLUETOOTH: - pw.print(prefix); pw.print(" Bluetooth: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Bluetooth: "); break; case SCREEN: - pw.print(prefix); pw.print(" Screen: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Screen: "); break; case FLASHLIGHT: - pw.print(prefix); pw.print(" Flashlight: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Flashlight: "); break; case APP: - pw.print(prefix); pw.print(" Uid "); + pw.print(" Uid "); UserHandle.formatUid(pw, bs.uidObj.getUid()); - pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println(); + pw.print(": "); break; case USER: - pw.print(prefix); pw.print(" User "); pw.print(bs.userId); - pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println(); + pw.print(" User "); pw.print(bs.userId); + pw.print(": "); break; case UNACCOUNTED: - pw.print(prefix); pw.print(" Unaccounted: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Unaccounted: "); break; case OVERCOUNTED: - pw.print(prefix); pw.print(" Over-counted: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Over-counted: "); break; case CAMERA: - pw.print(prefix); pw.print(" Camera: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Camera: "); + break; + default: + pw.print(" ???: "); break; } + printmAh(pw, bs.totalPowerMah); + + if (bs.drainType == BatterySipper.DrainType.APP) { + pw.print(" ("); + if (bs.cpuPowerMah != 0) { + pw.print(" cpu="); + printmAh(pw, bs.cpuPowerMah); + } + if (bs.wakeLockPowerMah != 0) { + pw.print(" wake="); + printmAh(pw, bs.wakeLockPowerMah); + } + if (bs.mobileRadioPowerMah != 0) { + pw.print(" radio="); + printmAh(pw, bs.mobileRadioPowerMah); + } + if (bs.wifiPowerMah != 0) { + pw.print(" wifi="); + printmAh(pw, bs.wifiPowerMah); + } + if (bs.gpsPowerMah != 0) { + pw.print(" gps="); + printmAh(pw, bs.gpsPowerMah); + } + if (bs.sensorPowerMah != 0) { + pw.print(" sensor="); + printmAh(pw, bs.sensorPowerMah); + } + if (bs.cameraPowerMah != 0) { + pw.print(" camera="); + printmAh(pw, bs.cameraPowerMah); + } + if (bs.flashlightPowerMah != 0) { + pw.print(" flash="); + printmAh(pw, bs.flashlightPowerMah); + } + pw.print(" )"); + } + pw.println(); } pw.println(); } diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java index 9a08827..eeb69a3 100644 --- a/core/java/android/preference/SeekBarDialogPreference.java +++ b/core/java/android/preference/SeekBarDialogPreference.java @@ -18,29 +18,28 @@ package android.preference; import android.content.Context; import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.SeekBar; +import com.android.internal.R; + /** * @hide */ public class SeekBarDialogPreference extends DialogPreference { - private static final String TAG = "SeekBarDialogPreference"; - - private Drawable mMyIcon; + private final Drawable mMyIcon; public SeekBarDialogPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); createActionButtons(); // Steal the XML dialogIcon attribute's value mMyIcon = getDialogIcon(); + setDialogIcon(null); } @@ -49,7 +48,7 @@ public class SeekBarDialogPreference extends DialogPreference { } public SeekBarDialogPreference(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle); + this(context, attrs, R.attr.seekBarDialogPreferenceStyle); } public SeekBarDialogPreference(Context context) { @@ -58,15 +57,15 @@ public class SeekBarDialogPreference extends DialogPreference { // Allow subclasses to override the action buttons public void createActionButtons() { - setPositiveButtonText(android.R.string.ok); - setNegativeButtonText(android.R.string.cancel); + setPositiveButtonText(R.string.ok); + setNegativeButtonText(R.string.cancel); } @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); - final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); + final ImageView iconView = (ImageView) view.findViewById(R.id.icon); if (mMyIcon != null) { iconView.setImageDrawable(mMyIcon); } else { @@ -75,6 +74,6 @@ public class SeekBarDialogPreference extends DialogPreference { } protected static SeekBar getSeekBar(View dialogView) { - return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + return (SeekBar) dialogView.findViewById(R.id.seekbar); } } diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index a2da01b..573499a 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -26,14 +26,13 @@ import android.view.KeyEvent; import android.view.View; import android.widget.SeekBar; +import com.android.internal.R; + /** * @hide */ public class VolumePreference extends SeekBarDialogPreference implements PreferenceManager.OnActivityStopListener, View.OnKeyListener, SeekBarVolumizer.Callback { - - static final String TAG = "VolumePreference"; - private int mStreamType; /** May be null if the dialog isn't visible. */ @@ -44,7 +43,7 @@ public class VolumePreference extends SeekBarDialogPreference implements super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.VolumePreference, defStyleAttr, defStyleRes); + R.styleable.VolumePreference, defStyleAttr, defStyleRes); mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0); a.recycle(); } @@ -54,7 +53,11 @@ public class VolumePreference extends SeekBarDialogPreference implements } public VolumePreference(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle); + this(context, attrs, R.attr.seekBarDialogPreferenceStyle); + } + + public VolumePreference(Context context) { + this(context, null); } public void setStreamType(int streamType) { @@ -65,7 +68,7 @@ public class VolumePreference extends SeekBarDialogPreference implements protected void onBindDialogView(View view) { super.onBindDialogView(view); - final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); + final SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar); mSeekBarVolumizer = new SeekBarVolumizer(getContext(), mStreamType, null, this); mSeekBarVolumizer.start(); mSeekBarVolumizer.setSeekBar(seekBar); @@ -128,14 +131,17 @@ public class VolumePreference extends SeekBarDialogPreference implements getPreferenceManager().unregisterOnActivityStopListener(this); if (mSeekBarVolumizer != null) { - Dialog dialog = getDialog(); + final Dialog dialog = getDialog(); if (dialog != null && dialog.isShowing()) { - View view = dialog.getWindow().getDecorView() - .findViewById(com.android.internal.R.id.seekbar); - if (view != null) view.setOnKeyListener(null); + final View view = dialog.getWindow().getDecorView().findViewById(R.id.seekbar); + if (view != null) { + view.setOnKeyListener(null); + } + // Stopped while dialog was showing, revert changes mSeekBarVolumizer.revertVolume(); } + mSeekBarVolumizer.stop(); mSeekBarVolumizer = null; } diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 69338b0..30535ff 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -93,6 +93,12 @@ public final class DocumentsContract { public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED"; /** + * Set this in a DocumentsUI intent to cause a package's own roots to be + * excluded from the roots list. + */ + public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; + + /** * Included in {@link AssetFileDescriptor#getExtras()} when returned * thumbnail should be rotated. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 640f434..167d8e5 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -577,6 +577,21 @@ public final class Settings { "android.settings.APPLICATION_DETAILS_SETTINGS"; /** + * Activity Action: Show screen for controlling which apps can ignore battery optimizations. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: The Intent's data URI specifies the application package name + * to be shown, with the "package" scheme. That is "package:com.my.app". + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = + "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; + + /** * @hide * Activity Action: Show the "app ops" settings screen. * <p> diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index b8493d4..8c6cd09 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -646,7 +646,7 @@ public abstract class NotificationListenerService extends Service { private void createLegacyIconExtras(Notification n) { Icon smallIcon = n.getSmallIcon(); Icon largeIcon = n.getLargeIcon(); - if (smallIcon.getType() == Icon.TYPE_RESOURCE) { + if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) { n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId()); n.icon = smallIcon.getResId(); } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 160c662..7d48a9a 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -523,7 +523,7 @@ public class SurfaceView extends View { mVisibleInsets, mStableInsets, mOutsets, mConfiguration, mNewSurface); if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { - mReportDrawNeeded = true; + reportDrawNeeded = true; } if (DEBUG) Log.i(TAG, "New surface: " + mNewSurface diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 94b9416..afc683a 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -618,12 +618,11 @@ public class ListPopupWindow { heightSpec = mDropDownHeight; } - mPopup.setWidth(widthSpec); - mPopup.setHeight(heightSpec); mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.update(getAnchorView(), mDropDownHorizontalOffset, - mDropDownVerticalOffset, -1, -1); + mDropDownVerticalOffset, (widthSpec < 0)? -1 : widthSpec, + (heightSpec < 0)? -1 : heightSpec); } else { final int widthSpec; if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index c77d614..2d0989f 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -361,7 +361,7 @@ public final class FloatingToolbar { mParent = Preconditions.checkNotNull(parent); mContentContainer = createContentContainer(parent.getContext()); mPopupWindow = createPopupWindow(mContentContainer); - mDismissAnimation = createShrinkFadeOutFromBottomAnimation( + mDismissAnimation = createExitAnimation( mContentContainer, 150, // startDelay new AnimatorListenerAdapter() { @@ -371,7 +371,7 @@ public final class FloatingToolbar { mContentContainer.removeAllViews(); } }); - mHideAnimation = createShrinkFadeOutFromBottomAnimation( + mHideAnimation = createExitAnimation( mContentContainer, 0, // startDelay new AnimatorListenerAdapter() { @@ -561,7 +561,7 @@ public final class FloatingToolbar { * Performs the "show" animation on the floating popup. */ private void runShowAnimation() { - createGrowFadeInFromBottom(mContentContainer).start(); + createEnterAnimation(mContentContainer).start(); } /** @@ -1369,38 +1369,35 @@ public final class FloatingToolbar { } /** - * Creates a "grow and fade in from the bottom" animation for the specified view. + * Creates an "appear" animation for the specified view. * * @param view The view to animate */ - private static AnimatorSet createGrowFadeInFromBottom(View view) { - AnimatorSet growFadeInFromBottomAnimation = new AnimatorSet(); - growFadeInFromBottomAnimation.playTogether( - ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125), - ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125), - ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75), + private static AnimatorSet createEnterAnimation(View view) { + AnimatorSet animation = new AnimatorSet(); + animation.playTogether( + ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(200), // Make sure that view.x is always fixed throughout the duration of this animation. ObjectAnimator.ofFloat(view, View.X, view.getX(), view.getX())); - growFadeInFromBottomAnimation.setStartDelay(50); - return growFadeInFromBottomAnimation; + animation.setStartDelay(50); + return animation; } /** - * Creates a "shrink and fade out from bottom" animation for the specified view. + * Creates a "disappear" animation for the specified view. * * @param view The view to animate * @param startDelay The start delay of the animation * @param listener The animation listener */ - private static AnimatorSet createShrinkFadeOutFromBottomAnimation( + private static AnimatorSet createExitAnimation( View view, int startDelay, Animator.AnimatorListener listener) { - AnimatorSet shrinkFadeOutFromBottomAnimation = new AnimatorSet(); - shrinkFadeOutFromBottomAnimation.playTogether( - ObjectAnimator.ofFloat(view, View.SCALE_Y, 1, 0.5f).setDuration(125), - ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(75)); - shrinkFadeOutFromBottomAnimation.setStartDelay(startDelay); - shrinkFadeOutFromBottomAnimation.addListener(listener); - return shrinkFadeOutFromBottomAnimation; + AnimatorSet animation = new AnimatorSet(); + animation.playTogether( + ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(200)); + animation.setStartDelay(startDelay); + animation.addListener(listener); + return animation; } private static int getEstimatedToolbarHeight(Context context) { diff --git a/core/res/res/layout/seekbar_dialog.xml b/core/res/res/layout/preference_dialog_seekbar.xml index 84352a5..4e366c4 100644 --- a/core/res/res/layout/seekbar_dialog.xml +++ b/core/res/res/layout/preference_dialog_seekbar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project +<!-- Copyright (C) 2015 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,20 +15,21 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <ImageView + android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="20dp" /> + + <SeekBar + android:id="@+id/seekbar" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:gravity="center_horizontal"> - - <ImageView android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingTop="20dip" /> - - <SeekBar android:id="@+id/seekbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="20dip" /> - + android:layout_height="wrap_content" + android:padding="20dp" /> + </LinearLayout> - diff --git a/core/res/res/layout/preference_dialog_seekbar_material.xml b/core/res/res/layout/preference_dialog_seekbar_material.xml new file mode 100644 index 0000000..a98a995 --- /dev/null +++ b/core/res/res/layout/preference_dialog_seekbar_material.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <ImageView + android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="?attr/dialogPreferredPadding" /> + + <SeekBar + android:id="@+id/seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="?attr/dialogPreferredPadding" + android:paddingStart="?attr/dialogPreferredPadding" + android:paddingEnd="?attr/dialogPreferredPadding" /> + +</LinearLayout> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index a13f494..0f66950 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -868,6 +868,8 @@ <attr name="dialogPreferenceStyle" format="reference" /> <!-- Default style for EditTextPreference. --> <attr name="editTextPreferenceStyle" format="reference" /> + <!-- @hide Default style for SeekBarDialogPreference. --> + <attr name="seekBarDialogPreferenceStyle" format="reference" /> <!-- Default style for RingtonePreference. --> <attr name="ringtonePreferenceStyle" format="reference" /> <!-- The preference layout that has the child/tabbed effect. --> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 2326968..61f9eef 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1519,10 +1519,10 @@ <string name="policylab_disableCamera">Disable cameras</string> <!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]--> <string name="policydesc_disableCamera">Prevent use of all device cameras.</string> - <!-- Title of policy access to disable all device cameras [CHAR LIMIT=30]--> - <string name="policylab_disableKeyguardFeatures">Disable features of screen lock</string> - <!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]--> - <string name="policydesc_disableKeyguardFeatures">Prevent use of some features of screen lock.</string> + <!-- Title of policy access to disable keyguard features [CHAR LIMIT=30]--> + <string name="policylab_disableKeyguardFeatures">Disable some screen lock features</string> + <!-- Description of policy access to disable keyguard features. [CHAR LIMIT=110]--> + <string name="policydesc_disableKeyguardFeatures">Prevent use of some screen lock features.</string> <!-- The order of these is important, don't reorder without changing Contacts.java --> <skip /> <!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. --> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 4eba117..4bad16d 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1017,6 +1017,10 @@ please see styles_device_defaults.xml. <item name="negativeButtonText">@string/no</item> </style> + <style name="Preference.DialogPreference.SeekBarPreference"> + <item name="dialogLayout">@layout/preference_dialog_seekbar</item> + </style> + <style name="Preference.DialogPreference.EditTextPreference"> <item name="dialogLayout">@layout/preference_dialog_edittext</item> </style> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index df4106e..70f9c02 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -87,6 +87,10 @@ please see styles_device_defaults.xml. <item name="negativeButtonText">@string/no</item> </style> + <style name="Preference.Material.DialogPreference.SeekBarPreference"> + <item name="dialogLayout">@layout/preference_dialog_seekbar_material</item> + </style> + <style name="Preference.Material.DialogPreference.EditTextPreference"> <item name="dialogLayout">@layout/preference_dialog_edittext_material</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 15b253d..099f6c1 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1341,7 +1341,6 @@ <java-symbol type="layout" name="preference_widget_seekbar" /> <java-symbol type="layout" name="progress_dialog" /> <java-symbol type="layout" name="resolve_list_item" /> - <java-symbol type="layout" name="seekbar_dialog" /> <java-symbol type="layout" name="select_dialog_singlechoice_holo" /> <java-symbol type="layout" name="ssl_certificate" /> <java-symbol type="layout" name="tab_content" /> @@ -2292,4 +2291,5 @@ <java-symbol type="string" name="config_radio_access_family" /> <java-symbol type="string" name="notification_inbox_ellipsis" /> <java-symbol type="bool" name="config_mainBuiltInDisplayIsRound" /> + <java-symbol type="attr" name="seekBarDialogPreferenceStyle" /> </resources> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 9e87b4d..1230b5e 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -331,6 +331,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child</item> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 9f3668d..9fe8df4 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -295,6 +295,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.Material.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.Material.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child_material</item> @@ -651,6 +652,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.Material.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.Material.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child_material</item> diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 1af48ca..134451b 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -333,17 +333,29 @@ public class RippleDrawable extends LayerDrawable { */ @Override public boolean isProjected() { - // If the maximum radius is contained entirely within the bounds, we - // don't need to project this ripple. + // If the layer is bounded, then we don't need to project. + if (isBounded()) { + return false; + } + + // Otherwise, if the maximum radius is contained entirely within the + // bounds then we don't need to project. This is sort of a hack to + // prevent check box ripples from being projected across the edges of + // scroll views. It does not impact rendering performance, and it can + // be removed once we have better handling of projection in scrollable + // views. final int radius = mState.mMaxRadius; - final Rect bounds = getBounds(); - if (radius != RADIUS_AUTO && radius <= bounds.width() / 2 - && radius <= bounds.height() / 2) { + final Rect drawableBounds = getBounds(); + final Rect hotspotBounds = mHotspotBounds; + if (radius != RADIUS_AUTO + && radius <= hotspotBounds.width() / 2 + && radius <= hotspotBounds.height() / 2 + && (drawableBounds.equals(hotspotBounds) + || drawableBounds.contains(hotspotBounds))) { return false; } - // Otherwise, if the layer is bounded then we don't need to project. - return !isBounded(); + return true; } private boolean isBounded() { diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index cb21131..8ea5816 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.concurrent.Executor; @@ -32,6 +33,10 @@ import libcore.io.IoUtils; import android.app.Activity; import android.app.Fragment; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; @@ -232,9 +237,38 @@ abstract class BaseActivity extends Activity { invalidateOptionsMenu(); } + final List<String> getExcludedAuthorities() { + List<String> authorities = new ArrayList<>(); + if (getIntent().getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false)) { + // Exclude roots provided by the calling package. + String packageName = getCallingPackageMaybeExtra(); + try { + PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, + PackageManager.GET_PROVIDERS); + for (ProviderInfo provider: pkgInfo.providers) { + authorities.add(provider.authority); + } + } catch (PackageManager.NameNotFoundException e) { + Log.e(mTag, "Calling package name does not resolve: " + packageName); + } + } + return authorities; + } + final String getCallingPackageMaybeExtra() { - final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME); - return (extra != null) ? extra : getCallingPackage(); + String callingPackage = getCallingPackage(); + // System apps can set the calling package name using an extra. + try { + ApplicationInfo info = getPackageManager().getApplicationInfo(callingPackage, 0); + if (info.isSystemApp() || info.isUpdatedSystemApp()) { + final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME); + if (extra != null) { + callingPackage = extra; + } + } + } finally { + return callingPackage; + } } public static BaseActivity get(Fragment fragment) { @@ -287,6 +321,9 @@ abstract class BaseActivity extends Activity { /** Currently copying file */ public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>(); + /** Name of the package that started DocsUI */ + public List<String> excludedAuthorities = new ArrayList<>(); + public static final int ACTION_OPEN = 1; public static final int ACTION_CREATE = 2; public static final int ACTION_GET_CONTENT = 3; @@ -327,6 +364,7 @@ abstract class BaseActivity extends Activity { out.writeString(currentSearch); out.writeMap(dirState); out.writeList(selectedDocumentsForCopy); + out.writeList(excludedAuthorities); } public static final Creator<State> CREATOR = new Creator<State>() { @@ -348,6 +386,7 @@ abstract class BaseActivity extends Activity { state.currentSearch = in.readString(); in.readMap(state.dirState, null); in.readList(state.selectedDocumentsForCopy, null); + in.readList(state.excludedAuthorities, null); return state; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index da59d0e..69ae34e 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -256,6 +256,8 @@ public class DocumentsActivity extends BaseActivity { BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false); } + state.excludedAuthorities = getExcludedAuthorities(); + return state; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java index 27e8f20..fbcb938 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java @@ -383,6 +383,12 @@ public class RootsCache { continue; } + // Exclude roots from the calling package. + if (state.excludedAuthorities.contains(root.authority)) { + if (LOGD) Log.d(TAG, "Excluding root " + root.authority + " from calling package."); + continue; + } + matching.add(root); } return matching; diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java index 97d8ed0..ecf4d6c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java +++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java @@ -55,7 +55,6 @@ public class RootInfo implements Durable, Parcelable { public String mimeTypes; /** Derived fields that aren't persisted */ - public String derivedPackageName; public String[] derivedMimeTypes; public int derivedIcon; @@ -75,7 +74,6 @@ public class RootInfo implements Durable, Parcelable { availableBytes = -1; mimeTypes = null; - derivedPackageName = null; derivedMimeTypes = null; derivedIcon = 0; } diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java index 7faa3ce..8c5bac1 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java @@ -114,6 +114,31 @@ public class RootsCacheTest extends AndroidTestCase { RootsCache.getMatchingRoots(mRoots, mState)); } + public void testExcludedAuthorities() throws Exception { + final List<RootInfo> roots = Lists.newArrayList(); + + // Set up some roots + for (int i = 0; i < 5; ++i) { + RootInfo root = new RootInfo(); + root.authority = "authority" + i; + roots.add(root); + } + // Make some allowed authorities + List<RootInfo> allowedRoots = Lists.newArrayList( + roots.get(0), roots.get(2), roots.get(4)); + // Set up the excluded authority list + for (RootInfo root: roots) { + if (!allowedRoots.contains(root)) { + mState.excludedAuthorities.add(root.authority); + } + } + mState.acceptMimes = new String[] { "*/*" }; + + assertContainsExactly( + allowedRoots, + RootsCache.getMatchingRoots(roots, mState)); + } + private static void assertContainsExactly(List<?> expected, List<?> actual) { assertEquals(expected.size(), actual.size()); for (Object o : expected) { diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml index 456d2f9..9912343 100644 --- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml +++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml @@ -3,16 +3,16 @@ ** ** Copyright 2012, 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 +** 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 +** 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 +** 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. --> @@ -48,7 +48,7 @@ android:layout_marginStart="2dp" android:visibility="invisible" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -80,7 +80,7 @@ android:layout_weight="0" android:contentDescription="@string/accessibility_recent" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -120,7 +120,7 @@ android:id="@+id/lights_out" android:visibility="gone" > - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -132,6 +132,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_back" /> <ImageView android:layout_width="128dp" android:paddingStart="25dp" android:paddingEnd="25dp" @@ -139,6 +140,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_home" /> <ImageView android:layout_width="128dp" android:paddingStart="25dp" android:paddingEnd="25dp" @@ -147,8 +149,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_recent" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -193,7 +196,7 @@ android:layout_marginStart="2dp" android:visibility="invisible" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -225,7 +228,7 @@ android:layout_weight="0" android:contentDescription="@string/accessibility_recent" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -264,7 +267,7 @@ android:id="@+id/lights_out" android:visibility="gone" > - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -276,6 +279,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_back" /> <ImageView android:layout_width="162dp" android:paddingStart="42dp" android:paddingEnd="42dp" @@ -283,6 +287,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_home" /> <ImageView android:layout_width="162dp" android:paddingStart="42dp" android:paddingEnd="42dp" @@ -291,8 +296,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_recent" /> - <Space + <Space android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml index 898389d..c92ba45 100644 --- a/packages/SystemUI/res/layout/navigation_bar.xml +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -4,16 +4,16 @@ ** ** Copyright 2011, 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 +** 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 +** 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 +** 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. */ --> @@ -57,7 +57,7 @@ android:scaleType="center" android:contentDescription="@string/accessibility_back" /> - <View + <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" @@ -73,7 +73,7 @@ android:scaleType="center" android:contentDescription="@string/accessibility_home" /> - <View + <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" @@ -130,8 +130,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_back" /> - <View + <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -143,8 +144,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_home" /> - <View + <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" @@ -157,6 +159,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_recent" /> </LinearLayout> @@ -180,7 +183,7 @@ android:paddingTop="0dp" > - <LinearLayout + <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" @@ -225,7 +228,7 @@ android:layout_weight="0" android:contentDescription="@string/accessibility_recent" /> - <View + <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" @@ -241,7 +244,7 @@ android:layout_weight="0" android:contentDescription="@string/accessibility_home" /> - <View + <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" @@ -265,7 +268,7 @@ </LinearLayout> <!-- lights out layout to match exactly --> - <LinearLayout + <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" @@ -279,8 +282,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_recent" /> - <View + <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" @@ -292,8 +296,9 @@ android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_home" /> - <View + <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" @@ -306,6 +311,7 @@ android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" + android:contentDescription="@string/accessibility_back" /> </LinearLayout> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 0e0584f..d972111 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -772,6 +772,9 @@ <!-- Shows when people have clicked on the camera icon [CHAR LIMIT=60] --> <string name="camera_hint">Swipe from icon for camera</string> + <!-- Accessibility content description for Interruption level: None. [CHAR LIMIT=NONE] --> + <string name="interruption_level_none_with_warning">Total silence. This will also silence screen readers.</string> + <!-- Interruption level: None. [CHAR LIMIT=40] --> <string name="interruption_level_none">Total silence</string> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 6e30803..98bbe7c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -552,6 +552,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } public void updateEntry() { + mSortedEntries.remove(HeadsUpEntry.this); long currentTime = mClock.currentTimeMillis(); earliestRemovaltime = currentTime + mMinimumDisplayTime; postTime = Math.max(postTime, currentTime); @@ -561,13 +562,13 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime); mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay); } - updateSortOrder(HeadsUpEntry.this); + mSortedEntries.add(HeadsUpEntry.this); } @Override public int compareTo(HeadsUpEntry o) { return postTime < o.postTime ? 1 - : postTime == o.postTime ? 0 + : postTime == o.postTime ? entry.key.compareTo(o.entry.key) : -1; } @@ -592,16 +593,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } } - /** - * Update the sorted heads up order. - * - * @param headsUpEntry the headsUp that changed - */ - private void updateSortOrder(HeadsUpEntry headsUpEntry) { - mSortedEntries.remove(headsUpEntry); - mSortedEntries.add(headsUpEntry); - } - public static class Clock { public long currentTimeMillis() { return SystemClock.elapsedRealtime(); diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index ced1a3c..a0eb61f 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -153,7 +153,7 @@ public class ZenModePanel extends LinearLayout { mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons); mZenButtons.addButton(R.string.interruption_level_none_twoline, - R.string.interruption_level_none, + R.string.interruption_level_none_with_warning, Global.ZEN_MODE_NO_INTERRUPTIONS); mZenButtons.addButton(R.string.interruption_level_alarms_twoline, R.string.interruption_level_alarms, diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 2f68aa8..9c6e16f 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -100,6 +100,7 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.NetworkStatsFactory; @@ -768,7 +769,8 @@ public class ConnectivityService extends IConnectivityManager.Stub return mNextNetworkRequestId++; } - private int reserveNetId() { + @VisibleForTesting + protected int reserveNetId() { synchronized (mNetworkForNetId) { for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { int netId = mNextNetId; @@ -1665,6 +1667,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; // Overridden for testing purposes to avoid writing to SystemProperties. + @VisibleForTesting protected int getDefaultTcpRwnd() { return SystemProperties.getInt(DEFAULT_TCP_RWND_KEY, 0); } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 577a4f9..23e62e2 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2019,15 +2019,22 @@ public final class ActivityStackSupervisor implements DisplayListener { r, top.task); top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); } else { - // A special case: we need to - // start the activity because it is not currently - // running, and the caller has asked to clear the - // current task to have this activity at the top. + // A special case: we need to start the activity because it is not + // currently running, and the caller has asked to clear the current + // task to have this activity at the top. addingToTask = true; - // Now pretend like this activity is being started - // by the top of its task, so it is put in the - // right place. + // Now pretend like this activity is being started by the top of its + // task, so it is put in the right place. sourceRecord = intentActivity; + TaskRecord task = sourceRecord.task; + if (task != null && task.stack == null) { + // Target stack got cleared when we all activities were removed + // above. Go ahead and reset it. + targetStack = computeStackFocus(sourceRecord, false /* newTask */); + targetStack.addTask( + task, !launchTaskBehind /* toTop */, false /* moving */); + } + } } else if (r.realActivity.equals(intentActivity.task.realActivity)) { // In this case the top activity on the task is the diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 7440b8c..b2ab797 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -346,6 +346,8 @@ public final class DisplayManagerService extends SystemService { synchronized (mTempDisplayStateWorkQueue) { try { // Update the display state within the lock. + // Note that we do not need to schedule traversals here although it + // may happen as a side-effect of displays changing state. synchronized (mSyncRoot) { if (mGlobalDisplayState == state && mGlobalDisplayBrightness == brightness) { @@ -357,8 +359,7 @@ public final class DisplayManagerService extends SystemService { + ", brightness=" + brightness + ")"); mGlobalDisplayState = state; mGlobalDisplayBrightness = brightness; - updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); - scheduleTraversalLocked(false); + applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); } // Setting the display power state can take hundreds of milliseconds @@ -715,6 +716,7 @@ public final class DisplayManagerService extends SystemService { handleDisplayDeviceRemovedLocked(device); } } + private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if (!mDisplayDevices.remove(device)) { @@ -729,7 +731,7 @@ public final class DisplayManagerService extends SystemService { scheduleTraversalLocked(false); } - private void updateGlobalDisplayStateLocked(List<Runnable> workQueue) { + private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { DisplayDevice device = mDisplayDevices.get(i); diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 4823769..6efc99a 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -133,6 +133,8 @@ final class LogicalDisplay { mInfo.overscanBottom = mOverrideDisplayInfo.overscanBottom; mInfo.rotation = mOverrideDisplayInfo.rotation; mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; + mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; + mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; } } return mInfo; diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 0462035..0bddff0 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -174,9 +174,11 @@ final class OverlayDisplayAdapter extends DisplayAdapter { if (width >= MIN_WIDTH && width <= MAX_WIDTH && height >= MIN_HEIGHT && height <= MAX_HEIGHT && densityDpi >= DisplayMetrics.DENSITY_LOW - && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) { + && densityDpi <= DisplayMetrics.DENSITY_XXXHIGH) { modes.add(new OverlayMode(width, height, densityDpi)); continue; + } else { + Slog.w(TAG, "Ignoring out-of-range overlay display mode: " + mode); } } catch (NumberFormatException ex) { } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e2cc3f7..7bdbec6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6368,6 +6368,16 @@ public class PackageManagerService extends IPackageManager.Stub { if ((scanFlags & SCAN_NEW_INSTALL) == 0) { derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); + + // Some system apps still use directory structure for native libraries + // in which case we might end up not detecting abi solely based on apk + // structure. Try to detect abi based on directory structure. + if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && + pkg.applicationInfo.primaryCpuAbi == null) { + setBundledAppAbisAndRoots(pkg, pkgSetting); + setNativeLibraryPaths(pkg); + } + } else { if ((scanFlags & SCAN_MOVE) != 0) { // We haven't run dex-opt for this move (since we've moved the compiled output too) @@ -7273,6 +7283,33 @@ public class PackageManagerService extends IPackageManager.Stub { } /** + * Calculate the abis and roots for a bundled app. These can uniquely + * be determined from the contents of the system partition, i.e whether + * it contains 64 or 32 bit shared libraries etc. We do not validate any + * of this information, and instead assume that the system was built + * sensibly. + */ + private void setBundledAppAbisAndRoots(PackageParser.Package pkg, + PackageSetting pkgSetting) { + final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); + + // If "/system/lib64/apkname" exists, assume that is the per-package + // native library directory to use; otherwise use "/system/lib/apkname". + final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); + setBundledAppAbi(pkg, apkRoot, apkName); + // pkgSetting might be null during rescan following uninstall of updates + // to a bundled app, so accommodate that possibility. The settings in + // that case will be established later from the parsed package. + // + // If the settings aren't null, sync them up with what we've just derived. + // note that apkRoot isn't stored in the package settings. + if (pkgSetting != null) { + pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; + pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; + } + } + + /** * Deduces the ABI of a bundled app and sets the relevant fields on the * parsed pkg object. * diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index feb0285..ab1206b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3129,7 +3129,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void uninstallCaCert(ComponentName admin, String alias) { + public void uninstallCaCerts(ComponentName admin, String[] aliases) { enforceCanManageCaCerts(admin); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); @@ -3137,7 +3137,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { - keyChainConnection.getService().deleteCaCertificate(alias); + for (int i = 0 ; i < aliases.length; i++) { + keyChainConnection.getService().deleteCaCertificate(aliases[i]); + } } catch (RemoteException e) { Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java index 56f1d48c..6684be4 100644 --- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java @@ -235,6 +235,27 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Prevent wrapped ConnectivityService from trying to write to SystemProperties. return 0; } + + @Override + protected int reserveNetId() { + while (true) { + final int netId = super.reserveNetId(); + + // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks + // can have odd side-effects, like network validations succeeding. + final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks(); + boolean overlaps = false; + for (Network network : networks) { + if (netId == network.netId) { + overlaps = true; + break; + } + } + if (overlaps) continue; + + return netId; + } + } } @Override diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index d6a7dd1..588f8c6 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -91,6 +91,7 @@ public class UsbDeviceManager { private static final int MSG_SYSTEM_READY = 3; private static final int MSG_BOOT_COMPLETED = 4; private static final int MSG_USER_SWITCHED = 5; + private static final int MSG_SET_USB_DATA_UNLOCKED = 6; private static final int AUDIO_MODE_SOURCE = 1; @@ -314,6 +315,7 @@ public class UsbDeviceManager { // current USB state private boolean mConnected; private boolean mConfigured; + private boolean mUsbDataUnlocked; private String mCurrentFunctions; private UsbAccessory mCurrentAccessory; private int mUsbNotificationId; @@ -350,7 +352,7 @@ public class UsbDeviceManager { SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY, "adb"), UsbManager.USB_FUNCTION_ADB); - mCurrentFunctions = mAdbEnabled ? "adb" : "none"; + mCurrentFunctions = mAdbEnabled ? "adb" : UsbManager.USB_FUNCTION_MTP; String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); @@ -459,6 +461,15 @@ public class UsbDeviceManager { } } + /** + * Stop and start the USB driver. This is needed to close all outstanding + * USB connections. + */ + private void restartCurrentFunction() { + setUsbConfig("none"); + setUsbConfig(mCurrentFunctions); + } + private void setEnabledFunctions(String functions) { if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions); @@ -531,6 +542,7 @@ public class UsbDeviceManager { intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(UsbManager.USB_CONNECTED, mConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); + intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked); if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); @@ -599,6 +611,10 @@ public class UsbDeviceManager { case MSG_UPDATE_STATE: mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); + if (!mConnected) { + // When a disconnect occurs, relock access to sensitive user data + mUsbDataUnlocked = false; + } updateUsbNotification(); updateAdbNotification(); if (containsFunction(mCurrentFunctions, @@ -621,6 +637,12 @@ public class UsbDeviceManager { String functions = (String)msg.obj; setEnabledFunctions(functions); break; + case MSG_SET_USB_DATA_UNLOCKED: + mUsbDataUnlocked = (msg.arg1 == 1); + updateUsbNotification(); + updateUsbState(); + restartCurrentFunction(); + break; case MSG_SYSTEM_READY: setUsbConfig(mCurrentFunctions); updatePersistentProperty(); @@ -676,7 +698,9 @@ public class UsbDeviceManager { int id = 0; Resources r = mContext.getResources(); if (mConnected) { - if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { + if (!mUsbDataUnlocked) { + id = com.android.internal.R.string.usb_charging_notification_title; + } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { id = com.android.internal.R.string.usb_mtp_notification_title; } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) { id = com.android.internal.R.string.usb_ptp_notification_title; @@ -771,7 +795,7 @@ public class UsbDeviceManager { } private String getDefaultFunctions() { - return "none"; + return UsbManager.USB_FUNCTION_MTP; } public void dump(FileDescriptor fd, PrintWriter pw) { @@ -817,6 +841,16 @@ public class UsbDeviceManager { mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions); } + public void setUsbDataUnlocked(boolean unlocked) { + if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")"); + mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked); + } + + public boolean isUsbDataUnlocked() { + if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked); + return mHandler.mUsbDataUnlocked; + } + private void readOemUsbOverrideConfig() { String[] configList = mContext.getResources().getStringArray( com.android.internal.R.array.config_oemUsbModeOverride); diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 51281a2..7a3426c 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -271,6 +271,18 @@ public class UsbService extends IUsbManager.Stub { } @Override + public void setUsbDataUnlocked(boolean unlocked) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + mDeviceManager.setUsbDataUnlocked(unlocked); + } + + @Override + public boolean isUsbDataUnlocked() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + return mDeviceManager.isUsbDataUnlocked(); + } + + @Override public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 0042414..9a63aa3 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -27,6 +27,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.view.Surface; @@ -442,8 +443,7 @@ public abstract class Connection extends Conferenceable { private static final int MSG_SET_PAUSE_IMAGE = 11; private static final int MSG_REMOVE_VIDEO_CALLBACK = 12; - private final VideoProvider.VideoProviderHandler - mMessageHandler = new VideoProvider.VideoProviderHandler(); + private VideoProvider.VideoProviderHandler mMessageHandler; private final VideoProvider.VideoProviderBinder mBinder; /** @@ -455,6 +455,14 @@ public abstract class Connection extends Conferenceable { * Default handler used to consolidate binder method calls onto a single thread. */ private final class VideoProviderHandler extends Handler { + public VideoProviderHandler() { + super(); + } + + public VideoProviderHandler(Looper looper) { + super(looper); + } + @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -586,6 +594,18 @@ public abstract class Connection extends Conferenceable { public VideoProvider() { mBinder = new VideoProvider.VideoProviderBinder(); + mMessageHandler = new VideoProvider.VideoProviderHandler(); + } + + /** + * Creates an instance of the {@link VideoProvider}, specifying the looper to use. + * + * @param looper The looper. + * @hide + */ + public VideoProvider(Looper looper) { + mBinder = new VideoProvider.VideoProviderBinder(); + mMessageHandler = new VideoProvider.VideoProviderHandler(looper); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 12f1644..393888d 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -193,7 +193,7 @@ public class TelephonyManager { // /** - * Broadcast intent action indicating that the call state (cellular) + * Broadcast intent action indicating that the call state * on the device has changed. * * <p> @@ -2437,10 +2437,23 @@ public class TelephonyManager { public static final int CALL_STATE_OFFHOOK = 2; /** - * Returns a constant indicating the call state (cellular) on the device. + * Returns one of the following constants that represents the current state of all + * phone calls. + * + * {@link TelephonyManager#CALL_STATE_RINGING} + * {@link TelephonyManager#CALL_STATE_OFFHOOK} + * {@link TelephonyManager#CALL_STATE_IDLE} */ public int getCallState() { - return getCallState(getDefaultSubscription()); + try { + ITelecomService telecom = getTelecomService(); + if (telecom != null) { + return telecom.getCallState(); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelecomService#getCallState", e); + } + return CALL_STATE_IDLE; } /** |
