diff options
108 files changed, 1414 insertions, 306 deletions
diff --git a/Android.mk b/Android.mk index fad3f1396af2..f0828b7552b4 100644 --- a/Android.mk +++ b/Android.mk @@ -119,6 +119,12 @@ LOCAL_SRC_FILES += \ core/java/android/content/pm/IPackageMoveObserver.aidl \ core/java/android/content/pm/IPackageStatsObserver.aidl \ core/java/android/database/IContentObserver.aidl \ + core/java/android/hardware/ICameraService.aidl \ + core/java/android/hardware/ICameraServiceListener.aidl \ + core/java/android/hardware/ICamera.aidl \ + core/java/android/hardware/ICameraClient.aidl \ + core/java/android/hardware/IProCameraUser.aidl \ + core/java/android/hardware/IProCameraCallbacks.aidl \ core/java/android/hardware/ISerialManager.aidl \ core/java/android/hardware/display/IDisplayManager.aidl \ core/java/android/hardware/display/IDisplayManagerCallback.aidl \ diff --git a/api/current.txt b/api/current.txt index aa6163fda59b..bb070c7cdb16 100644 --- a/api/current.txt +++ b/api/current.txt @@ -514,7 +514,7 @@ package android { field public static final int freezesText = 16843116; // 0x101016c field public static final int fromAlpha = 16843210; // 0x10101ca field public static final int fromDegrees = 16843187; // 0x10101b3 - field public static final int fromScene = 16843740; // 0x10103dc + field public static final int fromScene = 16843741; // 0x10103dd field public static final int fromXDelta = 16843206; // 0x10101c6 field public static final int fromXScale = 16843202; // 0x10101c2 field public static final int fromYDelta = 16843208; // 0x10101c8 @@ -629,7 +629,7 @@ package android { field public static final int keyboardLayout = 16843691; // 0x10103ab field public static final int keyboardMode = 16843341; // 0x101024d field public static final int keycode = 16842949; // 0x10100c5 - field public static final int keyset = 16843738; // 0x10103da + field public static final int keyset = 16843739; // 0x10103db field public static final int killAfterRestore = 16843420; // 0x101029c field public static final int label = 16842753; // 0x1010001 field public static final int labelFor = 16843718; // 0x10103c6 @@ -642,6 +642,7 @@ package android { field public static final int layout = 16842994; // 0x10100f2 field public static final int layoutAnimation = 16842988; // 0x10100ec field public static final int layoutDirection = 16843698; // 0x10103b2 + field public static final int layoutMode = 16843738; // 0x10103da field public static final int layout_above = 16843140; // 0x1010184 field public static final int layout_alignBaseline = 16843142; // 0x1010186 field public static final int layout_alignBottom = 16843146; // 0x101018a @@ -1015,7 +1016,7 @@ package android { field public static final int targetActivity = 16843266; // 0x1010202 field public static final int targetClass = 16842799; // 0x101002f field public static final int targetDescriptions = 16843680; // 0x10103a0 - field public static final int targetID = 16843739; // 0x10103db + field public static final int targetID = 16843740; // 0x10103dc field public static final int targetPackage = 16842785; // 0x1010021 field public static final int targetSdkVersion = 16843376; // 0x1010270 field public static final int taskAffinity = 16842770; // 0x1010012 @@ -1104,7 +1105,7 @@ package android { field public static final int titleTextStyle = 16843512; // 0x10102f8 field public static final int toAlpha = 16843211; // 0x10101cb field public static final int toDegrees = 16843188; // 0x10101b4 - field public static final int toScene = 16843741; // 0x10103dd + field public static final int toScene = 16843742; // 0x10103de field public static final int toXDelta = 16843207; // 0x10101c7 field public static final int toXScale = 16843203; // 0x10101c3 field public static final int toYDelta = 16843209; // 0x10101c9 @@ -1119,7 +1120,7 @@ package android { field public static final int transcriptMode = 16843008; // 0x1010100 field public static final int transformPivotX = 16843552; // 0x1010320 field public static final int transformPivotY = 16843553; // 0x1010321 - field public static final int transition = 16843742; // 0x10103de + field public static final int transition = 16843743; // 0x10103df field public static final int translationX = 16843554; // 0x1010322 field public static final int translationY = 16843555; // 0x1010323 field public static final int type = 16843169; // 0x10101a1 @@ -2882,6 +2883,7 @@ package android.app { } public class ActivityManager { + method public void dumpPackageState(java.io.FileDescriptor, java.lang.String); method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo(); method public int getLargeMemoryClass(); method public int getLauncherLargeIconDensity(); @@ -12150,6 +12152,7 @@ package android.media { ctor public MediaExtractor(); method public boolean advance(); method public long getCachedDuration(); + method public java.util.Map<java.util.UUID, byte[]> getPsshInfo(); method public boolean getSampleCryptoInfo(android.media.MediaCodec.CryptoInfo); method public int getSampleFlags(); method public long getSampleTime(); @@ -26343,6 +26346,7 @@ package android.view { method public float getY(); method public boolean hasFocus(); method public boolean hasFocusable(); + method public boolean hasLayout(); method public boolean hasOnClickListeners(); method public boolean hasOverlappingRendering(); method public boolean hasTransientState(); @@ -26355,6 +26359,7 @@ package android.view { method public void invalidate(); method public void invalidateDrawable(android.graphics.drawable.Drawable); method public boolean isActivated(); + method public boolean isAttachedToWindow(); method public boolean isClickable(); method public boolean isDirty(); method public boolean isDrawingCacheEnabled(); @@ -28512,6 +28517,7 @@ package android.view.transition { public class TransitionManager { ctor public TransitionManager(); + method public static void beginDelayedTransition(android.view.ViewGroup, android.view.transition.Transition); method public android.view.transition.Transition getDefaultTransition(); method public static void go(android.view.transition.Scene); method public static void go(android.view.transition.Scene, android.view.transition.Transition); diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 224945ad4901..6f57ae0b9d59 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -16,8 +16,7 @@ package com.android.commands.pm; -import com.android.internal.content.PackageHelper; - +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.content.ComponentName; import android.content.pm.ApplicationInfo; @@ -46,6 +45,7 @@ import android.os.UserHandle; import android.os.UserManager; import java.io.File; +import java.io.FileDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.InvalidAlgorithmParameterException; @@ -59,6 +59,8 @@ import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import com.android.internal.content.PackageHelper; + public final class Pm { IPackageManager mPm; IUserManager mUm; @@ -105,6 +107,11 @@ public final class Pm { return; } + if ("dump".equals(op)) { + runDump(); + return; + } + if ("install".equals(op)) { runInstall(); return; @@ -672,6 +679,15 @@ public final class Pm { displayPackageFilePath(pkg); } + private void runDump() { + String pkg = nextArg(); + if (pkg == null) { + System.err.println("Error: no package specified"); + return; + } + ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg); + } + class PackageInstallObserver extends IPackageInstallObserver.Stub { boolean finished; int result; @@ -1456,6 +1472,7 @@ public final class Pm { System.err.println(" pm list libraries"); System.err.println(" pm list users"); System.err.println(" pm path PACKAGE"); + System.err.println(" pm dump PACKAGE"); System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]"); System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]"); System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH"); @@ -1506,6 +1523,8 @@ public final class Pm { System.err.println(""); System.err.println("pm path: print the path to the .apk of the given PACKAGE."); System.err.println(""); + System.err.println("pm dump: print system state associated w ith the given PACKAGE."); + System.err.println(""); System.err.println("pm install: installs a package to the system. Options:"); System.err.println(" -l: install the package with FORWARD_LOCK."); System.err.println(" -r: reinstall an exisiting app, keeping its data."); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 63ac42e30417..f523b55404ad 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -16,8 +16,10 @@ package android.app; +import android.os.IBinder; import com.android.internal.app.IUsageStats; import com.android.internal.os.PkgUsageStats; +import com.android.internal.os.TransferPipe; import com.android.internal.util.MemInfoReader; import android.content.ComponentName; @@ -49,6 +51,9 @@ import android.util.Log; import android.util.Slog; import android.view.Display; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.PrintWriter; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -1709,7 +1714,7 @@ public class ActivityManager { public ComponentName importanceReasonComponent; /** - * When {@link importanceReasonPid} is non-0, this is the importance + * When {@link #importanceReasonPid} is non-0, this is the importance * of the other pid. @hide */ public int importanceReasonImportance; @@ -2181,4 +2186,54 @@ public class ActivityManager { return false; } } + + /** + * Perform a system dump of various state associated with the given application + * package name. This call blocks while the dump is being performed, so should + * not be done on a UI thread. The data will be written to the given file + * descriptor as text. An application must hold the + * {@link android.Manifest.permission#DUMP} permission to make this call. + * @param fd The file descriptor that the dump should be written to. + * @param packageName The name of the package that is to be dumped. + */ + public void dumpPackageState(FileDescriptor fd, String packageName) { + dumpPackageStateStatic(fd, packageName); + } + + /** + * @hide + */ + public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) { + FileOutputStream fout = new FileOutputStream(fd); + PrintWriter pw = new PrintWriter(fout); + dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] { "package", packageName}); + pw.println(); + dumpService(pw, fd, "package", new String[] { packageName}); + pw.println(); + dumpService(pw, fd, "batteryinfo", new String[] { packageName}); + pw.flush(); + } + + private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) { + pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":"); + IBinder service = ServiceManager.checkService(name); + if (service == null) { + pw.println(" (Service not found)"); + return; + } + TransferPipe tp = null; + try { + pw.flush(); + tp = new TransferPipe(); + tp.setBufferPrefix(" "); + service.dump(tp.getWriteFd().getFileDescriptor(), args); + tp.go(fd); + } catch (Throwable e) { + if (tp != null) { + tp.kill(); + } + pw.println("Failure dumping service:"); + e.printStackTrace(pw); + } + } } diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 634fa30c1c40..cda2c5f3b7c5 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -306,6 +306,7 @@ public class Dialog implements DialogInterface, Window.Callback, * method to do cleanup when the dialog is dismissed, instead implement * that in {@link #onStop}. */ + @Override public void dismiss() { if (Looper.myLooper() == mHandler.getLooper()) { dismissDialog(); @@ -325,7 +326,7 @@ public class Dialog implements DialogInterface, Window.Callback, } try { - mWindowManager.removeView(mDecor); + mWindowManager.removeViewImmediate(mDecor); } finally { if (mActionMode != null) { mActionMode.finish(); @@ -334,7 +335,7 @@ public class Dialog implements DialogInterface, Window.Callback, mWindow.closeAllPanels(); onStop(); mShowing = false; - + sendDismissMessage(); } } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 7a0f3769e5da..bffbb519a89a 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1696,6 +1696,9 @@ public class Notification implements Parcelable extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate); extras.putBoolean(EXTRA_SHOW_CHRONOMETER, mUseChronometer); extras.putBoolean(EXTRA_SHOW_WHEN, mShowWhen); + if (mLargeIcon != null) { + extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon); + } } /** diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 79bb476cb212..72ecda1211e5 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -36,6 +36,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.HashMap; import java.util.LinkedList; +import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.Set; @@ -433,7 +434,7 @@ public final class BluetoothAdapter { if (address == null || address.length != 6) { throw new IllegalArgumentException("Bluetooth address must have 6 bytes"); } - return new BluetoothDevice(String.format("%02X:%02X:%02X:%02X:%02X:%02X", + return new BluetoothDevice(String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", address[0], address[1], address[2], address[3], address[4], address[5])); } diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index a19341c07da4..d10eaea2fba1 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.Locale; import java.util.UUID; import android.net.LocalSocket; import java.nio.ByteOrder; @@ -473,7 +474,7 @@ public final class BluetoothSocket implements Closeable { return mPort; } private String convertAddr(final byte[] addr) { - return String.format("%02X:%02X:%02X:%02X:%02X:%02X", + return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0] , addr[1], addr[2], addr[3] , addr[4], addr[5]); } private String waitSocketSignal(InputStream is) throws IOException { diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index ac42b76e2ba2..feb47aa6d381 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -2769,21 +2769,24 @@ public class Camera { * JPEG {@link PictureCallback}. The camera driver may set orientation * in the EXIF header without rotating the picture. Or the driver may * rotate the picture and the EXIF thumbnail. If the Jpeg picture is - * rotated, the orientation in the EXIF header will be missing or 1 - * (row #0 is top and column #0 is left side). - * - * <p>If applications want to rotate the picture to match the orientation - * of what users see, apps should use {@link - * android.view.OrientationEventListener} and {@link CameraInfo}. - * The value from OrientationEventListener is relative to the natural - * orientation of the device. CameraInfo.orientation is the angle - * between camera orientation and natural device orientation. The sum - * of the two is the rotation angle for back-facing camera. The - * difference of the two is the rotation angle for front-facing camera. - * Note that the JPEG pictures of front-facing cameras are not mirrored - * as in preview display. - * - * <p>For example, suppose the natural orientation of the device is + * rotated, the orientation in the EXIF header will be missing or 1 (row + * #0 is top and column #0 is left side). + * + * <p> + * If applications want to rotate the picture to match the orientation + * of what users see, apps should use + * {@link android.view.OrientationEventListener} and + * {@link android.hardware.Camera.CameraInfo}. The value from + * OrientationEventListener is relative to the natural orientation of + * the device. CameraInfo.orientation is the angle between camera + * orientation and natural device orientation. The sum of the two is the + * rotation angle for back-facing camera. The difference of the two is + * the rotation angle for front-facing camera. Note that the JPEG + * pictures of front-facing cameras are not mirrored as in preview + * display. + * + * <p> + * For example, suppose the natural orientation of the device is * portrait. The device is rotated 270 degrees clockwise, so the device * orientation is 270. Suppose a back-facing camera sensor is mounted in * landscape and the top side of the camera sensor is aligned with the diff --git a/core/java/android/hardware/CameraInfo.aidl b/core/java/android/hardware/CameraInfo.aidl new file mode 100644 index 000000000000..e21e6941e976 --- /dev/null +++ b/core/java/android/hardware/CameraInfo.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +parcelable CameraInfo; diff --git a/core/java/android/hardware/CameraInfo.java b/core/java/android/hardware/CameraInfo.java new file mode 100644 index 000000000000..53da0ce00e39 --- /dev/null +++ b/core/java/android/hardware/CameraInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Information about a camera + * + * @hide + */ +public class CameraInfo implements Parcelable { + // Can't parcel nested classes, so make this a top level class that composes + // CameraInfo. + public Camera.CameraInfo info = new Camera.CameraInfo(); + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(info.facing); + out.writeInt(info.orientation); + } + + public void readFromParcel(Parcel in) { + info.facing = in.readInt(); + info.orientation = in.readInt(); + } + + public static final Parcelable.Creator<CameraInfo> CREATOR = + new Parcelable.Creator<CameraInfo>() { + @Override + public CameraInfo createFromParcel(Parcel in) { + CameraInfo info = new CameraInfo(); + info.readFromParcel(in); + + return info; + } + + @Override + public CameraInfo[] newArray(int size) { + return new CameraInfo[size]; + } + }; +}; diff --git a/core/java/android/hardware/ICamera.aidl b/core/java/android/hardware/ICamera.aidl new file mode 100644 index 000000000000..d4f64f8468b3 --- /dev/null +++ b/core/java/android/hardware/ICamera.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +interface ICamera +{ + /** + * Keep up-to-date with frameworks/av/include/camera/ICamera.h + */ + void disconnect(); +} diff --git a/core/java/android/hardware/ICameraClient.aidl b/core/java/android/hardware/ICameraClient.aidl new file mode 100644 index 000000000000..d7877b4be956 --- /dev/null +++ b/core/java/android/hardware/ICameraClient.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +interface ICameraClient +{ + /** + * Keep up-to-date with frameworks/av/include/camera/ICameraClient.h + */ + // TODO: consider implementing this. +} diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl new file mode 100644 index 000000000000..b8fbfdbf8448 --- /dev/null +++ b/core/java/android/hardware/ICameraService.aidl @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +import android.hardware.ICamera; +import android.hardware.ICameraClient; +import android.hardware.IProCameraUser; +import android.hardware.IProCameraCallbacks; +import android.hardware.ICameraServiceListener; +import android.hardware.CameraInfo; + +/** @hide */ +interface ICameraService +{ + /** + * Keep up-to-date with frameworks/av/include/camera/ICameraService.h + */ + int getNumberOfCameras(); + + // rest of 'int' return values in this file are actually status_t + + int getCameraInfo(int cameraId, out CameraInfo info); + + ICamera connect(ICameraClient client, int cameraId, + String clientPackageName, + int clientUid); + + IProCameraUser connectPro(IProCameraCallbacks callbacks, int cameraId, + String clientPackageName, + int clientUid); + + int addListener(ICameraServiceListener listener); + int removeListener(ICameraServiceListener listener); +} diff --git a/core/java/android/hardware/ICameraServiceListener.aidl b/core/java/android/hardware/ICameraServiceListener.aidl new file mode 100644 index 000000000000..c548496525ea --- /dev/null +++ b/core/java/android/hardware/ICameraServiceListener.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +interface ICameraServiceListener +{ + /** + * Keep up-to-date with frameworks/av/include/camera/ICameraServiceListener.h + */ + void onStatusChanged(int status, int cameraId); +} diff --git a/core/java/android/hardware/IProCameraCallbacks.aidl b/core/java/android/hardware/IProCameraCallbacks.aidl new file mode 100644 index 000000000000..a09b452176bd --- /dev/null +++ b/core/java/android/hardware/IProCameraCallbacks.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +interface IProCameraCallbacks +{ + /** + * Keep up-to-date with frameworks/av/include/camera/IProCameraCallbacks.h + */ + // TODO: consider implementing this. +} diff --git a/core/java/android/hardware/IProCameraUser.aidl b/core/java/android/hardware/IProCameraUser.aidl new file mode 100644 index 000000000000..eacb0f48a91e --- /dev/null +++ b/core/java/android/hardware/IProCameraUser.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +/** @hide */ +interface IProCameraUser +{ + /** + * Keep up-to-date with frameworks/av/include/camera/IProCameraUser.h + */ + void disconnect(); +} diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 4ab479e23942..333fcc67bc99 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -21,6 +21,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException; import java.util.Collection; +import java.util.Locale; import android.util.Log; @@ -223,7 +224,7 @@ public class NetworkUtils { public static InetAddress hexToInet6Address(String addrHexString) throws IllegalArgumentException { try { - return numericToInetAddress(String.format("%s:%s:%s:%s:%s:%s:%s:%s", + return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s", addrHexString.substring(0,4), addrHexString.substring(4,8), addrHexString.substring(8,12), addrHexString.substring(12,16), addrHexString.substring(16,20), addrHexString.substring(20,24), diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index 65d3f2b27673..733de949a5e8 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -17,8 +17,8 @@ package android.net; import android.app.Activity; -import android.app.Service; import android.app.PendingIntent; +import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; @@ -30,10 +30,10 @@ import android.os.ServiceManager; import com.android.internal.net.VpnConfig; -import java.net.InetAddress; +import java.net.DatagramSocket; import java.net.Inet4Address; import java.net.Inet6Address; -import java.net.DatagramSocket; +import java.net.InetAddress; import java.net.Socket; import java.util.ArrayList; @@ -329,7 +329,8 @@ public class VpnService extends Service { throw new IllegalArgumentException("Bad address"); } - mAddresses.append(' ' + address.getHostAddress() + '/' + prefixLength); + mAddresses.append(' ') + .append(address.getHostAddress()).append('/').append(prefixLength); return this; } @@ -364,7 +365,7 @@ public class VpnService extends Service { } } - mRoutes.append(String.format(" %s/%d", address.getHostAddress(), prefixLength)); + mRoutes.append(' ').append(address.getHostAddress()).append('/').append(prefixLength); return this; } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 32bbfbd3c609..fef18182ce85 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2279,7 +2279,7 @@ public abstract class BatteryStats implements Parcelable { * @param pw a Printer to receive the dump output. */ @SuppressWarnings("unused") - public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { + public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) { prepareForDumpLocked(); long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); @@ -2336,11 +2336,11 @@ public abstract class BatteryStats implements Parcelable { pw.println("Statistics since last charge:"); pw.println(" System starts: " + getStartCount() + ", currently on battery: " + getIsOnBattery()); - dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); + dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid); pw.println(""); } pw.println("Statistics since last unplugged:"); - dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1); + dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid); } @SuppressWarnings("unused") diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index bfea9cadef89..2e0e59bc91c9 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -164,11 +164,19 @@ public abstract class NotificationListenerService extends Service { private class INotificationListenerWrapper extends INotificationListener.Stub { @Override public void onNotificationPosted(StatusBarNotification sbn) { - NotificationListenerService.this.onNotificationPosted(sbn); + try { + NotificationListenerService.this.onNotificationPosted(sbn); + } catch (Throwable t) { + Log.w(TAG, "Error running onNotificationPosted", t); + } } @Override public void onNotificationRemoved(StatusBarNotification sbn) { - NotificationListenerService.this.onNotificationRemoved(sbn); + try { + NotificationListenerService.this.onNotificationRemoved(sbn); + } catch (Throwable t) { + Log.w(TAG, "Error running onNotificationRemoved", t); + } } } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 55a8f747b5b2..e860dcaab2e4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2195,6 +2195,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2; + /** + * Flag indicating that the view has been through at least one layout since it + * was last attached to a window. + */ + static final int PFLAG3_HAS_LAYOUT = 0x4; + /* End of masks for mPrivateFlags3 */ @@ -6138,6 +6144,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Returns true if this view is currently attached to a window. + */ + public boolean isAttachedToWindow() { + return mAttachInfo != null; + } + + /** + * Returns true if this view has been through at least one layout since it + * was last attached to or detached from a window. + */ + public boolean hasLayout() { + return (mPrivateFlags3 & PFLAG3_HAS_LAYOUT) == PFLAG3_HAS_LAYOUT; + } + + /** * If this view doesn't do any drawing on its own, set this flag to * allow further optimizations. By default, this flag is not set on * View, but could be set on some View subclasses such as ViewGroup. @@ -7024,7 +7045,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - private void notifySubtreeAccessibilityStateChangedIfNeeded() { + public void notifySubtreeAccessibilityStateChangedIfNeeded() { if (!AccessibilityManager.getInstance(mContext).isEnabled()) { return; } @@ -11779,6 +11800,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH; } + mPrivateFlags3 &= ~PFLAG3_HAS_LAYOUT; + jumpDrawablesToCurrentState(); clearAccessibilityFocus(); @@ -12065,6 +12088,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ protected void onDetachedFromWindow() { mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT; + mPrivateFlags3 &= ~PFLAG3_HAS_LAYOUT; removeUnsetPressCallback(); removeLongPressCallback(); @@ -14371,6 +14395,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; + mPrivateFlags3 |= PFLAG3_HAS_LAYOUT; } /** @@ -18867,6 +18892,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final long minEventIntevalMillis = ViewConfiguration.getSendRecurringAccessibilityEventsInterval(); if (timeSinceLastMillis >= minEventIntevalMillis) { + removeCallbacks(this); run(); } else { postDelayed(this, minEventIntevalMillis - timeSinceLastMillis); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index caed4a27d495..29b2e4bea80c 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3595,7 +3595,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } if (child.isImportantForAccessibility() && child.getVisibility() != View.GONE) { - childAccessibilityStateChanged(child); + notifySubtreeAccessibilityStateChangedIfNeeded(); } } @@ -3838,7 +3838,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager onViewRemoved(view); if (view.isImportantForAccessibility() && view.getVisibility() != View.GONE) { - childAccessibilityStateChanged(view); + notifySubtreeAccessibilityStateChangedIfNeeded(); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a5f92de09294..60d8a75c749c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2787,6 +2787,7 @@ public final class ViewRootImpl implements ViewParent, setAccessibilityFocus(null, null); + mView.assignParent(null); mView = null; mAttachInfo.mRootView = null; mAttachInfo.mSurface = null; @@ -6397,12 +6398,10 @@ public final class ViewRootImpl implements ViewParent, public void run() { mLastEventTimeMillis = SystemClock.uptimeMillis(); - if (AccessibilityManager.getInstance(mContext).isEnabled()) { - AccessibilityEvent event = AccessibilityEvent.obtain(); - event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); - event.setContentChangeType(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE); - mSource.sendAccessibilityEventUnchecked(event); - } + AccessibilityEvent event = AccessibilityEvent.obtain(); + event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + event.setContentChangeType(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE); + mSource.sendAccessibilityEventUnchecked(event); mSource.resetSubtreeAccessibilityStateChanged(); mSource = null; } @@ -6417,6 +6416,7 @@ public final class ViewRootImpl implements ViewParent, final long minEventIntevalMillis = ViewConfiguration.getSendRecurringAccessibilityEventsInterval(); if (timeSinceLastMillis >= minEventIntevalMillis) { + mSource.removeCallbacks(this); run(); } else { mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis); diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 6bcf863aa6e6..f7b85cc7436c 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -335,15 +335,13 @@ public final class WindowManagerGlobal { } } root.die(immediate); + if (view != null) { + view.assignParent(null); + } } void doRemoveView(ViewRootImpl root) { synchronized (mLock) { - final View view = root.getView(); - if (view != null) { - view.assignParent(null); - } - final int index = mRoots.indexOf(root); if (index >= 0) { mRoots.remove(index); diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java index 4971a92466b3..8088f6b2c23d 100644 --- a/core/java/android/view/transition/TransitionManager.java +++ b/core/java/android/view/transition/TransitionManager.java @@ -19,6 +19,8 @@ import android.util.ArrayMap; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import java.util.ArrayList; + /** * This class manages the set of transitions that fire when there is a * change of {@link Scene}. To use the manager, add scenes along with @@ -41,8 +43,10 @@ public class TransitionManager { new ArrayMap<Scene, ArrayMap<Scene, Transition>>(); static ArrayMap<ViewGroup, Transition> sRunningTransitions = new ArrayMap<ViewGroup, Transition>(); + private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>(); + - /** + /** * Sets the transition to be used for any scene change for which no * other transition is explicitly set. The initial value is * an {@link AutoTransition} instance. @@ -142,24 +146,15 @@ public class TransitionManager { final ViewGroup sceneRoot = scene.getSceneRoot(); - Transition runningTransition = sRunningTransitions.get(sceneRoot); - if (runningTransition != null) { - runningTransition.cancelTransition(); - } - - // Capture current values - if (transition != null) { - transition.captureValues(sceneRoot, true); - } - - // Notify previous scene that it is being exited - Scene previousScene = sceneRoot.getCurrentScene(); - if (previousScene != null) { - previousScene.exit(); - } + sceneChangeSetup(sceneRoot, transition); scene.enter(); + sceneChangeRunTransition(sceneRoot, transition); + } + + private static void sceneChangeRunTransition(final ViewGroup sceneRoot, + final Transition transition) { if (transition != null) { final ViewTreeObserver observer = sceneRoot.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @@ -181,6 +176,25 @@ public class TransitionManager { } } + private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) { + + Transition runningTransition = sRunningTransitions.get(sceneRoot); + if (runningTransition != null) { + runningTransition.cancelTransition(); + } + + // Capture current values + if (transition != null) { + transition.captureValues(sceneRoot, true); + } + + // Notify previous scene that it is being exited + Scene previousScene = sceneRoot.getCurrentScene(); + if (previousScene != null) { + previousScene.exit(); + } + } + /** * Change to the given scene, using the * appropriate transition for this particular scene change @@ -272,4 +286,47 @@ public class TransitionManager { scene.setEnterAction(action); changeScene(scene, transition); } + + /** + * Static utility method to animate to a new scene defined by all changes within + * the given scene root between calling this method and the next rendering frame. + * Calling this method causes TransitionManager to capture current values in the + * scene root and then post a request to run a transition on the next frame. + * At that time, the new values in the scene root will be captured and changes + * will be animated. There is no need to create a Scene; it is implied by + * changes which take place between calling this method and the next frame when + * the transition begins. + * + * <p>Calling this method several times before the next frame (for example, if + * unrelated code also wants to make dynamic changes and run a transition on + * the same scene root), only the first call will trigger capturing values + * and exiting the current scene. Subsequent calls to the method with the + * same scene root during the same frame will be ignored.</p> + * + * <p>Passing in <code>null</code> for the transition parameter will + * cause the TransitionManager to use its default transition.</p> + * + * @param sceneRoot The root of the View hierarchy to run the transition on. + * @param transition The transition to use for this change. A + * value of null causes the TransitionManager to use the default transition. + */ + public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) { + + if (!sPendingTransitions.contains(sceneRoot)) { + sPendingTransitions.add(sceneRoot); + if (transition == null) { + transition = sDefaultTransition; + } + final Transition finalTransition = transition; + sceneChangeSetup(sceneRoot, transition); + sceneRoot.setCurrentScene(null); + sceneRoot.postOnAnimation(new Runnable() { + @Override + public void run() { + sPendingTransitions.remove(sceneRoot); + sceneChangeRunTransition(sceneRoot, finalTransition); + } + }); + } + } } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index ddc8d8266bf4..1991af1d65a9 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -6519,7 +6519,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te int viewType = lp.viewType; final boolean scrapHasTransientState = scrap.hasTransientState(); if (!shouldRecycleViewType(viewType) || scrapHasTransientState) { - if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) { + if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER && scrapHasTransientState) { if (mSkippedScrap == null) { mSkippedScrap = new ArrayList<View>(); } @@ -6593,7 +6593,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final boolean scrapHasTransientState = victim.hasTransientState(); if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) { // Do not move views that should be ignored - if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || + if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER && scrapHasTransientState) { removeDetachedView(victim, false); } diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index 4a2df58c5415..31ab0afa4334 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -1033,7 +1033,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { checkSelectionChanged(); } - childAccessibilityStateChanged(this); + notifySubtreeAccessibilityStateChangedIfNeeded(); } void checkSelectionChanged() { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 38a8c19801f9..949a499d3338 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6038,7 +6038,7 @@ public final class BatteryStatsImpl extends BatteryStats { updateNetworkActivityLocked(); } - public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { + public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) { if (DEBUG) { Printer pr = new PrintWriterPrinter(pw); pr.println("*** Screen timer:"); @@ -6068,6 +6068,6 @@ public final class BatteryStatsImpl extends BatteryStats { pr.println("*** Bluetooth timer:"); mBluetoothOnTimer.logState(pr, " "); } - super.dumpLocked(pw, isUnpluggedOnly); + super.dumpLocked(pw, isUnpluggedOnly, reqUid); } } diff --git a/services/java/com/android/server/am/TransferPipe.java b/core/java/com/android/internal/os/TransferPipe.java index 055c577316fe..068d9148e219 100644 --- a/services/java/com/android/server/am/TransferPipe.java +++ b/core/java/com/android/internal/os/TransferPipe.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.am; +package com.android.internal.os; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -32,7 +32,7 @@ import android.util.Slog; /** * Helper for transferring data through a pipe from a client app. */ -final class TransferPipe implements Runnable { +public final class TransferPipe implements Runnable { static final String TAG = "TransferPipe"; static final boolean DEBUG = false; @@ -53,7 +53,7 @@ final class TransferPipe implements Runnable { String[] args) throws RemoteException; } - TransferPipe() throws IOException { + public TransferPipe() throws IOException { mThread = new Thread(this, "TransferPipe"); mFds = ParcelFileDescriptor.createPipe(); } @@ -62,11 +62,11 @@ final class TransferPipe implements Runnable { return mFds[0]; } - ParcelFileDescriptor getWriteFd() { + public ParcelFileDescriptor getWriteFd() { return mFds[1]; } - void setBufferPrefix(String prefix) { + public void setBufferPrefix(String prefix) { mBufferPrefix = prefix; } @@ -120,11 +120,11 @@ final class TransferPipe implements Runnable { } } - void go(FileDescriptor out) throws IOException { + public void go(FileDescriptor out) throws IOException { go(out, DEFAULT_TIMEOUT); } - void go(FileDescriptor out, long timeout) throws IOException { + public void go(FileDescriptor out, long timeout) throws IOException { try { synchronized (this) { mOutFd = out; @@ -173,7 +173,7 @@ final class TransferPipe implements Runnable { } } - void kill() { + public void kill() { closeFd(0); closeFd(1); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6918099e98ae..1643522708ae 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -216,7 +216,8 @@ android:description="@string/permdesc_sendSms" /> <!-- Allows an application (Phone) to send a request to other applications - to handle the respond-via-message action during incoming calls. --> + to handle the respond-via-message action during incoming calls. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" android:permissionGroup="android.permission-group.MESSAGES" android:protectionLevel="signature|system" @@ -240,7 +241,8 @@ android:description="@string/permdesc_receiveMms" /> <!-- Allows an application to receive emergency cell broadcast messages, - to record or display them to the user. Reserved for system apps. + to record or display them to the user. + <p>Not for use by third-party applications. @hide Pending API council approval --> <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST" android:permissionGroup="android.permission-group.MESSAGES" @@ -319,7 +321,8 @@ android:description="@string/permdesc_writeContacts" /> <!-- Allows an application to execute contacts directory search. - This should only be used by ContactsProvider. --> + This should only be used by ContactsProvider. + <p>Not for use by third-party applications. --> <!-- @hide --> <permission android:name="android.permission.BIND_DIRECTORY_SEARCH" android:permissionGroup="android.permission-group.PERSONAL_INFO" @@ -598,15 +601,16 @@ android:label="@string/permlab_accessLocationExtraCommands" android:description="@string/permdesc_accessLocationExtraCommands" /> - <!-- Allows an application to install a location provider into the Location Manager --> + <!-- Allows an application to install a location provider into the Location Manager. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" android:protectionLevel="signature|system" android:label="@string/permlab_installLocationProvider" android:description="@string/permdesc_installLocationProvider" /> <!-- Allows an application to use location features in hardware, - such as the geofencing api - Protected by signature|system protection level --> + such as the geofencing api. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.LOCATION_HARDWARE" android:permissionGroup="android.permission-group.LOCATION" android:protectionLevel="signature|system" /> @@ -769,8 +773,8 @@ android:label="@string/permlab_manageAccounts" android:description="@string/permdesc_manageAccounts" /> - <!-- Allows applications to call into AccountAuthenticators. Only - the system can get this permission. --> + <!-- Allows applications to call into AccountAuthenticators. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCOUNT_MANAGER" android:permissionGroup="android.permission-group.ACCOUNTS" android:protectionLevel="signature" @@ -870,7 +874,8 @@ android:label="@string/permlab_accessMtp" android:description="@string/permdesc_accessMtp" /> - <!-- Allows access to hardware peripherals. Intended only for hardware testing --> + <!-- Allows access to hardware peripherals. Intended only for hardware testing. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.HARDWARE_TEST" android:permissionGroup="android.permission-group.HARDWARE_CONTROLS" android:protectionLevel="signature" @@ -971,7 +976,8 @@ android:description="@string/permdesc_processOutgoingCalls" /> <!-- Allows modification of the telephony state - power on, mmi, etc. - Does not include placing calls. --> + Does not include placing calls. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.MODIFY_PHONE_STATE" android:permissionGroup="android.permission-group.PHONE_CALLS" android:protectionLevel="signature|system" @@ -1265,7 +1271,8 @@ android:description="@string/permgroupdesc_systemClock" android:priority="140" /> - <!-- Allows applications to set the system time --> + <!-- Allows applications to set the system time. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_TIME" android:protectionLevel="signature|system" android:label="@string/permlab_setTime" @@ -1378,7 +1385,8 @@ android:label="@string/permlab_writeSettings" android:description="@string/permdesc_writeSettings" /> - <!-- Allows an application to modify the Google service map. --> + <!-- Allows an application to modify the Google service map. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_GSERVICES" android:protectionLevel="signature|system" android:label="@string/permlab_writeGservices" @@ -1401,7 +1409,8 @@ android:label="@string/permlab_retrieve_window_content" android:description="@string/permdesc_retrieve_window_content" /> - <!-- Modify the global animation scaling factor. --> + <!-- Modify the global animation scaling factor. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ANIMATION_SCALE" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature|system|development" @@ -1459,14 +1468,16 @@ android:label="@string/permlab_broadcastSticky" android:description="@string/permdesc_broadcastSticky" /> - <!-- Allows mounting and unmounting file systems for removable storage. --> + <!-- Allows mounting and unmounting file systems for removable storage. + <p>Not for use by third-party applications.--> <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="system|signature" android:label="@string/permlab_mount_unmount_filesystems" android:description="@string/permdesc_mount_unmount_filesystems" /> - <!-- Allows formatting file systems for removable storage. --> + <!-- Allows formatting file systems for removable storage. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="system|signature" @@ -1513,7 +1524,8 @@ android:label="@string/permlab_asec_rename" android:description="@string/permdesc_asec_rename" /> - <!-- Allows applications to write the apn settings --> + <!-- Allows applications to write the apn settings. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_APN_SETTINGS" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature|system" @@ -1561,7 +1573,7 @@ <eat-comment /> <!-- Group of permissions that are related to development features. These - are not permissions that should appear in normal applications; they + are not permissions that should appear in third-party applications; they protect APIs that are intended only to be used for development purposes. --> <permission-group android:name="android.permission-group.DEVELOPMENT_TOOLS" @@ -1569,15 +1581,16 @@ android:description="@string/permgroupdesc_developmentTools" android:priority="310" /> - <!-- Allows an application to read or write the secure system settings. --> + <!-- Allows an application to read or write the secure system settings. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_SECURE_SETTINGS" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" android:label="@string/permlab_writeSecureSettings" android:description="@string/permdesc_writeSecureSettings" /> - <!-- Allows an application to retrieve state dump information from system - services. --> + <!-- Allows an application to retrieve state dump information from system services. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.DUMP" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" @@ -1585,15 +1598,16 @@ android:description="@string/permdesc_dump" /> <!-- Allows an application to read the low-level system log files. - Log entries can contain the user's private information, - which is why this permission is not available to normal apps. --> + <p>Not for use by third-party applications, because + Log entries can contain the user's private information. --> <permission android:name="android.permission.READ_LOGS" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" android:label="@string/permlab_readLogs" android:description="@string/permdesc_readLogs" /> - <!-- Configure an application for debugging. --> + <!-- Configure an application for debugging. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_DEBUG_APP" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" @@ -1601,7 +1615,8 @@ android:description="@string/permdesc_setDebugApp" /> <!-- Allows an application to set the maximum number of (not needed) - application processes that can be running. --> + application processes that can be running. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_PROCESS_LIMIT" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" @@ -1609,14 +1624,16 @@ android:description="@string/permdesc_setProcessLimit" /> <!-- Allows an application to control whether activities are immediately - finished when put in the background. --> + finished when put in the background. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ALWAYS_FINISH" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" android:label="@string/permlab_setAlwaysFinish" android:description="@string/permdesc_setAlwaysFinish" /> - <!-- Allow an application to request that a signal be sent to all persistent processes --> + <!-- Allow an application to request that a signal be sent to all persistent processes. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES" android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS" android:protectionLevel="signature|system|development" @@ -1628,7 +1645,8 @@ <!-- ==================================== --> <eat-comment /> - <!-- Allows applications to RW to diagnostic resources. --> + <!-- Allows applications to RW to diagnostic resources. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.DIAGNOSTIC" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature" @@ -1636,7 +1654,8 @@ android:label="@string/permlab_diagnostic" /> <!-- Allows an application to open, close, or disable the status bar - and its icons. --> + and its icons. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.STATUS_BAR" android:label="@string/permlab_statusBar" android:description="@string/permdesc_statusBar" @@ -1650,14 +1669,15 @@ android:protectionLevel="signature" /> <!-- Allows an application to force a BACK operation on whatever is the - top activity. --> + top activity. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.FORCE_BACK" android:label="@string/permlab_forceBack" android:description="@string/permdesc_forceBack" android:protectionLevel="signature" /> - <!-- Allows an application to update device statistics. Not for - use by third party apps. --> + <!-- Allows an application to update device statistics. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.UPDATE_DEVICE_STATS" android:label="@string/permlab_updateBatteryStats" android:description="@string/permdesc_updateBatteryStats" @@ -1678,15 +1698,16 @@ android:protectionLevel="signature|system" /> <!-- Allows an application to open windows that are for use by parts - of the system user interface. Not for use by third party apps. --> + of the system user interface. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" android:label="@string/permlab_internalSystemWindow" android:description="@string/permdesc_internalSystemWindow" android:protectionLevel="signature" /> <!-- Allows an application to manage (create, destroy, - Z-order) application tokens in the window manager. This is only - for use by the system. --> + Z-order) application tokens in the window manager. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.MANAGE_APP_TOKENS" android:label="@string/permlab_manageAppTokens" android:description="@string/permdesc_manageAppTokens" @@ -1702,7 +1723,7 @@ <!-- Allows an application to inject user events (keys, touch, trackball) into the event stream and deliver them to ANY window. Without this permission, you can only deliver events to windows in your own process. - Very few applications should need to use this permission. --> + <p>Not for use by third-party applications. --> <permission android:name="android.permission.INJECT_EVENTS" android:label="@string/permlab_injectEvents" android:description="@string/permdesc_injectEvents" @@ -1735,7 +1756,8 @@ <!-- Allows an application to watch and control how activities are started globally in the system. Only for is in debugging - (usually the monkey command). --> + (usually the monkey command). + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ACTIVITY_WATCHER" android:label="@string/permlab_runSetActivityWatcher" android:description="@string/permdesc_runSetActivityWatcher" @@ -1760,14 +1782,16 @@ android:protectionLevel="signature|system" /> <!-- Allows an application to retrieve private information about - the current top activity, such as any assist context it can provide. --> + the current top activity, such as any assist context it can provide. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" android:label="@string/permlab_getTopActivityInfo" android:description="@string/permdesc_getTopActivityInfo" android:protectionLevel="signature" /> <!-- Allows an application to retrieve the current state of keys and - switches. This is only for use by the system. + switches. + <p>Not for use by third-party applications. @deprecated The API that used this permission has been removed. --> <permission android:name="android.permission.READ_INPUT_STATE" android:label="@string/permlab_readInputState" @@ -1817,46 +1841,51 @@ android:protectionLevel="signature" /> <!-- Allows low-level access to setting the orientation (actually - rotation) of the screen. Not for use by normal applications. --> + rotation) of the screen. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ORIENTATION" android:label="@string/permlab_setOrientation" android:description="@string/permdesc_setOrientation" android:protectionLevel="signature" /> <!-- Allows low-level access to setting the pointer speed. - Not for use by normal applications. --> + <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_POINTER_SPEED" android:label="@string/permlab_setPointerSpeed" android:description="@string/permdesc_setPointerSpeed" android:protectionLevel="signature" /> <!-- Allows low-level access to setting the keyboard layout. - Not for use by normal applications. + <p>Not for use by third-party applications. @hide --> <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" android:label="@string/permlab_setKeyboardLayout" android:description="@string/permdesc_setKeyboardLayout" android:protectionLevel="signature" /> - <!-- Allows an application to install packages. --> + <!-- Allows an application to install packages. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.INSTALL_PACKAGES" android:label="@string/permlab_installPackages" android:description="@string/permdesc_installPackages" android:protectionLevel="signature|system" /> - <!-- Allows an application to clear user data --> + <!-- Allows an application to clear user data. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.CLEAR_APP_USER_DATA" android:label="@string/permlab_clearAppUserData" android:description="@string/permdesc_clearAppUserData" android:protectionLevel="signature" /> - <!-- Allows an application to delete cache files. --> + <!-- Allows an application to delete cache files. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.DELETE_CACHE_FILES" android:label="@string/permlab_deleteCacheFiles" android:description="@string/permdesc_deleteCacheFiles" android:protectionLevel="signature|system" /> - <!-- Allows an application to delete packages. --> + <!-- Allows an application to delete packages. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.DELETE_PACKAGES" android:label="@string/permlab_deletePackages" android:description="@string/permdesc_deletePackages" @@ -1870,7 +1899,8 @@ android:protectionLevel="signature|system" /> <!-- Allows an application to change whether an application component (other than its own) is - enabled or not. --> + enabled or not. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" android:label="@string/permlab_changeComponentState" android:description="@string/permdesc_changeComponentState" @@ -1882,14 +1912,16 @@ android:description="@string/permdesc_grantRevokePermissions" android:protectionLevel="signature" /> - <!-- Allows an application to use SurfaceFlinger's low level features --> + <!-- Allows an application to use SurfaceFlinger's low level features. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_SURFACE_FLINGER" android:label="@string/permlab_accessSurfaceFlinger" android:description="@string/permdesc_accessSurfaceFlinger" android:protectionLevel="signature" /> <!-- Allows an application to take screen shots and more generally - get access to the frame buffer data --> + get access to the frame buffer data. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_FRAME_BUFFER" android:label="@string/permlab_readFrameBuffer" android:description="@string/permdesc_readFrameBuffer" @@ -1911,19 +1943,22 @@ android:description="@string/permdesc_controlWifiDisplay" android:protectionLevel="signature" /> - <!-- Required to be able to disable the device (very dangerous!). --> + <!-- Required to be able to disable the device (very dangerous!). + <p>Not for use by third-party applications.. --> <permission android:name="android.permission.BRICK" android:label="@string/permlab_brick" android:description="@string/permdesc_brick" android:protectionLevel="signature" /> - <!-- Required to be able to reboot the device. --> + <!-- Required to be able to reboot the device. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.REBOOT" android:label="@string/permlab_reboot" android:description="@string/permdesc_reboot" android:protectionLevel="signature|system" /> - <!-- Allows low-level access to power management --> + <!-- Allows low-level access to power management. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.DEVICE_POWER" android:label="@string/permlab_devicePower" android:description="@string/permdesc_devicePower" @@ -1935,34 +1970,39 @@ android:protectionLevel="signature" /> <!-- Run as a manufacturer test application, running as the root user. - Only available when the device is running in manufacturer test mode. --> + Only available when the device is running in manufacturer test mode. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.FACTORY_TEST" android:label="@string/permlab_factoryTest" android:description="@string/permdesc_factoryTest" android:protectionLevel="signature" /> <!-- Allows an application to broadcast a notification that an application - package has been removed. --> + package has been removed. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:label="@string/permlab_broadcastPackageRemoved" android:description="@string/permdesc_broadcastPackageRemoved" android:protectionLevel="signature" /> - <!-- Allows an application to broadcast an SMS receipt notification --> + <!-- Allows an application to broadcast an SMS receipt notification. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.BROADCAST_SMS" android:permissionGroup="android.permission-group.MESSAGES" android:label="@string/permlab_broadcastSmsReceived" android:description="@string/permdesc_broadcastSmsReceived" android:protectionLevel="signature" /> - <!-- Allows an application to broadcast a WAP PUSH receipt notification --> + <!-- Allows an application to broadcast a WAP PUSH receipt notification. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.BROADCAST_WAP_PUSH" android:permissionGroup="android.permission-group.MESSAGES" android:label="@string/permlab_broadcastWapPush" android:description="@string/permdesc_broadcastWapPush" android:protectionLevel="signature" /> + <!-- Not for use by third-party applications. --> <permission android:name="android.permission.MASTER_CLEAR" android:label="@string/permlab_masterClear" android:description="@string/permdesc_masterClear" @@ -1970,7 +2010,8 @@ <!-- Allows an application to call any phone number, including emergency numbers, without going through the Dialer user interface for the user - to confirm the call being placed. Not for use by third party apps. --> + to confirm the call being placed. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.CALL_PRIVILEGED" android:label="@string/permlab_callPrivileged" android:description="@string/permdesc_callPrivileged" @@ -1983,14 +2024,16 @@ android:protectionLevel="signature|system" /> <!-- Allows enabling/disabling location update notifications from - the radio. Not for use by normal applications. --> + the radio. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.CONTROL_LOCATION_UPDATES" android:label="@string/permlab_locationUpdates" android:description="@string/permdesc_locationUpdates" android:protectionLevel="signature|system" /> <!-- Allows read/write access to the "properties" table in the checkin - database, to change values that get uploaded. --> + database, to change values that get uploaded. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" android:label="@string/permlab_checkinProperties" android:description="@string/permdesc_checkinProperties" @@ -2010,7 +2053,8 @@ android:description="@string/permdesc_batteryStats" android:protectionLevel="dangerous" /> - <!-- Allows an application to control the backup and restore process + <!-- Allows an application to control the backup and restore process. + <p>Not for use by third-party applications. @hide pending API council --> <permission android:name="android.permission.BACKUP" android:label="@string/permlab_backup" @@ -2037,7 +2081,7 @@ picks an AppWidget to go into a particular host, thereby giving that host application access to the private data from the AppWidget app. An application that has this permission should honor that contract. - Very few applications should need to use this permission. --> + <p>Not for use by third-party applications. --> <permission android:name="android.permission.BIND_APPWIDGET" android:permissionGroup="android.permission-group.PERSONAL_INFO" android:label="@string/permlab_bindGadget" @@ -2058,7 +2102,8 @@ android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature|system" /> - <!-- Allows applications to change the background data setting + <!-- Allows applications to change the background data setting. + <p>Not for use by third-party applications. @hide pending API council --> <permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 70d65eb124bf..bd40c643e30b 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -944,11 +944,11 @@ <item quantity="other" msgid="3903706804349556379">"vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item> </plurals> <plurals name="num_minutes_ago"> - <item quantity="one" msgid="3306787433088810191">"Vor 1 Minute"</item> + <item quantity="one" msgid="3306787433088810191">"vor 1 Minute"</item> <item quantity="other" msgid="2176942008915455116">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item> </plurals> <plurals name="num_hours_ago"> - <item quantity="one" msgid="9150797944610821849">"Vor 1 Stunde"</item> + <item quantity="one" msgid="9150797944610821849">"vor 1 Stunde"</item> <item quantity="other" msgid="2467273239587587569">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item> </plurals> <plurals name="last_num_days"> @@ -957,7 +957,7 @@ <string name="last_month" msgid="3959346739979055432">"Letzter Monat"</string> <string name="older" msgid="5211975022815554840">"Älter"</string> <plurals name="num_days_ago"> - <item quantity="one" msgid="861358534398115820">"Gestern"</item> + <item quantity="one" msgid="861358534398115820">"gestern"</item> <item quantity="other" msgid="2479586466153314633">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item> </plurals> <plurals name="in_num_seconds"> @@ -985,11 +985,11 @@ <item quantity="other" msgid="851164968597150710">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item> </plurals> <plurals name="abbrev_num_hours_ago"> - <item quantity="one" msgid="4796212039724722116">"Vor 1 Stunde"</item> + <item quantity="one" msgid="4796212039724722116">"vor 1 Stunde"</item> <item quantity="other" msgid="6889970745748538901">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item> </plurals> <plurals name="abbrev_num_days_ago"> - <item quantity="one" msgid="8463161711492680309">"Gestern"</item> + <item quantity="one" msgid="8463161711492680309">"gestern"</item> <item quantity="other" msgid="3453342639616481191">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item> </plurals> <plurals name="abbrev_in_num_seconds"> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 3a24738d8f21..c388643bb27f 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -607,7 +607,7 @@ <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"δοκιμή πρόσβασης σε προστατευμένο χώρο αποθήκευσης"</string> <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Επιτρέπει USB για άλλες συσκ."</string> <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Επιτρέπει στην εφαρμογή τη δοκιμή μια άδειας για την κάρτα SD που θα διατίθεται σε μελλοντικές συσκευές."</string> - <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. περιεχ. αποθ. χώρ. USB"</string> + <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. του USB"</string> <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"τροποποίηση ή διαγραφή των περιεχομένων της κάρτας SD"</string> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Επιτρέπει στην εφαρμογή την εγγραφή στον αποθηκευτικό χώρο USB."</string> <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index cb580f25c67b..f5ba0fb8837e 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -607,7 +607,7 @@ <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"testar o acesso ao armazenamento protegido"</string> <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Permite que o aplicativo teste uma permissão para o armazenamento USB que estará disponível em dispositivos futuros."</string> <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Permite que o aplicativo teste uma permissão para o cartão SD que estará disponível em dispositivos futuros."</string> - <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modif ou excl cont. armaz USB"</string> + <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modificar ou excluir conteúdo do armazenamento USB"</string> <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modificar ou excluir o conteúdo do cartão SD"</string> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite gravar no armaz. USB."</string> <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o aplicativo grave em seu cartão SD."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index a7f58b28deec..d72b1a78b66e 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1498,7 +1498,7 @@ <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="owner_name" msgid="2716755460376028154">"Chủ sở hữu"</string> <string name="error_message_title" msgid="4510373083082500195">"Lỗi"</string> - <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ứng dụng này không hỗ trợ tài khoản cho các tiểu sử bị hạn chế"</string> + <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ứng dụng này không hỗ trợ tài khoản đối với các tiểu sử bị hạn chế"</string> <string name="app_not_found" msgid="3429141853498927379">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string> <string name="revoke" msgid="5404479185228271586">"Thu hồi"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 90c7c1220c9f..499b3aceb51e 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -621,7 +621,7 @@ <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允許應用程式讀取及寫入快取檔案系統。"</string> <string name="permlab_use_sip" msgid="5986952362795870502">"撥打/接聽網路電話"</string> <string name="permdesc_use_sip" msgid="4717632000062674294">"允許應用程式使用 SIP 服務撥打/接聽網路電話。"</string> - <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"讀取網路用量記錄"</string> + <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"讀取網路用量紀錄"</string> <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"允許應用程式讀取特定網路和應用程式的網路使用記錄。"</string> <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"管理網路政策"</string> <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允許應用程式管理網路政策並定義應用程式專用規則。"</string> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 089a859a4c55..36a7a8631aa7 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2046,6 +2046,7 @@ <public type="attr" name="canRequestTouchExplorationMode" id="0x010103d7" /> <public type="attr" name="canRequestEnhancedWebAccessibility" id="0x010103d8" /> <public type="attr" name="canRequestFilterKeyEvents" id="0x010103d9" /> + <public type="attr" name="layoutMode" id="0x010103da" /> <public type="style" name="Theme.Holo.NoActionBar.Overscan" id="0x010301dd" /> <public type="style" name="Theme.Holo.Light.NoActionBar.Overscan" id="0x010301de" /> diff --git a/docs/html/tools/extras/support-library.jd b/docs/html/tools/extras/support-library.jd index 60168f46a201..a82a98ae4eba 100644 --- a/docs/html/tools/extras/support-library.jd +++ b/docs/html/tools/extras/support-library.jd @@ -18,8 +18,7 @@ page.title=Support Library <h2>See also</h2> <ol> <li><a -href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing Apps for Android 3.0</a></li> - <li><a href="http://code.google.com/p/iosched/">Google I/O App source code</a></li> +href="{@docRoot}training/basics/fragments/support-lib.html">Using the Support Library</a></li> </ol> </div> @@ -708,8 +707,8 @@ each activity when running on Android 3.0 and higher.</p> </div> <p>For more information about how you can optimize your application for the latest -Android-powered devices, read <a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing -Apps for Android 3.0</a>.</p> +Android-powered devices, read <a href="{@docRoot}guide/practices/tablets-and-handsets.html" +>Supporting Tablets and Handsets</a>.</p> <h2 id="Docs">Reference Docs</h2> diff --git a/docs/html/training/basics/data-storage/databases.jd b/docs/html/training/basics/data-storage/databases.jd index 61fb7583f2e8..6ea2140d6c0b 100644 --- a/docs/html/training/basics/data-storage/databases.jd +++ b/docs/html/training/basics/data-storage/databases.jd @@ -73,25 +73,23 @@ single table:</p> <pre> -public static abstract class FeedEntry implements BaseColumns { - public static final String TABLE_NAME = "entry"; - public static final String COLUMN_NAME_ENTRY_ID = "entryid"; - public static final String COLUMN_NAME_TITLE = "title"; - public static final String COLUMN_NAME_SUBTITLE = "subtitle"; - ... +public final class FeedReaderContract { + // To prevent someone from accidentally instantiating the contract class, + // give it an empty constructor. + public FeedReaderContract() {} + + /* Inner class that defines the table contents */ + public static abstract class FeedEntry implements BaseColumns { + public static final String TABLE_NAME = "entry"; + public static final String COLUMN_NAME_ENTRY_ID = "entryid"; + public static final String COLUMN_NAME_TITLE = "title"; + public static final String COLUMN_NAME_SUBTITLE = "subtitle"; + ... + } } </pre> -<p>To prevent someone from accidentally instantiating the contract class, give -it an empty constructor. </p> - -<pre> -// Prevents the FeedReaderContract class from being instantiated. -private FeedReaderContract() {} -</pre> - - <h2 id="DbHelper">Create a Database Using a SQL Helper</h2> @@ -103,15 +101,15 @@ statements that create and delete a table:</P> private static final String TEXT_TYPE = " TEXT"; private static final String COMMA_SEP = ","; private static final String SQL_CREATE_ENTRIES = - "CREATE TABLE " + FeedReaderContract.FeedEntry.TABLE_NAME + " (" + - FeedReaderContract.FeedEntry._ID + " INTEGER PRIMARY KEY," + - FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + - FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + + "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" + + FeedEntry._ID + " INTEGER PRIMARY KEY," + + FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + + FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + ... // Any other options for the CREATE command " )"; private static final String SQL_DELETE_ENTRIES = - "DROP TABLE IF EXISTS " + TABLE_NAME_ENTRIES; + "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME; </pre> <p>Just like files that you save on the device's <a @@ -191,15 +189,15 @@ SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); -values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID, id); -values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title); -values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_CONTENT, content); +values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); +values.put(FeedEntry.COLUMN_NAME_CONTENT, content); // Insert the new row, returning the primary key value of the new row long newRowId; newRowId = db.insert( - FeedReaderContract.FeedEntry.TABLE_NAME, - FeedReaderContract.FeedEntry.COLUMN_NAME_NULLABLE, + FeedEntry.TABLE_NAME, + FeedEntry.COLUMN_NAME_NULLABLE, values); </pre> @@ -227,18 +225,18 @@ SQLiteDatabase db = mDbHelper.getReadableDatabase(); // Define a <em>projection</em> that specifies which columns from the database // you will actually use after this query. String[] projection = { - FeedReaderContract.FeedEntry._ID, - FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, - FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED, + FeedEntry._ID, + FeedEntry.COLUMN_NAME_TITLE, + FeedEntry.COLUMN_NAME_UPDATED, ... }; // How you want the results sorted in the resulting Cursor String sortOrder = - FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED + " DESC"; + FeedEntry.COLUMN_NAME_UPDATED + " DESC"; Cursor c = db.query( - FeedReaderContract.FeedEntry.TABLE_NAME, // The table to query + FeedEntry.TABLE_NAME, // The table to query projection, // The columns to return selection, // The columns for the WHERE clause selectionArgs, // The values for the WHERE clause @@ -262,7 +260,7 @@ For example:</p> <pre> cursor.moveToFirst(); long itemId = cursor.getLong( - cursor.getColumnIndexOrThrow(FeedReaderContract.FeedEntry._ID) + cursor.getColumnIndexOrThrow(FeedEntry._ID) ); </pre> @@ -282,7 +280,7 @@ immune to SQL injection.</p> <pre> // Define 'where' part of query. -String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; // Specify arguments in placeholder order. String[] selectionArgs = { String.valueOf(rowId) }; // Issue SQL statement. @@ -305,10 +303,10 @@ SQLiteDatabase db = mDbHelper.getReadableDatabase(); // New value for one column ContentValues values = new ContentValues(); -values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); // Which row to update, based on the ID -String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; String[] selectionArgs = { String.valueOf(rowId) }; int count = db.update( diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 06209f122053..b2d991520aa3 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -63,6 +63,7 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { void DisplayList::clearResources() { mDisplayListData = NULL; + mSize = 0; // TODO: shouldn't be needed, WAR possible use after delete mClipRectOp = NULL; mSaveLayerOp = NULL; @@ -479,7 +480,7 @@ void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) { */ template <class T> void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) { - if (mSize == 0 || mAlpha <= 0) { + if (mSize == 0 || mAlpha <= 0 || CC_UNLIKELY(!mSaveOp)) { // TODO: shouldn't need mSaveOp check DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string()); return; } diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl index c70889c9237c..583f436690c6 100644 --- a/media/java/android/media/IRemoteControlDisplay.aidl +++ b/media/java/android/media/IRemoteControlDisplay.aidl @@ -40,6 +40,33 @@ oneway interface IRemoteControlDisplay void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent, boolean clearing); + /** + * Sets the playback information (state, position and speed) of a client. + * @param generationId the current generation ID as known by this client + * @param state the current playback state, one of the following values: + * {@link RemoteControlClient#PLAYSTATE_STOPPED}, + * {@link RemoteControlClient#PLAYSTATE_PAUSED}, + * {@link RemoteControlClient#PLAYSTATE_PLAYING}, + * {@link RemoteControlClient#PLAYSTATE_FAST_FORWARDING}, + * {@link RemoteControlClient#PLAYSTATE_REWINDING}, + * {@link RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS}, + * {@link RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS}, + * {@link RemoteControlClient#PLAYSTATE_BUFFERING}, + * {@link RemoteControlClient#PLAYSTATE_ERROR}. + * @param stateChangeTimeMs the time at which the client reported the playback information + * @param currentPosMs a 0 or positive value for the current media position expressed in ms + * Strictly negative values imply that position is not known: + * a value of {@link RemoteControlClient#PLAYBACK_POSITION_INVALID} is intended to express + * that an application doesn't know the position (e.g. listening to a live stream of a radio) + * or that the position information is not applicable (e.g. when state + * is {@link RemoteControlClient#PLAYSTATE_BUFFERING} and nothing had played yet); + * a value of {@link RemoteControlClient#PLAYBACK_POSITION_ALWAYS_UNKNOWN} implies that the + * application uses {@link RemoteControlClient#setPlaybackState(int)} (legacy API) and will + * never pass a playback position. + * @param speed a value expressed as a ratio of 1x playback: 1.0f is normal playback, + * 2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is + * playing (e.g. when state is {@link RemoteControlClient#PLAYSTATE_ERROR}). + */ void setPlaybackState(int generationId, int state, long stateChangeTimeMs, long currentPosMs, float speed); diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java index cf159f0ed1db..e558c07d3c87 100644 --- a/media/java/android/media/MediaExtractor.java +++ b/media/java/android/media/MediaExtractor.java @@ -199,9 +199,9 @@ final public class MediaExtractor { public native final int getTrackCount(); /** - * Get the PSSH info if present. This returns a map of uuid-to-bytes, with the uuid specifying + * Get the PSSH info if present. + * @return a map of uuid-to-bytes, with the uuid specifying * the crypto scheme, and the bytes being the data specific to that scheme. - * {@hide} */ public Map<UUID, byte[]> getPsshInfo() { Map<UUID, byte[]> psshMap = null; diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index c6ae9aade2c0..7379438360ab 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -180,6 +180,12 @@ public class RemoteControlClient public final static long PLAYBACK_POSITION_INVALID = -1; /** * @hide + * An invalid playback position value associated with the use of {@link #setPlaybackState(int)} + * used to indicate that playback position will remain unknown. + */ + public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L; + /** + * @hide * The default playback speed, 1x. */ public final static float PLAYBACK_SPEED_1X = 1.0f; @@ -602,7 +608,8 @@ public class RemoteControlClient * {@link #PLAYSTATE_ERROR}. */ public void setPlaybackState(int state) { - setPlaybackState(state, PLAYBACK_POSITION_INVALID, PLAYBACK_SPEED_1X); + setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X, + false /* legacy API, converting to method with position and speed */); } /** @@ -629,12 +636,28 @@ public class RemoteControlClient * playing (e.g. when state is {@link #PLAYSTATE_ERROR}). */ public void setPlaybackState(int state, long timeInMs, float playbackSpeed) { + setPlaybackStateInt(state, timeInMs, playbackSpeed, true); + } + + private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed, + boolean hasPosition) { synchronized(mCacheLock) { if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs) || (mPlaybackSpeed != playbackSpeed)) { // store locally mPlaybackState = state; - mPlaybackPositionMs = timeInMs; + // distinguish between an application not knowing the current playback position + // at the moment and an application using the API where only the playback state + // is passed, not the playback position. + if (hasPosition) { + if (timeInMs < 0) { + mPlaybackPositionMs = PLAYBACK_POSITION_INVALID; + } else { + mPlaybackPositionMs = timeInMs; + } + } else { + mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN; + } mPlaybackSpeed = playbackSpeed; // keep track of when the state change occurred mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime(); diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml index b6987058dc9d..91ee2c60cef8 100644 --- a/media/tests/MediaFrameworkTest/AndroidManifest.xml +++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml @@ -71,4 +71,9 @@ android:label="Media Power tests InstrumentationRunner"> </instrumentation> + <instrumentation android:name=".MediaFrameworkIntegrationTestRunner" + android:targetPackage="com.android.mediaframeworktest" + android:label="MediaFramework integration tests InstrumentationRunner"> + </instrumentation> + </manifest> diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java new file mode 100644 index 000000000000..88c5b0c66e8d --- /dev/null +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mediaframeworktest; + +import android.os.Bundle; +import android.test.InstrumentationTestRunner; +import android.test.InstrumentationTestSuite; + +import com.android.mediaframeworktest.integration.CameraBinderTest; + +import junit.framework.TestSuite; + +/** + * Instrumentation Test Runner for all media framework integration tests. + * + * Running all tests: + * + * adb shell am instrument -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner + */ + +public class MediaFrameworkIntegrationTestRunner extends InstrumentationTestRunner { + + + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(CameraBinderTest.class); + return suite; + } + + @Override + public ClassLoader getLoader() { + return MediaFrameworkIntegrationTestRunner.class.getClassLoader(); + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + } +} diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java index 92ac9eb09766..cbb66428b07d 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java @@ -50,7 +50,7 @@ import android.test.InstrumentationTestSuite; * Running all tests: * * adb shell am instrument \ - * -w com.android.smstests.MediaPlayerInstrumentationTestRunner + * -w com.android.mediaframeworktest/.MediaFrameworkTestRunner */ public class MediaFrameworkTestRunner extends InstrumentationTestRunner { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java index 2f864d7fa906..7f23ba576fbb 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java @@ -36,7 +36,12 @@ import java.io.*; /** * Junit / Instrumentation test case for the camera api - + * + * To run only tests in this class: + * + * adb shell am instrument \ + * -e class com.android.mediaframeworktest.functional.CameraTest \ + * -w com.android.mediaframeworktest/.MediaFrameworkTestRunner */ public class CameraTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> { private String TAG = "CameraTest"; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java new file mode 100644 index 000000000000..ba2859bc9c51 --- /dev/null +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mediaframeworktest.integration; + +import android.content.Context; +import android.content.pm.FeatureInfo; +import android.content.pm.PackageManager; +import android.hardware.CameraInfo; +import android.hardware.ICamera; +import android.hardware.ICameraClient; +import android.hardware.ICameraService; +import android.hardware.ICameraServiceListener; +import android.hardware.IProCameraCallbacks; +import android.hardware.IProCameraUser; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +/** + * Junit / Instrumentation test case for the camera2 api + * + * To run only tests in + * this class: + * + * adb shell am instrument \ + * -e class com.android.mediaframeworktest.integration.CameraBinderTest \ + * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner + */ +public class CameraBinderTest extends AndroidTestCase { + private static String TAG = "CameraBinderTest"; + + private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera"; + private static final int NO_ERROR = 0; + private static final int ALREADY_EXISTS = -17; + private static final int BAD_VALUE = -22; + + private static final int USE_CALLING_UID = -1; + + private ICameraService mCameraService; + private int mGuessedNumCameras = 0; + + public CameraBinderTest() { + } + + private final static boolean isFeatureAvailable(Context context, String feature) { + final PackageManager packageManager = context.getPackageManager(); + final FeatureInfo[] featuresList = packageManager.getSystemAvailableFeatures(); + for (FeatureInfo f : featuresList) { + if (f.name != null && f.name.equals(feature)) { + return true; + } + } + + return false; + } + + // Guess the lower bound for how many cameras there are + private void guessNumCameras() { + + /** + * Why do we need this? This way we have no dependency on getNumCameras + * actually working. On most systems there are only 0, 1, or 2 cameras, + * and this covers that 'usual case'. On other systems there might be 3+ + * cameras, but this will at least check the first 2. + */ + mGuessedNumCameras = 0; + + // Front facing camera + if (isFeatureAvailable(getContext(), PackageManager.FEATURE_CAMERA_FRONT)) { + mGuessedNumCameras++; + } + + // Back facing camera + if (isFeatureAvailable(getContext(), PackageManager.FEATURE_CAMERA)) { + mGuessedNumCameras++; + } + + // Any facing camera + if (mGuessedNumCameras == 0 + && isFeatureAvailable(getContext(), PackageManager.FEATURE_CAMERA_ANY)) { + mGuessedNumCameras++; + } + + Log.v(TAG, "Guessing there are at least " + mGuessedNumCameras + " cameras"); + } + + protected void setUp() throws Exception { + super.setUp(); + + guessNumCameras(); + + IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME); + assertNotNull("Camera service IBinder should not be null", cameraServiceBinder); + + mCameraService = ICameraService.Stub.asInterface(cameraServiceBinder); + assertNotNull("Camera service should not be null", mCameraService); + } + + @SmallTest + public void testNumberOfCameras() throws Exception { + int numCameras = mCameraService.getNumberOfCameras(); + assertTrue("At least this many cameras: " + mGuessedNumCameras, + numCameras >= mGuessedNumCameras); + Log.v(TAG, "Number of cameras " + numCameras); + } + + @SmallTest + public void testCameraInfo() throws Exception { + for (int cameraId = 0; cameraId < mGuessedNumCameras; ++cameraId) { + + CameraInfo info = new CameraInfo(); + info.info.facing = -1; + info.info.orientation = -1; + + assertTrue("Camera service returned info for camera " + cameraId, + mCameraService.getCameraInfo(cameraId, info) == NO_ERROR); + assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1); + assertTrue("Orientation was not set for camera " + cameraId, + info.info.orientation != -1); + + Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing + + ", orientation " + info.info.orientation); + } + } + + static abstract class DummyBase extends Binder implements android.os.IInterface { + @Override + public IBinder asBinder() { + return this; + } + } + + static class DummyCameraClient extends DummyBase implements ICameraClient { + } + + @SmallTest + public void testConnect() throws Exception { + for (int cameraId = 0; cameraId < mGuessedNumCameras; ++cameraId) { + + ICameraClient dummyCallbacks = new DummyCameraClient(); + + String clientPackageName = getContext().getPackageName(); + + ICamera cameraUser = mCameraService.connect(dummyCallbacks, cameraId, clientPackageName, + USE_CALLING_UID); + assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); + + Log.v(TAG, String.format("Camera %s connected", cameraId)); + + cameraUser.disconnect(); + } + } + + static class DummyProCameraCallbacks extends DummyBase implements IProCameraCallbacks { + } + + @SmallTest + public void testConnectPro() throws Exception { + for (int cameraId = 0; cameraId < mGuessedNumCameras; ++cameraId) { + + IProCameraCallbacks dummyCallbacks = new DummyProCameraCallbacks(); + + String clientPackageName = getContext().getPackageName(); + + IProCameraUser cameraUser = mCameraService.connectPro(dummyCallbacks, cameraId, + clientPackageName, USE_CALLING_UID); + assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); + + Log.v(TAG, String.format("Camera %s connected", cameraId)); + + cameraUser.disconnect(); + } + } + + static class DummyCameraServiceListener extends DummyBase implements ICameraServiceListener { + @Override + public void onStatusChanged(int status, int cameraId) + throws RemoteException { + Log.v(TAG, String.format("Camera %d has status changed to 0x%x", cameraId, status)); + } + } + + /** + * adb shell am instrument \ + * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \ + * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner + */ + @SmallTest + public void testAddRemoveListeners() throws Exception { + for (int cameraId = 0; cameraId < mGuessedNumCameras; ++cameraId) { + + ICameraServiceListener listener = new DummyCameraServiceListener(); + + assertTrue("Listener was removed before added", + mCameraService.removeListener(listener) == BAD_VALUE); + + assertTrue("Listener was not added", mCameraService.addListener(listener) == NO_ERROR); + assertTrue("Listener was wrongly added again", + mCameraService.addListener(listener) == ALREADY_EXISTS); + + assertTrue("Listener was not removed", + mCameraService.removeListener(listener) == NO_ERROR); + assertTrue("Listener was wrongly removed again", + mCameraService.removeListener(listener) == BAD_VALUE); + } + } +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 0b85e70201be..3f044708d5a0 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -20,6 +20,7 @@ import android.app.backup.BackupAgentHelper; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.FullBackupDataOutput; +import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -330,7 +331,16 @@ public class SettingsBackupAgent extends BackupAgentHelper { if (DEBUG_BACKUP) { Log.v(TAG, "Starting deferred restore of wifi data"); } + final ContentResolver cr = getContentResolver(); + final int scanAlways = Settings.Global.getInt(cr, + Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0); final int retainedWifiState = enableWifi(false); + if (scanAlways != 0) { + Settings.Global.putInt(cr, + Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0); + // !!! Give the wifi stack a moment to quiesce + try { Thread.sleep(1000); } catch (InterruptedException e) {} + } if (restoredSupplicantData != null) { restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, restoredSupplicantData, restoredSupplicantData.length); @@ -344,6 +354,10 @@ public class SettingsBackupAgent extends BackupAgentHelper { restoredWifiConfigFile, restoredWifiConfigFile.length); } // restore the previous WIFI state. + if (scanAlways != 0) { + Settings.Global.putInt(cr, + Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, scanAlways); + } enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED || retainedWifiState == WifiManager.WIFI_STATE_ENABLING); } diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..1a5a8aa4ab4f --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..cceab0ad0393 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..e377608bac25 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..d619f6b440f9 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..515788ac7f80 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..58327c1fd852 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..66dc6940fabc --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..80784248c750 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..50e5011b92d9 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..bb1de0632be1 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..6de14dca4db7 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..17ca21a77a6a --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..0d344b968800 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..ac010bf381dd --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..b704cdf31bb1 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..3cb8f3e079c1 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..d819f5cd742b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..bb1de0632be1 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..6de14dca4db7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..17ca21a77a6a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png Binary files differnew file mode 100644 index 000000000000..75c5c72d5811 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png Binary files differnew file mode 100644 index 000000000000..402db439d3de --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png Binary files differnew file mode 100644 index 000000000000..7a59975300e2 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png Binary files differnew file mode 100644 index 000000000000..84348add5943 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index ee6fabc68bd8..1fa3b4d48166 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -199,8 +199,8 @@ <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string> <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string> <string name="status_bar_help_title" msgid="1199237744086469217">"Arifa zitaonekana hapa"</string> - <string name="status_bar_help_text" msgid="7874607155052076323">"Wafikie wakati wowote kwa kupapasa chini."\n"Papasa chini tena kupata vidhibiti vya mfumo."</string> - <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Papasa kwenda juu kutoka chini ya skrini ili kuonyesha upau wa mfumo"</string> - <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Papasa chini ya skrini ili kuonyesha upau"</string> - <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Papasa kutoka kulia kwa skrini ili kuonyesha upau wa mfumo"</string> + <string name="status_bar_help_text" msgid="7874607155052076323">"Zifikie wakati wowote kwa kutelezesha chini."\n"Telezesha chini tena kupata vidhibiti vya mfumo."</string> + <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Telezesha kwenda juu kutoka chini ya skrini ili kuonyesha upau wa mfumo"</string> + <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Telezesha sehemu ya chini ya skrini ili kuonyesha upau"</string> + <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Telezesha kutoka kulia mwa skrini ili kuonyesha upau wa mfumo"</string> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index a27630db17fe..4c81c886cb7d 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -102,5 +102,8 @@ <!-- Enable the "flip settings" panel --> <bool name="config_hasFlipSettingsPanel">true</bool> + + <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? --> + <bool name="config_show4GForLTE">false</bool> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 5e232f3ddfc8..9498fe480862 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -320,6 +320,9 @@ <!-- Content description of the data connection type 4G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_data_connection_4g">4G</string> + <!-- Content description of the data connection type LTE for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_data_connection_lte">LTE</string> + <!-- Content description of the data connection type CDMA for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_data_connection_cdma">CDMA</string> diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java index 122f81e2c61b..036bd4ff3dc9 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java +++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.UserHandle; public abstract class CurrentUserTracker extends BroadcastReceiver { @@ -54,4 +55,8 @@ public abstract class CurrentUserTracker extends BroadcastReceiver { } public abstract void onUserSwitched(int newUserId); + + public boolean isCurrentUserOwner() { + return mCurrentUserId == UserHandle.USER_OWNER; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java index cdfd52e9361b..b0aca16218dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java @@ -580,7 +580,7 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, } catch (SettingNotFoundException e) { } - mBugreportState.enabled = enabled; + mBugreportState.enabled = enabled && mUserTracker.isCurrentUserOwner(); mBugreportCallback.refreshView(mBugreportTile, mBugreportState); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 57c347bf488a..a19b52a2ead4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -90,6 +90,7 @@ public class NetworkController extends BroadcastReceiver { boolean mShowPhoneRSSIForData = false; boolean mShowAtLeastThreeGees = false; boolean mAlwaysShowCdmaRssi = false; + boolean mShow4GforLTE = false; String mContentDescriptionPhoneSignal; String mContentDescriptionWifi; @@ -199,6 +200,7 @@ public class NetworkController extends BroadcastReceiver { mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData); mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G); + mShow4GforLTE = res.getBoolean(R.bool.config_show4GForLTE); mAlwaysShowCdmaRssi = res.getBoolean( com.android.internal.R.bool.config_alwaysUseCdmaRssi); @@ -678,11 +680,19 @@ public class NetworkController extends BroadcastReceiver { R.string.accessibility_data_connection_3g); break; case TelephonyManager.NETWORK_TYPE_LTE: - mDataIconList = TelephonyIcons.DATA_4G[mInetCondition]; - mDataTypeIconId = R.drawable.stat_sys_data_connected_4g; - mQSDataTypeIconId = R.drawable.ic_qs_signal_4g; - mContentDescriptionDataType = mContext.getString( - R.string.accessibility_data_connection_4g); + if (mShow4GforLTE) { + mDataIconList = TelephonyIcons.DATA_4G[mInetCondition]; + mDataTypeIconId = R.drawable.stat_sys_data_connected_4g; + mQSDataTypeIconId = R.drawable.ic_qs_signal_4g; + mContentDescriptionDataType = mContext.getString( + R.string.accessibility_data_connection_4g); + } else { + mDataIconList = TelephonyIcons.DATA_LTE[mInetCondition]; + mDataTypeIconId = R.drawable.stat_sys_data_connected_lte; + mQSDataTypeIconId = R.drawable.ic_qs_signal_lte; + mContentDescriptionDataType = mContext.getString( + R.string.accessibility_data_connection_lte); + } break; default: if (!mShowAtLeastThreeGees) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index 3b953a01aa55..4b2c65e67bc6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -136,6 +136,17 @@ class TelephonyIcons { R.drawable.stat_sys_data_fully_connected_4g } }; + // LTE branded "LTE" + static final int[][] DATA_LTE = { + { R.drawable.stat_sys_data_connected_lte, + R.drawable.stat_sys_data_connected_lte, + R.drawable.stat_sys_data_connected_lte, + R.drawable.stat_sys_data_connected_lte }, + { R.drawable.stat_sys_data_fully_connected_lte, + R.drawable.stat_sys_data_fully_connected_lte, + R.drawable.stat_sys_data_fully_connected_lte, + R.drawable.stat_sys_data_fully_connected_lte } + }; } diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index a2ac8feb5dc2..884f57e94951 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -265,7 +265,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac // next: bug report, if enabled if (Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0) { + Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) { mItems.add( new SinglePressAction(com.android.internal.R.drawable.stat_sys_adb, R.string.global_action_bug_report) { @@ -349,16 +349,24 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac return dialog; } + private UserInfo getCurrentUser() { + try { + return ActivityManagerNative.getDefault().getCurrentUser(); + } catch (RemoteException re) { + return null; + } + } + + private boolean isCurrentUserOwner() { + UserInfo currentUser = getCurrentUser(); + return currentUser == null || currentUser.isPrimary(); + } + private void addUsersToMenu(ArrayList<Action> items) { List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE)) .getUsers(); if (users.size() > 1) { - UserInfo currentUser; - try { - currentUser = ActivityManagerNative.getDefault().getCurrentUser(); - } catch (RemoteException re) { - currentUser = null; - } + UserInfo currentUser = getCurrentUser(); for (final UserInfo user : users) { boolean isCurrentUser = currentUser == null ? user.id == 0 : (currentUser.id == user.id); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index ad23b667c67e..83739f55e000 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -64,6 +64,7 @@ import com.android.internal.app.IMediaContainerService; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.server.NativeDaemonConnector.Command; +import com.android.server.NativeDaemonConnector.SensitiveArg; import com.android.server.am.ActivityManagerService; import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; @@ -1641,8 +1642,8 @@ class MountService extends IMountService.Stub int rc = StorageResultCode.OperationSucceeded; try { - mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid, - external ? "1" : "0"); + mConnector.execute("asec", "create", id, sizeMb, fstype, new SensitiveArg(key), + ownerUid, external ? "1" : "0"); } catch (NativeDaemonConnectorException e) { rc = StorageResultCode.OperationFailedInternalError; } @@ -1742,7 +1743,7 @@ class MountService extends IMountService.Stub int rc = StorageResultCode.OperationSucceeded; try { - mConnector.execute("asec", "mount", id, key, ownerUid); + mConnector.execute("asec", "mount", id, new SensitiveArg(key), ownerUid); } catch (NativeDaemonConnectorException e) { int code = e.getCode(); if (code != VoldResponseCode.OpFailedStorageBusy) { @@ -2018,7 +2019,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { - event = mConnector.execute("cryptfs", "checkpw", password); + event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password)); final int code = Integer.parseInt(event.getMessage()); if (code == 0) { @@ -2057,7 +2058,7 @@ class MountService extends IMountService.Stub } try { - mConnector.execute("cryptfs", "enablecrypto", "inplace", password); + mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password)); } catch (NativeDaemonConnectorException e) { // Encryption failed return e.getCode(); @@ -2082,7 +2083,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { - event = mConnector.execute("cryptfs", "changepw", password); + event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password)); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { // Encryption failed @@ -2115,7 +2116,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { - event = mConnector.execute("cryptfs", "verifypw", password); + event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password)); Slog.i(TAG, "cryptfs verifypw => " + event.getMessage()); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { @@ -2481,8 +2482,8 @@ class MountService extends IMountService.Stub int rc = StorageResultCode.OperationSucceeded; try { - mConnector.execute( - "obb", "mount", mObbState.voldPath, hashedKey, mObbState.ownerGid); + mConnector.execute("obb", "mount", mObbState.voldPath, new SensitiveArg(hashedKey), + mObbState.ownerGid); } catch (NativeDaemonConnectorException e) { int code = e.getCode(); if (code != VoldResponseCode.OpFailedStorageBusy) { diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java index abcd8eeb35e2..8a8e38d41456 100644 --- a/services/java/com/android/server/NativeDaemonConnector.java +++ b/services/java/com/android/server/NativeDaemonConnector.java @@ -201,9 +201,28 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo } /** + * Wrapper around argument that indicates it's sensitive and shouldn't be + * logged. + */ + public static class SensitiveArg { + private final Object mArg; + + public SensitiveArg(Object arg) { + mArg = arg; + } + + @Override + public String toString() { + return String.valueOf(mArg); + } + } + + /** * Make command for daemon, escaping arguments as needed. */ - private void makeCommand(StringBuilder builder, String cmd, Object... args) { + @VisibleForTesting + static void makeCommand(StringBuilder rawBuilder, StringBuilder logBuilder, int sequenceNumber, + String cmd, Object... args) { if (cmd.indexOf('\0') >= 0) { throw new IllegalArgumentException("Unexpected command: " + cmd); } @@ -211,16 +230,26 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo throw new IllegalArgumentException("Arguments must be separate from command"); } - builder.append(cmd); + rawBuilder.append(sequenceNumber).append(' ').append(cmd); + logBuilder.append(sequenceNumber).append(' ').append(cmd); for (Object arg : args) { final String argString = String.valueOf(arg); if (argString.indexOf('\0') >= 0) { throw new IllegalArgumentException("Unexpected argument: " + arg); } - builder.append(' '); - appendEscaped(builder, argString); + rawBuilder.append(' '); + logBuilder.append(' '); + + appendEscaped(rawBuilder, argString); + if (arg instanceof SensitiveArg) { + logBuilder.append("[scrubbed]"); + } else { + appendEscaped(logBuilder, argString); + } } + + rawBuilder.append('\0'); } /** @@ -300,27 +329,27 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo */ public NativeDaemonEvent[] execute(int timeout, String cmd, Object... args) throws NativeDaemonConnectorException { + final long startTime = SystemClock.elapsedRealtime(); + final ArrayList<NativeDaemonEvent> events = Lists.newArrayList(); + final StringBuilder rawBuilder = new StringBuilder(); + final StringBuilder logBuilder = new StringBuilder(); final int sequenceNumber = mSequenceNumber.incrementAndGet(); - final StringBuilder cmdBuilder = - new StringBuilder(Integer.toString(sequenceNumber)).append(' '); - final long startTime = SystemClock.elapsedRealtime(); - makeCommand(cmdBuilder, cmd, args); + makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args); - final String logCmd = cmdBuilder.toString(); /* includes cmdNum, cmd, args */ - log("SND -> {" + logCmd + "}"); + final String rawCmd = rawBuilder.toString(); + final String logCmd = logBuilder.toString(); - cmdBuilder.append('\0'); - final String sentCmd = cmdBuilder.toString(); /* logCmd + \0 */ + log("SND -> {" + logCmd + "}"); synchronized (mDaemonLock) { if (mOutputStream == null) { throw new NativeDaemonConnectorException("missing output stream"); } else { try { - mOutputStream.write(sentCmd.getBytes(Charsets.UTF_8)); + mOutputStream.write(rawCmd.getBytes(Charsets.UTF_8)); } catch (IOException e) { throw new NativeDaemonConnectorException("problem sending command", e); } @@ -329,7 +358,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo NativeDaemonEvent event = null; do { - event = mResponseQueue.remove(sequenceNumber, timeout, sentCmd); + event = mResponseQueue.remove(sequenceNumber, timeout, logCmd); if (event == null) { loge("timed-out waiting for response to " + logCmd); throw new NativeDaemonFailureException(logCmd, event); @@ -444,10 +473,11 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo private static class ResponseQueue { private static class PendingCmd { - public int cmdNum; + public final int cmdNum; + public final String logCmd; + public BlockingQueue<NativeDaemonEvent> responses = new ArrayBlockingQueue<NativeDaemonEvent>(10); - public String request; // The availableResponseCount member is used to track when we can remove this // instance from the ResponseQueue. @@ -465,7 +495,11 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo // hold references to this instance already so it can be removed from // mPendingCmds queue. public int availableResponseCount; - public PendingCmd(int c, String r) {cmdNum = c; request = r;} + + public PendingCmd(int cmdNum, String logCmd) { + this.cmdNum = cmdNum; + this.logCmd = logCmd; + } } private final LinkedList<PendingCmd> mPendingCmds; @@ -494,7 +528,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo // let any waiter timeout waiting for this PendingCmd pendingCmd = mPendingCmds.remove(); Slog.e("NativeDaemonConnector.ResponseQueue", - "Removing request: " + pendingCmd.request + " (" + + "Removing request: " + pendingCmd.logCmd + " (" + pendingCmd.cmdNum + ")"); } found = new PendingCmd(cmdNum, null); @@ -512,7 +546,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo // note that the timeout does not count time in deep sleep. If you don't want // the device to sleep, hold a wakelock - public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String origCmd) { + public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String logCmd) { PendingCmd found = null; synchronized (mPendingCmds) { for (PendingCmd pendingCmd : mPendingCmds) { @@ -522,7 +556,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo } } if (found == null) { - found = new PendingCmd(cmdNum, origCmd); + found = new PendingCmd(cmdNum, logCmd); mPendingCmds.add(found); } found.availableResponseCount--; @@ -544,7 +578,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo pw.println("Pending requests:"); synchronized (mPendingCmds) { for (PendingCmd pendingCmd : mPendingCmds) { - pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.request); + pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.logCmd); } } } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index a78d68b6c163..769b97f99f15 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -34,7 +34,6 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.Tethe import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult; import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; -import android.bluetooth.BluetoothTetheringDataTracker; import android.content.Context; import android.net.INetworkManagementEventObserver; import android.net.InterfaceConfiguration; @@ -61,6 +60,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.util.Preconditions; import com.android.server.NativeDaemonConnector.Command; +import com.android.server.NativeDaemonConnector.SensitiveArg; import com.android.server.net.LockdownVpnTracker; import com.google.android.collect.Maps; @@ -1000,8 +1000,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub mConnector.execute("softap", "set", wlanIface); } else { mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID, - "broadcast", getSecurityType(wifiConfig), - wifiConfig.preSharedKey); + "broadcast", "6", getSecurityType(wifiConfig), + new SensitiveArg(wifiConfig.preSharedKey)); } mConnector.execute("softap", "startap"); } catch (NativeDaemonConnectorException e) { @@ -1050,8 +1050,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub mConnector.execute("softap", "set", wlanIface); } else { mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID, - "broadcast", getSecurityType(wifiConfig), - wifiConfig.preSharedKey); + "broadcast", "6", getSecurityType(wifiConfig), + new SensitiveArg(wifiConfig.preSharedKey)); } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index f4065ed0ef89..6ddf3a1bdc63 100644 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -1390,7 +1390,7 @@ public class NotificationManagerService extends INotificationManager.Stub return ; } - final boolean isSystemToast = ("android".equals(pkg)); + final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg)); if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) { if (!isSystemToast) { @@ -1608,7 +1608,7 @@ public class NotificationManagerService extends INotificationManager.Stub Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification); } checkCallerIsSystemOrSameApp(pkg); - final boolean isSystemNotification = ("android".equals(pkg)); + final boolean isSystemNotification = isCallerSystem() || ("android".equals(pkg)); userId = ActivityManager.handleIncomingUser(callingPid, callingUid, userId, true, false, "enqueueNotification", pkg); @@ -2084,19 +2084,26 @@ public class NotificationManagerService extends INotificationManager.Stub cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId); } + // Return true if the caller is a system or phone UID and therefore should not have + // any notifications or toasts blocked. + boolean isCallerSystem() { + final int uid = Binder.getCallingUid(); + final int appid = UserHandle.getAppId(uid); + return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0); + } + void checkCallerIsSystem() { - int uid = Binder.getCallingUid(); - if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { + if (isCallerSystem()) { return; } - throw new SecurityException("Disallowed call for uid " + uid); + throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid()); } void checkCallerIsSystemOrSameApp(String pkg) { - int uid = Binder.getCallingUid(); - if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { + if (isCallerSystem()) { return; } + final int uid = Binder.getCallingUid(); try { ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo( pkg, 0, UserHandle.getCallingUserId()); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 7c5959dbd08a..55f2a32fa78b 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -540,7 +540,7 @@ class ServerThread { * AppWidget Provider. Make sure MountService is completely started * first before continuing. */ - if (mountService != null) { + if (mountService != null && !onlyCore) { mountService.waitForAsecScan(); } diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java index d5c9c8fc96c9..415fcc126aae 100644 --- a/services/java/com/android/server/WiredAccessoryManager.java +++ b/services/java/com/android/server/WiredAccessoryManager.java @@ -44,6 +44,7 @@ import java.io.FileReader; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; /** * <p>WiredAccessoryManager monitors for a wired headset on the main board or dock using @@ -408,11 +409,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { public String getDevName() { return mDevName; } public String getDevPath() { - return String.format("/devices/virtual/switch/%s", mDevName); + return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName); } public String getSwitchStatePath() { - return String.format("/sys/class/switch/%s/state", mDevName); + return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName); } public boolean checkSwitchExists() { diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java index 98c43521208e..a5d64b2c89de 100644 --- a/services/java/com/android/server/am/ActiveServices.java +++ b/services/java/com/android/server/am/ActiveServices.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.List; import com.android.internal.os.BatteryStatsImpl; +import com.android.internal.os.TransferPipe; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.NeededUriGrants; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index f06b9a62fc78..38fe5e6a65cf 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -32,6 +32,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsService; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.ProcessStats; +import com.android.internal.os.TransferPipe; import com.android.internal.util.FastXmlSerializer; import com.android.server.AppOpsService; import com.android.server.AttributeCache; @@ -3422,7 +3423,7 @@ public final class ActivityManagerService extends ActivityManagerNative File lastTracesFile = null; File curTracesFile = null; for (int i=9; i>=0; i--) { - String name = String.format("slow%02d.txt", i); + String name = String.format(Locale.US, "slow%02d.txt", i); curTracesFile = new File(tracesDir, name); if (curTracesFile.exists()) { if (lastTracesFile != null) { diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index af61bfb5802f..6fe28f4c884e 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -69,6 +69,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.app.HeavyWeightSwitcherActivity; +import com.android.internal.os.TransferPipe; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.am.ActivityStack.ActivityState; import com.android.server.wm.StackBox; diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index 5a15f0bb8846..f143feb83363 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -27,6 +27,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Process; import android.os.ServiceManager; +import android.os.UserHandle; import android.os.WorkSource; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; @@ -479,12 +480,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub { private void dumpHelp(PrintWriter pw) { pw.println("Battery stats (batteryinfo) dump options:"); - pw.println(" [--checkin] [--unplugged] [--reset] [--write] [-h]"); + pw.println(" [--checkin] [--unplugged] [--reset] [--write] [-h] [<package.name>]"); pw.println(" --checkin: format output for a checkin report."); pw.println(" --unplugged: only output data since last unplugged."); pw.println(" --reset: reset the stats, clearing all current data."); pw.println(" --write: force write current collected stats to disk."); pw.println(" -h: print this help text."); + pw.println(" <package.name>: optional name of package to filter output by."); } @Override @@ -500,6 +502,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { boolean isCheckin = false; boolean isUnpluggedOnly = false; boolean noOutput = false; + int reqUid = -1; if (args != null) { for (String arg : args) { if ("--checkin".equals(arg)) { @@ -523,9 +526,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub { return; } else if ("-a".equals(arg)) { // fall through - } else { + } else if (arg.length() > 0 && arg.charAt(0) == '-'){ pw.println("Unknown option: " + arg); dumpHelp(pw); + return; + } else { + // Not an option, last argument must be a package name. + try { + reqUid = mContext.getPackageManager().getPackageUid(arg, + UserHandle.getCallingUserId()); + } catch (PackageManager.NameNotFoundException e) { + pw.println("Unknown package: " + arg); + dumpHelp(pw); + return; + } } } } @@ -539,7 +553,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } else { synchronized (mStats) { - mStats.dumpLocked(pw, isUnpluggedOnly); + mStats.dumpLocked(pw, isUnpluggedOnly, reqUid); } } } diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java index 5759a4485e80..7da8c48dea35 100644 --- a/services/java/com/android/server/am/ProviderMap.java +++ b/services/java/com/android/server/am/ProviderMap.java @@ -22,6 +22,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; import android.util.SparseArray; +import com.android.internal.os.TransferPipe; import java.io.FileDescriptor; import java.io.IOException; diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java index d03da20f2219..d79211ccf5b5 100644 --- a/services/java/com/android/server/am/TaskRecord.java +++ b/services/java/com/android/server/am/TaskRecord.java @@ -57,7 +57,7 @@ final class TaskRecord extends ThumbnailHolder { /** Current stack */ ActivityStack stack; - private boolean mApplicationTask; + private boolean mApplicationTask = true; TaskRecord(int _taskId, ActivityInfo info, Intent _intent, ActivityStack _stack) { taskId = _taskId; @@ -164,7 +164,10 @@ final class TaskRecord extends ThumbnailHolder { // Was not previously in list. numFullscreen++; } - mApplicationTask = r.isApplicationActivity(); + // Only set this to be an application task if it has not already been set as home task. + if (mApplicationTask) { + mApplicationTask = r.isApplicationActivity(); + } mActivities.add(index, r); } diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java index cf593ce630a0..80c7d88508c6 100644 --- a/services/java/com/android/server/content/SyncManager.java +++ b/services/java/com/android/server/content/SyncManager.java @@ -1966,6 +1966,10 @@ public class SyncManager { for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) { final Bundle extras = info.periodicSyncs.get(i).first; final Long periodInMillis = info.periodicSyncs.get(i).second * 1000; + // Skip if the period is invalid + if (periodInMillis <= 0) { + continue; + } // find when this periodic sync was last scheduled to run final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i); diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java index f154ab3a0d88..8272c1579768 100644 --- a/services/java/com/android/server/pm/KeySetManager.java +++ b/services/java/com/android/server/pm/KeySetManager.java @@ -399,24 +399,50 @@ public class KeySetManager { return new String(Base64.encode(k.getEncoded(), 0)); } - public void dump(PrintWriter pw) { + public void dump(PrintWriter pw, String packageName, + PackageManagerService.DumpState dumpState) { synchronized (mLockObject) { - pw.println(" Dumping KeySetManager"); + boolean printedHeader = false; for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) { - String packageName = e.getKey(); + String keySetPackage = e.getKey(); + if (packageName != null && !packageName.equals(keySetPackage)) { + continue; + } + if (!printedHeader) { + if (dumpState.onTitlePrinted()) + pw.println(); + pw.println("Key Set Manager:"); + printedHeader = true; + } PackageSetting pkg = e.getValue(); - pw.print(" ["); pw.print(packageName); pw.println("]"); + pw.print(" ["); pw.print(keySetPackage); pw.println("]"); if (pkg.keySetData != null) { - pw.print(" Defined KeySets:"); + boolean printedLabel = false; for (long keySetId : pkg.keySetData.getDefinedKeySets()) { - pw.print(" "); pw.print(Long.toString(keySetId)); + if (!printedLabel) { + pw.print(" Defined KeySets: "); + printedLabel = true; + } else { + pw.print(", "); + } + pw.print(Long.toString(keySetId)); + } + if (printedLabel) { + pw.println(""); } - pw.println(""); - pw.print(" Signing KeySets:"); + printedLabel = false; for (long keySetId : pkg.keySetData.getSigningKeySets()) { + if (!printedLabel) { + pw.print(" Signing KeySets:"); + printedLabel = true; + } else { + pw.print(", "); + } pw.print(" "); pw.print(Long.toString(keySetId)); } - pw.println(""); + if (printedLabel) { + pw.println(""); + } } } } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 07805f9d35c5..5e6e0553c3a1 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -10041,6 +10041,9 @@ public class PackageManagerService extends IPackageManager.Stub { // Is this a package name? if ("android".equals(cmd) || cmd.contains(".")) { packageName = cmd; + // When dumping a single package, we always dump all of its + // filter information since the amount of data will be reasonable. + dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); } else if ("l".equals(cmd) || "libraries".equals(cmd)) { dumpState.setDump(DumpState.DUMP_LIBS); } else if ("f".equals(cmd) || "features".equals(cmd)) { @@ -10076,7 +10079,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Verifiers:"); pw.print(" Required: "); pw.print(mRequiredVerifierPackage); @@ -10086,16 +10089,20 @@ public class PackageManagerService extends IPackageManager.Stub { } if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { - if (dumpState.onTitlePrinted()) - pw.println(" "); - pw.println("Libraries:"); + boolean printedHeader = false; final Iterator<String> it = mSharedLibraries.keySet().iterator(); while (it.hasNext()) { String name = it.next(); + SharedLibraryEntry ent = mSharedLibraries.get(name); + if (!printedHeader) { + if (dumpState.onTitlePrinted()) + pw.println(); + pw.println("Libraries:"); + printedHeader = true; + } pw.print(" "); pw.print(name); pw.print(" -> "); - SharedLibraryEntry ent = mSharedLibraries.get(name); if (ent.path != null) { pw.print("(jar) "); pw.print(ent.path); @@ -10109,7 +10116,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Features:"); Iterator<String> it = mAvailableFeatures.keySet().iterator(); while (it.hasNext()) { @@ -10185,7 +10192,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Registered ContentProviders:"); printedSomething = true; } @@ -10200,7 +10207,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("ContentProvider Authorities:"); printedSomething = true; } @@ -10214,10 +10221,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (dumpState.isDumping(DumpState.DUMP_KEYSETS)) { - if (dumpState.onTitlePrinted()) { - pw.println(" "); - } - mSettings.mKeySetManager.dump(pw); + mSettings.mKeySetManager.dump(pw, packageName, dumpState); } if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { @@ -10230,10 +10234,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); mSettings.dumpReadMessagesLPr(pw, dumpState); - pw.println(" "); + pw.println(); pw.println("Package warning messages:"); final File fname = getSettingsProblemFile(); FileInputStream in = null; diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index a9c2ea17c174..b7810ba8d75a 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -2893,7 +2893,7 @@ final class Settings { if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Packages:"); printedSomething = true; } @@ -2909,7 +2909,7 @@ final class Settings { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Renamed packages:"); printedSomething = true; } @@ -2929,7 +2929,7 @@ final class Settings { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Hidden system packages:"); printedSomething = true; } @@ -2946,7 +2946,7 @@ final class Settings { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Permissions:"); printedSomething = true; } @@ -2980,7 +2980,7 @@ final class Settings { } if (!printedSomething) { if (dumpState.onTitlePrinted()) - pw.println(" "); + pw.println(); pw.println("Shared users:"); printedSomething = true; } diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java index 3a5357afef17..5a60de0f269b 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -56,6 +56,7 @@ import java.io.PrintWriter; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Scanner; @@ -240,7 +241,7 @@ public class UsbDeviceManager { for (int i = 0; i < serialLength; i++) { address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i); } - String addrString = String.format("%02X:%02X:%02X:%02X:%02X:%02X", + String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", address[0], address[1], address[2], address[3], address[4], address[5]); try { FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); diff --git a/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java index 275d80764533..e2253a2151b0 100644 --- a/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java +++ b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java @@ -17,10 +17,13 @@ package com.android.server; import static com.android.server.NativeDaemonConnector.appendEscaped; +import static com.android.server.NativeDaemonConnector.makeCommand; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; +import com.android.server.NativeDaemonConnector.SensitiveArg; + /** * Tests for {@link NativeDaemonConnector}. */ @@ -67,4 +70,28 @@ public class NativeDaemonConnectorTest extends AndroidTestCase { appendEscaped(builder, "caf\u00E9 c\u00F6ffee"); assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString()); } + + public void testSensitiveArgs() throws Exception { + final StringBuilder rawBuilder = new StringBuilder(); + final StringBuilder logBuilder = new StringBuilder(); + + rawBuilder.setLength(0); + logBuilder.setLength(0); + makeCommand(rawBuilder, logBuilder, 1, "foo", "bar", "baz"); + assertEquals("1 foo bar baz\0", rawBuilder.toString()); + assertEquals("1 foo bar baz", logBuilder.toString()); + + rawBuilder.setLength(0); + logBuilder.setLength(0); + makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("bar"), "baz"); + assertEquals("1 foo bar baz\0", rawBuilder.toString()); + assertEquals("1 foo [scrubbed] baz", logBuilder.toString()); + + rawBuilder.setLength(0); + logBuilder.setLength(0); + makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("foo bar"), "baz baz", + new SensitiveArg("wat")); + assertEquals("1 foo \"foo bar\" \"baz baz\" wat\0", rawBuilder.toString()); + assertEquals("1 foo [scrubbed] \"baz baz\" [scrubbed]", logBuilder.toString()); + } } diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml index be6b145e2bc7..98174ab34e6c 100644 --- a/tests/TransitionTests/AndroidManifest.xml +++ b/tests/TransitionTests/AndroidManifest.xml @@ -212,6 +212,13 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + <activity android:label="DelayedTransition" + android:name="DelayedTransition"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> </application> diff --git a/tests/TransitionTests/res/layout/two_buttons.xml b/tests/TransitionTests/res/layout/two_buttons.xml new file mode 100644 index 000000000000..23d59f8584bd --- /dev/null +++ b/tests/TransitionTests/res/layout/two_buttons.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:id="@+id/container"> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/button1"/> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/button2"/> +</LinearLayout>
\ No newline at end of file diff --git a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java new file mode 100644 index 000000000000..f05ea782bdf2 --- /dev/null +++ b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.transitiontests; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.view.transition.TransitionManager; +import android.widget.Button; +import android.widget.LinearLayout; +import static android.widget.LinearLayout.LayoutParams; + +public class DelayedTransition extends Activity { + + private static final int SEARCH_SCREEN = 0; + private static final int RESULTS_SCREEN = 1; + ViewGroup mSceneRoot; + static int mCurrentScene; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.two_buttons); + + final Button button1 = (Button) findViewById(R.id.button1); + final Button button2 = (Button) findViewById(R.id.button2); + final LinearLayout container = (LinearLayout) findViewById(R.id.container); + button1.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int buttonWidth = button1.getWidth(); + int containerWidth = container.getWidth(); + if (buttonWidth < containerWidth) { + TransitionManager.beginDelayedTransition(container, null); + button1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT)); + TransitionManager.beginDelayedTransition(container, null); + button2.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT)); + } else { + TransitionManager.beginDelayedTransition(container, null); + button1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT)); + TransitionManager.beginDelayedTransition(container, null); + button2.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT)); + } + } + }); + } + +} diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index 55e9b2dd5336..a35a34b124ff 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -27,6 +27,7 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; +import java.util.Locale; /** * Stores SSID octets and handles conversion. @@ -199,7 +200,7 @@ public class WifiSsid implements Parcelable { String out = "0x"; byte[] ssidbytes = getOctets(); for (int i = 0; i < octets.size(); i++) { - out += String.format("%02x", ssidbytes[i]); + out += String.format(Locale.US, "%02x", ssidbytes[i]); } return out; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 1ba991ed2f55..d65d03ed1db2 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -19,6 +19,8 @@ package android.net.wifi.p2p; import android.os.Parcelable; import android.os.Parcel; +import java.util.Locale; + /** * A class representing Wifi Display information for a device * @hide @@ -135,7 +137,8 @@ public class WifiP2pWfdInfo implements Parcelable { } public String getDeviceInfoHex() { - return String.format("%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput); + return String.format( + Locale.US, "%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput); } public String toString() { diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index bc1d3c6b4430..cab817d40c6e 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -22,6 +22,7 @@ import android.text.TextUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; /** @@ -126,7 +127,7 @@ public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo { sb.append(" "); byte[] data = instanceName.getBytes(); - sb.append(String.format("%02x", data.length)); + sb.append(String.format(Locale.US, "%02x", data.length)); sb.append(WifiP2pServiceInfo.bin2HexStr(data)); // This is the start point of this response. // Therefore, it indicates the request domain name. @@ -186,8 +187,8 @@ public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo { dnsName = dnsName.toLowerCase(); } sb.append(compressDnsName(dnsName)); - sb.append(String.format("%04x", dnsType)); - sb.append(String.format("%02x", version)); + sb.append(String.format(Locale.US, "%04x", dnsType)); + sb.append(String.format(Locale.US, "%02x", version)); return sb.toString(); } @@ -214,7 +215,7 @@ public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo { int i = dnsName.indexOf('.'); if (i == -1) { if (dnsName.length() > 0) { - sb.append(String.format("%02x", dnsName.length())); + sb.append(String.format(Locale.US, "%02x", dnsName.length())); sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes())); } // for a sequence of labels ending in a zero octet @@ -224,7 +225,7 @@ public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo { String name = dnsName.substring(0, i); dnsName = dnsName.substring(i + 1); - sb.append(String.format("%02x", name.length())); + sb.append(String.format(Locale.US, "%02x", name.length())); sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes())); } return sb.toString(); diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java index c7f0e5fedf0c..81395c9b7d80 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java @@ -20,6 +20,8 @@ import android.net.wifi.p2p.WifiP2pManager; import android.os.Parcel; import android.os.Parcelable; +import java.util.Locale; + /** * A class for creating a service discovery request for use with * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest} @@ -134,10 +136,10 @@ public class WifiP2pServiceRequest implements Parcelable { public String getSupplicantQuery() { StringBuffer sb = new StringBuffer(); // length is retained as little endian format. - sb.append(String.format("%02x", (mLength) & 0xff)); - sb.append(String.format("%02x", (mLength >> 8) & 0xff)); - sb.append(String.format("%02x", mProtocolType)); - sb.append(String.format("%02x", mTransId)); + sb.append(String.format(Locale.US, "%02x", (mLength) & 0xff)); + sb.append(String.format(Locale.US, "%02x", (mLength >> 8) & 0xff)); + sb.append(String.format(Locale.US, "%02x", mProtocolType)); + sb.append(String.format(Locale.US, "%02x", mTransId)); if (mQuery != null) { sb.append(mQuery); } diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java index 40a0d61ecf41..a4cdfd97f20d 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java @@ -18,6 +18,7 @@ package android.net.wifi.p2p.nsd; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.UUID; /** @@ -98,7 +99,7 @@ public class WifiP2pUpnpServiceInfo extends WifiP2pServiceInfo { private static String createSupplicantQuery(String uuid, String data) { StringBuffer sb = new StringBuffer(); sb.append("upnp "); - sb.append(String.format("%02x ", VERSION_1_0)); + sb.append(String.format(Locale.US, "%02x ", VERSION_1_0)); sb.append("uuid:"); sb.append(uuid); if (data != null) { diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java index b5cf14443a22..98e447e37bae 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java @@ -18,6 +18,8 @@ package android.net.wifi.p2p.nsd; import android.net.wifi.p2p.WifiP2pManager; +import java.util.Locale; + /** * A class for creating a Upnp service discovery request for use with * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest} @@ -73,7 +75,7 @@ public class WifiP2pUpnpServiceRequest extends WifiP2pServiceRequest { throw new IllegalArgumentException("search target cannot be null"); } StringBuffer sb = new StringBuffer(); - sb.append(String.format("%02x", WifiP2pUpnpServiceInfo.VERSION_1_0)); + sb.append(String.format(Locale.US, "%02x", WifiP2pUpnpServiceInfo.VERSION_1_0)); sb.append(WifiP2pServiceInfo.bin2HexStr(st.getBytes())); return new WifiP2pUpnpServiceRequest(sb.toString()); } |