Merge "AudioTrack in SoundPool uses audio_attributes_t parameter" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index f3f650e..5fac213 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,7 +23,6 @@
field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
- field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
@@ -32,6 +31,7 @@
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
@@ -14694,6 +14694,7 @@
public final class AudioDeviceInfo {
method public int[] getChannelCounts();
+ method public int[] getChannelIndexMasks();
method public int[] getChannelMasks();
method public int[] getFormats();
method public int getId();
@@ -30315,16 +30316,12 @@
public final class PhoneAccount implements android.os.Parcelable {
method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
- method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
method public int describeContents();
method public android.telecom.PhoneAccountHandle getAccountHandle();
method public android.net.Uri getAddress();
method public int getCapabilities();
method public int getHighlightColor();
- method public android.graphics.Bitmap getIconBitmap();
- method public java.lang.String getIconPackageName();
- method public int getIconResId();
- method public int getIconTint();
+ method public android.graphics.drawable.Icon getIcon();
method public java.lang.CharSequence getLabel();
method public java.lang.CharSequence getShortDescription();
method public android.net.Uri getSubscriptionAddress();
@@ -30340,7 +30337,6 @@
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
- field public static final int NO_ICON_TINT = 0; // 0x0
field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
field public static final java.lang.String SCHEME_SIP = "sip";
field public static final java.lang.String SCHEME_TEL = "tel";
@@ -30355,11 +30351,7 @@
method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setCapabilities(int);
method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon);
method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence);
method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>);
diff --git a/api/system-current.txt b/api/system-current.txt
index 6f4ec48..d727b22 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -32,7 +32,7 @@
field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
- field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
+ field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
@@ -43,6 +43,7 @@
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -15906,6 +15907,7 @@
public final class AudioDeviceInfo {
method public int[] getChannelCounts();
+ method public int[] getChannelIndexMasks();
method public int[] getChannelMasks();
method public int[] getFormats();
method public int getId();
@@ -32498,16 +32500,12 @@
public final class PhoneAccount implements android.os.Parcelable {
method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
- method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
method public int describeContents();
method public android.telecom.PhoneAccountHandle getAccountHandle();
method public android.net.Uri getAddress();
method public int getCapabilities();
method public int getHighlightColor();
- method public android.graphics.Bitmap getIconBitmap();
- method public java.lang.String getIconPackageName();
- method public int getIconResId();
- method public int getIconTint();
+ method public android.graphics.drawable.Icon getIcon();
method public java.lang.CharSequence getLabel();
method public java.lang.CharSequence getShortDescription();
method public android.net.Uri getSubscriptionAddress();
@@ -32524,7 +32522,6 @@
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
- field public static final int NO_ICON_TINT = 0; // 0x0
field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
field public static final java.lang.String SCHEME_SIP = "sip";
field public static final java.lang.String SCHEME_TEL = "tel";
@@ -32539,11 +32536,7 @@
method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setCapabilities(int);
method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon);
method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence);
method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index edff537..4c034b3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1107,6 +1107,11 @@
<permission android:name="android.permission.CAPTURE_TV_INPUT"
android:protectionLevel="signatureOrSystem" />
+ <!-- @hide Allows TvInputService to access DVB device.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.DVB_DEVICE"
+ android:protectionLevel="signatureOrSystem" />
+
<!-- @hide Allows enabling/disabling OEM unlock
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.OEM_UNLOCK_STATE"
@@ -1184,10 +1189,20 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.ConnectionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ @deprecated {@link android.telecom.ConnectionService}s should require
+ android.permission.BIND_TELECOM_CONNECTION_SERVICE instead.
+ @SystemApi
+ @hide -->
<permission android:name="android.permission.BIND_CONNECTION_SERVICE"
android:protectionLevel="system|signature" />
+ <!-- Must be required by a {@link android.telecom.ConnectionService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:protectionLevel="system|signature" />
+
+
<!-- @SystemApi Allows an application to control the in-call experience.
@hide -->
<permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index b2c3ab7..668a14a 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -18,9 +18,9 @@
import android.annotation.DrawableRes;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
@@ -29,15 +29,16 @@
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.UserHandle;
import android.util.Log;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
-import java.lang.IllegalArgumentException;
-import java.lang.Override;
+import java.io.OutputStream;
/**
* An umbrella container for several serializable graphics representations, including Bitmaps,
@@ -57,6 +58,8 @@
private static final int TYPE_DATA = 3;
private static final int TYPE_URI = 4;
+ private static final int VERSION_STREAM_SERIALIZER = 1;
+
private final int mType;
// To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
@@ -281,16 +284,81 @@
return loadDrawable(context);
}
+ /**
+ * Writes a serialized version of an Icon to the specified stream.
+ *
+ * @param stream The stream on which to serialize the Icon.
+ * @hide
+ */
+ public void writeToStream(OutputStream stream) throws IOException {
+ DataOutputStream dataStream = new DataOutputStream(stream);
+
+ dataStream.writeInt(VERSION_STREAM_SERIALIZER);
+ dataStream.writeByte(mType);
+
+ switch (mType) {
+ case TYPE_BITMAP:
+ getBitmap().compress(Bitmap.CompressFormat.PNG, 100, dataStream);
+ break;
+ case TYPE_DATA:
+ dataStream.writeInt(getDataLength());
+ dataStream.write(getDataBytes(), getDataOffset(), getDataLength());
+ break;
+ case TYPE_RESOURCE:
+ dataStream.writeUTF(getResPackage());
+ dataStream.writeInt(getResId());
+ break;
+ case TYPE_URI:
+ dataStream.writeUTF(getUriString());
+ break;
+ }
+ }
+
private Icon(int mType) {
this.mType = mType;
}
/**
+ * Create an Icon from the specified stream.
+ *
+ * @param stream The input stream from which to reconstruct the Icon.
+ * @hide
+ */
+ public static Icon createFromStream(InputStream stream) throws IOException {
+ DataInputStream inputStream = new DataInputStream(stream);
+
+ final int version = inputStream.readInt();
+ if (version >= VERSION_STREAM_SERIALIZER) {
+ final int type = inputStream.readByte();
+ switch (type) {
+ case TYPE_BITMAP:
+ return createWithBitmap(BitmapFactory.decodeStream(inputStream));
+ case TYPE_DATA:
+ final int length = inputStream.readInt();
+ final byte[] data = new byte[length];
+ inputStream.read(data, 0 /* offset */, length);
+ return createWithData(data, 0 /* offset */, length);
+ case TYPE_RESOURCE:
+ final String packageName = inputStream.readUTF();
+ final int resId = inputStream.readInt();
+ return createWithResource(packageName, resId);
+ case TYPE_URI:
+ final String uriOrPath = inputStream.readUTF();
+ return createWithContentUri(uriOrPath);
+ }
+ }
+ return null;
+ }
+
+ /**
* Create an Icon pointing to a drawable resource.
* @param res Resources for a package containing the resource in question
* @param resId ID of the drawable resource
*/
public static Icon createWithResource(Resources res, @DrawableRes int resId) {
+ if (res == null) {
+ throw new IllegalArgumentException("Resource must not be null.");
+ }
final Icon rep = new Icon(TYPE_RESOURCE);
rep.mObj1 = res;
rep.mInt1 = resId;
@@ -304,6 +372,9 @@
* @param resId ID of the drawable resource
*/
public static Icon createWithResource(String resPackage, @DrawableRes int resId) {
+ if (resPackage == null) {
+ throw new IllegalArgumentException("Resource package name must not be null.");
+ }
final Icon rep = new Icon(TYPE_RESOURCE);
rep.mInt1 = resId;
rep.mString1 = resPackage;
@@ -315,6 +386,9 @@
* @param bits A valid {@link android.graphics.Bitmap} object
*/
public static Icon createWithBitmap(Bitmap bits) {
+ if (bits == null) {
+ throw new IllegalArgumentException("Bitmap must not be null.");
+ }
final Icon rep = new Icon(TYPE_BITMAP);
rep.mObj1 = bits;
return rep;
@@ -329,6 +403,9 @@
* @param length Length of the bitmap data
*/
public static Icon createWithData(byte[] data, int offset, int length) {
+ if (data == null) {
+ throw new IllegalArgumentException("Data must not be null.");
+ }
final Icon rep = new Icon(TYPE_DATA);
rep.mObj1 = data;
rep.mInt1 = length;
@@ -342,6 +419,9 @@
* @param uri A uri referring to local content:// or file:// image data.
*/
public static Icon createWithContentUri(String uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("Uri must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = uri;
return rep;
@@ -353,6 +433,9 @@
* @param uri A uri referring to local content:// or file:// image data.
*/
public static Icon createWithContentUri(Uri uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("Uri must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = uri.toString();
return rep;
@@ -365,6 +448,9 @@
* a type that {@link android.graphics.BitmapFactory} can decode.
*/
public static Icon createWithFilePath(String path) {
+ if (path == null) {
+ throw new IllegalArgumentException("Path must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = path;
return rep;
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 566f8dc..4ecb930 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -16,6 +16,7 @@
package android.media;
+import android.annotation.NonNull;
import android.util.SparseIntArray;
/**
@@ -151,27 +152,38 @@
/**
* @return An array of sample rates supported by the audio device.
*/
- public int[] getSampleRates() {
+ public @NonNull int[] getSampleRates() {
return mPort.samplingRates();
}
/**
- * @return An array of channel masks ({@link AudioFormat#CHANNEL_IN_STEREO},
- * {@link AudioFormat#CHANNEL_OUT_7POINT1) for which this audio device can be configured.
+ * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO},
+ * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
*
* @see AudioFormat
*/
- public int[] getChannelMasks() {
+ public @NonNull int[] getChannelMasks() {
return mPort.channelMasks();
}
/**
- * @return An array of channel counts (1, 2, 4....) for which this audio device
+ * @return An array of channel index masks for which this audio device can be configured.
+ *
+ * @see AudioFormat
+ */
+ public @NonNull int[] getChannelIndexMasks() {
+ // TODO: implement
+ return new int[0];
+ }
+
+ /**
+ * @return An array of channel counts (1, 2, 4, ...) for which this audio device
* can be configured.
*/
- public int[] getChannelCounts() {
+ public @NonNull int[] getChannelCounts() {
int[] masks = getChannelMasks();
int[] counts = new int[masks.length];
+ // TODO: consider channel index masks
for (int mask_index = 0; mask_index < masks.length; mask_index++) {
counts[mask_index] = isSink()
? AudioFormat.channelCountFromOutChannelMask(masks[mask_index])
@@ -181,12 +193,16 @@
}
/**
- * @return An array of audio format IDs (@link AudioFormat#ENCODING_PCM_16BIT,
- * {@link AudioFormat#ENCODING_PCM_FLOAT}...) supported by the audio device.
+ * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT},
+ * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device.
+ * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more
+ * than 16 bits of integer precision. Specifying <code>ENCODING_PCM_FLOAT</code>
+ * with {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of
+ * integer precision to that device.
*
* @see AudioFormat
*/
- public int[] getFormats() {
+ public @NonNull int[] getFormats() {
return mPort.formats();
}
diff --git a/media/java/android/media/tv/DvbDeviceInfo.aidl b/media/java/android/media/tv/DvbDeviceInfo.aidl
new file mode 100644
index 0000000..4851050
--- /dev/null
+++ b/media/java/android/media/tv/DvbDeviceInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ *
+ * Copyright 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv;
+
+parcelable DvbDeviceInfo;
\ No newline at end of file
diff --git a/media/java/android/media/tv/DvbDeviceInfo.java b/media/java/android/media/tv/DvbDeviceInfo.java
new file mode 100644
index 0000000..1885a34
--- /dev/null
+++ b/media/java/android/media/tv/DvbDeviceInfo.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.media.tv.TvInputManager;
+import android.util.Log;
+
+import java.lang.IllegalArgumentException;
+
+/**
+ * Simple container for information about DVB device.
+ * Not for third-party developers.
+ *
+ * @hide
+ */
+public final class DvbDeviceInfo implements Parcelable {
+ static final String TAG = "DvbDeviceInfo";
+
+ public static final Parcelable.Creator<DvbDeviceInfo> CREATOR =
+ new Parcelable.Creator<DvbDeviceInfo>() {
+ @Override
+ public DvbDeviceInfo createFromParcel(Parcel source) {
+ try {
+ return new DvbDeviceInfo(source);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating DvbDeviceInfo from parcel", e);
+ return null;
+ }
+ }
+
+ @Override
+ public DvbDeviceInfo[] newArray(int size) {
+ return new DvbDeviceInfo[size];
+ }
+ };
+
+ private final int mAdapterId;
+ private final int mDeviceId;
+
+ private DvbDeviceInfo(Parcel source) {
+ mAdapterId = source.readInt();
+ mDeviceId = source.readInt();
+ }
+
+ /**
+ * Constructs a new {@link DvbDeviceInfo} with the given adapter ID and device ID.
+ */
+ public DvbDeviceInfo(int adapterId, int deviceId) {
+ mAdapterId = adapterId;
+ mDeviceId = deviceId;
+ }
+
+ /**
+ * Returns the adapter ID of DVB device, in terms of enumerating the DVB device adapters
+ * installed in the system. The adapter ID counts from zero.
+ */
+ public int getAdapterId() {
+ return mAdapterId;
+ }
+
+ /**
+ * Returns the device ID of DVB device, in terms of enumerating the DVB devices attached to
+ * the same device adapter. The device ID counts from zero.
+ */
+ public int getDeviceId() {
+ return mDeviceId;
+ }
+
+ // Parcelable
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mAdapterId);
+ dest.writeInt(mDeviceId);
+ }
+}
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 078fb2f..6fe5dbb 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.graphics.Rect;
+import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
@@ -29,6 +30,7 @@
import android.media.tv.TvTrackInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
import android.view.Surface;
/**
@@ -91,4 +93,8 @@
boolean captureFrame(in String inputId, in Surface surface, in TvStreamConfig config,
int userId);
boolean isSingleSessionActive(int userId);
+
+ // For DVB device binding
+ List<DvbDeviceInfo> getDvbDeviceList();
+ ParcelFileDescriptor openDvbDevice(in DvbDeviceInfo info, int device);
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 705aa3d6..e74860e 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -21,12 +21,14 @@
import android.annotation.SystemApi;
import android.graphics.Rect;
import android.media.MediaPlayer;
+import android.media.tv.DvbDeviceInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
@@ -42,6 +44,7 @@
import com.android.internal.util.Preconditions;
+import java.lang.IllegalArgumentException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
@@ -55,6 +58,25 @@
public final class TvInputManager {
private static final String TAG = "TvInputManager";
+ static final int DVB_DEVICE_START = 0;
+ static final int DVB_DEVICE_END = 2;
+
+ /**
+ * A demux device of DVB API for controlling the filters of DVB hardware/software.
+ * @hide
+ */
+ public static final int DVB_DEVICE_DEMUX = DVB_DEVICE_START;
+ /**
+ * A DVR device of DVB API for reading transport streams.
+ * @hide
+ */
+ public static final int DVB_DEVICE_DVR = 1;
+ /**
+ * A frontend device of DVB API for controlling the tuner and DVB demodulator hardware.
+ * @hide
+ */
+ public static final int DVB_DEVICE_FRONTEND = DVB_DEVICE_END;
+
static final int VIDEO_UNAVAILABLE_REASON_START = 0;
static final int VIDEO_UNAVAILABLE_REASON_END = 4;
@@ -1258,6 +1280,43 @@
}
/**
+ * Returns the list of currently available DVB devices on the system.
+ *
+ * @return the list of {@link DvbDeviceInfo} objects representing available DVB devices.
+ * @hide
+ */
+ public List<DvbDeviceInfo> getDvbDeviceList() {
+ try {
+ return mService.getDvbDeviceList();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns a {@link ParcelFileDescriptor} of a specified DVB device for a given
+ * {@link DvbDeviceInfo}
+ *
+ * @param info A {@link DvbDeviceInfo} to open a DVB device.
+ * @param device A DVB device. The DVB device can be {@link DVB_DEVICE_DEMUX},
+ * {@link DVB_DEVICE_DVR} or {@link DVB_DEVICE_FRONTEND}.
+ * @return a {@link ParcelFileDescriptor} of a specified DVB device for a given
+ * {@link DvbDeviceInfo}, or {@code null} if the given {@link DvbDeviceInfo} was
+ * invalid or the specified DVB device was busy with a previous request.
+ * @hide
+ */
+ public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device) {
+ try {
+ if (DVB_DEVICE_START > device || DVB_DEVICE_END < device) {
+ throw new IllegalArgumentException("Invalid DVB device: " + device);
+ }
+ return mService.openDvbDevice(info, device);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* The Session provides the per-session functionality of TV inputs.
* @hide
*/
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index b702e35..377a9a4 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -48,6 +48,8 @@
<string name="wifi_security_psk_generic">@string/wifi_security_wpa_wpa2</string>
<!-- Do not translate. Concise terminology for wifi with 802.1x EAP security -->
<string name="wifi_security_eap">802.1x EAP</string>
+ <!-- Do not translate. Concise terminology for Passpoint network -->
+ <string name="wifi_security_passpoint">Passpoint</string>
<!-- Summary for the remembered network. -->
<string name="wifi_remembered">Saved</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 1ad7a51..7049d6a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -248,6 +248,9 @@
public String getSecurityString(boolean concise) {
Context context = mContext;
+ if (mConfig != null && mConfig.isPasspoint()) {
+ return context.getString(R.string.wifi_security_passpoint);
+ }
switch(security) {
case SECURITY_EAP:
return concise ? context.getString(R.string.wifi_security_short_eap) :
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 080665aa..0462035 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -34,6 +34,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -47,6 +49,21 @@
* service as usual. The UI handler is only used by the {@link OverlayDisplayWindow}.
* </p><p>
* Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
+ * </p><p>
+ * This adapter is configured via the
+ * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
+ * formatted as follows:
+ * <pre>
+ * [mode1]|[mode2]|...,[flag1],[flag2],...
+ * </pre>
+ * with each mode specified as:
+ * <pre>
+ * [width]x[height]/[densityDpi]
+ * </pre>
+ * Supported flags:
+ * <ul>
+ * <li><pre>secure</pre>: creates a secure display</li>
+ * </ul>
* </p>
*/
final class OverlayDisplayAdapter extends DisplayAdapter {
@@ -58,8 +75,10 @@
private static final int MAX_WIDTH = 4096;
private static final int MAX_HEIGHT = 4096;
- private static final Pattern SETTING_PATTERN =
- Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
+ private static final Pattern DISPLAY_PATTERN =
+ Pattern.compile("([^,]+)(,[a-z]+)*");
+ private static final Pattern MODE_PATTERN =
+ Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
// Unique id prefix for overlay displays.
private static final String UNIQUE_ID_PREFIX = "overlay:";
@@ -136,40 +155,49 @@
int count = 0;
for (String part : value.split(";")) {
- Matcher matcher = SETTING_PATTERN.matcher(part);
- if (matcher.matches()) {
+ Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
+ if (displayMatcher.matches()) {
if (count >= 4) {
Slog.w(TAG, "Too many overlay display devices specified: " + value);
break;
}
- try {
- int width = Integer.parseInt(matcher.group(1), 10);
- int height = Integer.parseInt(matcher.group(2), 10);
- int densityDpi = Integer.parseInt(matcher.group(3), 10);
- String flagString = matcher.group(4);
- if (width >= MIN_WIDTH && width <= MAX_WIDTH
- && height >= MIN_HEIGHT && height <= MAX_HEIGHT
- && densityDpi >= DisplayMetrics.DENSITY_LOW
- && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
- int number = ++count;
- String name = getContext().getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_name,
- number);
- int gravity = chooseOverlayGravity(number);
- boolean secure = flagString != null && flagString.contains(",secure");
-
- Slog.i(TAG, "Showing overlay display device #" + number
- + ": name=" + name + ", width=" + width + ", height=" + height
- + ", densityDpi=" + densityDpi + ", secure=" + secure);
-
- mOverlays.add(new OverlayDisplayHandle(name,
- width, height, densityDpi, gravity, secure, number));
+ String modeString = displayMatcher.group(1);
+ String flagString = displayMatcher.group(2);
+ ArrayList<OverlayMode> modes = new ArrayList<>();
+ for (String mode : modeString.split("\\|")) {
+ Matcher modeMatcher = MODE_PATTERN.matcher(mode);
+ if (modeMatcher.matches()) {
+ try {
+ int width = Integer.parseInt(modeMatcher.group(1), 10);
+ int height = Integer.parseInt(modeMatcher.group(2), 10);
+ int densityDpi = Integer.parseInt(modeMatcher.group(3), 10);
+ if (width >= MIN_WIDTH && width <= MAX_WIDTH
+ && height >= MIN_HEIGHT && height <= MAX_HEIGHT
+ && densityDpi >= DisplayMetrics.DENSITY_LOW
+ && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
+ modes.add(new OverlayMode(width, height, densityDpi));
+ continue;
+ }
+ } catch (NumberFormatException ex) {
+ }
+ } else if (mode.isEmpty()) {
continue;
}
- } catch (NumberFormatException ex) {
}
- } else if (part.isEmpty()) {
- continue;
+ if (!modes.isEmpty()) {
+ int number = ++count;
+ String name = getContext().getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_name,
+ number);
+ int gravity = chooseOverlayGravity(number);
+ boolean secure = flagString != null && flagString.contains(",secure");
+
+ Slog.i(TAG, "Showing overlay display device #" + number
+ + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()));
+
+ mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number));
+ continue;
+ }
}
Slog.w(TAG, "Malformed overlay display devices setting: " + value);
}
@@ -189,36 +217,41 @@
}
}
- private final class OverlayDisplayDevice extends DisplayDevice {
+ private abstract class OverlayDisplayDevice extends DisplayDevice {
private final String mName;
- private final int mWidth;
- private final int mHeight;
private final float mRefreshRate;
private final long mDisplayPresentationDeadlineNanos;
- private final int mDensityDpi;
private final boolean mSecure;
- private final Display.Mode mMode;
+ private final List<OverlayMode> mRawModes;
+ private final Display.Mode[] mModes;
+ private final int mDefaultMode;
private int mState;
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
+ private int mActiveMode;
public OverlayDisplayDevice(IBinder displayToken, String name,
- int width, int height, float refreshRate, long presentationDeadlineNanos,
- int densityDpi, boolean secure, int state,
+ List<OverlayMode> modes, int activeMode, int defaultMode,
+ float refreshRate, long presentationDeadlineNanos,
+ boolean secure, int state,
SurfaceTexture surfaceTexture, int number) {
super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
mName = name;
- mWidth = width;
- mHeight = height;
mRefreshRate = refreshRate;
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
- mDensityDpi = densityDpi;
mSecure = secure;
mState = state;
mSurfaceTexture = surfaceTexture;
- mMode = createMode(width, height, refreshRate);
+ mRawModes = modes;
+ mModes = new Display.Mode[modes.size()];
+ for (int i = 0; i < modes.size(); i++) {
+ OverlayMode mode = modes.get(i);
+ mModes[i] = createMode(mode.mWidth, mode.mHeight, refreshRate);
+ }
+ mActiveMode = activeMode;
+ mDefaultMode = defaultMode;
}
public void destroyLocked() {
@@ -248,17 +281,19 @@
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
+ Display.Mode mode = mModes[mActiveMode];
+ OverlayMode rawMode = mRawModes.get(mActiveMode);
mInfo = new DisplayDeviceInfo();
mInfo.name = mName;
mInfo.uniqueId = getUniqueId();
- mInfo.width = mWidth;
- mInfo.height = mHeight;
- mInfo.modeId = mMode.getModeId();
- mInfo.defaultModeId = mMode.getModeId();
- mInfo.supportedModes = new Display.Mode[] { mMode };
- mInfo.densityDpi = mDensityDpi;
- mInfo.xDpi = mDensityDpi;
- mInfo.yDpi = mDensityDpi;
+ mInfo.width = mode.getPhysicalWidth();
+ mInfo.height = mode.getPhysicalHeight();
+ mInfo.modeId = mode.getModeId();
+ mInfo.defaultModeId = mModes[0].getModeId();
+ mInfo.supportedModes = mModes;
+ mInfo.densityDpi = rawMode.mDensityDpi;
+ mInfo.xDpi = rawMode.mDensityDpi;
+ mInfo.yDpi = rawMode.mDensityDpi;
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
@@ -271,6 +306,40 @@
}
return mInfo;
}
+
+ @Override
+ public void requestModeInTransactionLocked(int id) {
+ int index = -1;
+ if (id == 0) {
+ // Use the default.
+ index = 0;
+ } else {
+ for (int i = 0; i < mModes.length; i++) {
+ if (mModes[i].getModeId() == id) {
+ index = i;
+ break;
+ }
+ }
+ }
+ if (index == -1) {
+ Slog.w(TAG, "Unable to locate mode " + id + ", reverting to default.");
+ index = mDefaultMode;
+ }
+ if (mActiveMode == index) {
+ return;
+ }
+ mActiveMode = index;
+ mInfo = null;
+ sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
+ onModeChangedLocked(index);
+ }
+
+ /**
+ * Called when the device switched to a new mode.
+ *
+ * @param index index of the mode in the list of modes
+ */
+ public abstract void onModeChangedLocked(int index);
}
/**
@@ -280,27 +349,32 @@
* Guarded by the {@link DisplayManagerService.SyncRoot} lock.
*/
private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
+ private static final int DEFAULT_MODE_INDEX = 0;
+
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private final List<OverlayMode> mModes;
private final int mGravity;
private final boolean mSecure;
private final int mNumber;
private OverlayDisplayWindow mWindow;
private OverlayDisplayDevice mDevice;
+ private int mActiveMode;
- public OverlayDisplayHandle(String name, int width,
- int height, int densityDpi, int gravity, boolean secure, int number) {
+ public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity,
+ boolean secure, int number) {
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
+ mModes = modes;
mGravity = gravity;
mSecure = secure;
mNumber = number;
+ mActiveMode = 0;
+
+ showLocked();
+ }
+
+ private void showLocked() {
mUiHandler.post(mShowRunnable);
}
@@ -309,15 +383,28 @@
mUiHandler.post(mDismissRunnable);
}
+ private void onActiveModeChangedLocked(int index) {
+ mUiHandler.removeCallbacks(mResizeRunnable);
+ mActiveMode = index;
+ if (mWindow != null) {
+ mUiHandler.post(mResizeRunnable);
+ }
+ }
+
// Called on the UI thread.
@Override
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
long presentationDeadlineNanos, int state) {
synchronized (getSyncRoot()) {
IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
- mDevice = new OverlayDisplayDevice(displayToken, mName,
- mWidth, mHeight, refreshRate, presentationDeadlineNanos,
- mDensityDpi, mSecure, state, surfaceTexture, mNumber);
+ mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
+ DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
+ mSecure, state, surfaceTexture, mNumber) {
+ @Override
+ public void onModeChangedLocked(int index) {
+ onActiveModeChangedLocked(index);
+ }
+ };
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
}
@@ -347,9 +434,8 @@
public void dumpLocked(PrintWriter pw) {
pw.println(" " + mName + ":");
- pw.println(" mWidth=" + mWidth);
- pw.println(" mHeight=" + mHeight);
- pw.println(" mDensityDpi=" + mDensityDpi);
+ pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
+ pw.println(" mActiveMode=" + mActiveMode);
pw.println(" mGravity=" + mGravity);
pw.println(" mSecure=" + mSecure);
pw.println(" mNumber=" + mNumber);
@@ -366,8 +452,9 @@
private final Runnable mShowRunnable = new Runnable() {
@Override
public void run() {
+ OverlayMode mode = mModes.get(mActiveMode);
OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
- mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure,
+ mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure,
OverlayDisplayHandle.this);
window.show();
@@ -392,5 +479,47 @@
}
}
};
+
+ // Runs on the UI thread.
+ private final Runnable mResizeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ OverlayMode mode;
+ OverlayDisplayWindow window;
+ synchronized (getSyncRoot()) {
+ if (mWindow == null) {
+ return;
+ }
+ mode = mModes.get(mActiveMode);
+ window = mWindow;
+ }
+ window.resize(mode.mWidth, mode.mHeight, mode.mDensityDpi);
+ }
+ };
+ }
+
+ /**
+ * A display mode for an overlay display.
+ */
+ private static final class OverlayMode {
+ final int mWidth;
+ final int mHeight;
+ final int mDensityDpi;
+
+ OverlayMode(int width, int height, int densityDpi) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{")
+ .append("width=").append(mWidth)
+ .append(", height=").append(mHeight)
+ .append(", densityDpi=").append(mDensityDpi)
+ .append("}")
+ .toString();
+ }
}
}
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 786889a..f23caf2 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -60,9 +60,9 @@
private final Context mContext;
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private int mWidth;
+ private int mHeight;
+ private int mDensityDpi;
private final int mGravity;
private final boolean mSecure;
private final Listener mListener;
@@ -97,19 +97,9 @@
Listener listener) {
mContext = context;
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
mGravity = gravity;
mSecure = secure;
mListener = listener;
- mTitle = context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_title,
- mName, mWidth, mHeight, mDensityDpi);
- if (secure) {
- mTitle += context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
- }
mDisplayManager = (DisplayManager)context.getSystemService(
Context.DISPLAY_SERVICE);
@@ -119,6 +109,8 @@
mDefaultDisplay = mWindowManager.getDefaultDisplay();
updateDefaultDisplayInfo();
+ resize(width, height, densityDpi, false /* doLayout */);
+
createWindow();
}
@@ -145,6 +137,26 @@
}
}
+ public void resize(int width, int height, int densityDpi) {
+ resize(width, height, densityDpi, true /* doLayout */);
+ }
+
+ private void resize(int width, int height, int densityDpi, boolean doLayout) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ mTitle = mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_title,
+ mName, mWidth, mHeight, mDensityDpi);
+ if (mSecure) {
+ mTitle += mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
+ }
+ if (doLayout) {
+ relayout();
+ }
+ }
+
public void relayout() {
if (mWindowVisible) {
updateWindowParams();
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e649e48..a869c20 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -39,6 +39,7 @@
import android.graphics.Rect;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
@@ -64,6 +65,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -80,23 +82,34 @@
import org.xmlpull.v1.XmlPullParserException;
+import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.IllegalArgumentException;
+import java.lang.Integer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** This class provides a system service that manages television inputs. */
public final class TvInputManagerService extends SystemService {
private static final boolean DEBUG = false;
private static final String TAG = "TvInputManagerService";
+ // Pattern for selecting the DVB frontend devices from the list of files in the /dev directory.
+ private static final Pattern sFrontEndDevicePattern =
+ Pattern.compile("^dvb([0-9]+)\\.frontend([0-9]+)$");
+
private final Context mContext;
private final TvInputHardwareManager mTvInputHardwareManager;
@@ -1507,6 +1520,74 @@
}
@Override
+ public List<DvbDeviceInfo> getDvbDeviceList() throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ArrayList<DvbDeviceInfo> deviceInfos = new ArrayList<>();
+ File devDirectory = new File("/dev");
+ for (String fileName : devDirectory.list()) {
+ Matcher matcher = sFrontEndDevicePattern.matcher(fileName);
+ if (matcher.find()) {
+ int adapterId = Integer.parseInt(matcher.group(1));
+ int deviceId = Integer.parseInt(matcher.group(2));
+ deviceInfos.add(new DvbDeviceInfo(adapterId, deviceId));
+ }
+ }
+ return Collections.unmodifiableList(deviceInfos);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device)
+ throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ String deviceFileName;
+ switch (device) {
+ case TvInputManager.DVB_DEVICE_DEMUX:
+ deviceFileName = String.format("/dev/dvb%d.demux%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_DVR:
+ deviceFileName = String.format("/dev/dvb%d.dvr%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_FRONTEND:
+ deviceFileName = String.format("/dev/dvb%d.frontend%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid DVB device: " + device);
+ }
+ try {
+ // The DVB frontend device only needs to be opened in read/write mode, which
+ // allows performing tuning operations. The DVB demux and DVR device are enough
+ // to be opened in read only mode.
+ return ParcelFileDescriptor.open(new File(deviceFileName),
+ TvInputManager.DVB_DEVICE_FRONTEND == device
+ ? ParcelFileDescriptor.MODE_READ_WRITE
+ : ParcelFileDescriptor.MODE_READ_ONLY);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int userId)
throws RemoteException {
if (mContext.checkCallingPermission(
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6b8ca69..199100b 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -50,7 +50,7 @@
* <pre>
* <service android:name="com.example.package.MyConnectionService"
* android:label="@string/some_label_for_my_connection_service"
- * android:permission="android.permission.BIND_CONNECTION_SERVICE">
+ * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
* <intent-filter>
* <action android:name="android.telecom.ConnectionService" />
* </intent-filter>
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 86475b1..f05a1ef 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -26,6 +26,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -127,6 +128,7 @@
/**
* Indicating no icon tint is set.
+ * @hide
*/
public static final int NO_ICON_TINT = 0;
@@ -144,14 +146,11 @@
private final Uri mAddress;
private final Uri mSubscriptionAddress;
private final int mCapabilities;
- private final int mIconResId;
- private final String mIconPackageName;
- private final Bitmap mIconBitmap;
- private final int mIconTint;
private final int mHighlightColor;
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
+ private final Icon mIcon;
/**
* Helper class for creating a {@link PhoneAccount}.
@@ -161,14 +160,11 @@
private Uri mAddress;
private Uri mSubscriptionAddress;
private int mCapabilities;
- private int mIconResId;
- private String mIconPackageName;
- private Bitmap mIconBitmap;
- private int mIconTint = NO_ICON_TINT;
private int mHighlightColor = NO_HIGHLIGHT_COLOR;
private CharSequence mLabel;
private CharSequence mShortDescription;
private List<String> mSupportedUriSchemes = new ArrayList<String>();
+ private Icon mIcon;
/**
* Creates a builder with the specified {@link PhoneAccountHandle} and label.
@@ -189,14 +185,11 @@
mAddress = phoneAccount.getAddress();
mSubscriptionAddress = phoneAccount.getSubscriptionAddress();
mCapabilities = phoneAccount.getCapabilities();
- mIconResId = phoneAccount.getIconResId();
- mIconPackageName = phoneAccount.getIconPackageName();
- mIconBitmap = phoneAccount.getIconBitmap();
- mIconTint = phoneAccount.getIconTint();
mHighlightColor = phoneAccount.getHighlightColor();
mLabel = phoneAccount.getLabel();
mShortDescription = phoneAccount.getShortDescription();
mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
+ mIcon = phoneAccount.getIcon();
}
/**
@@ -233,65 +226,12 @@
}
/**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
+ * Sets the icon. See {@link PhoneAccount#getIcon}.
*
- * @param packageContext The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @return The builder.
+ * @param icon The icon to set.
*/
- public Builder setIcon(Context packageContext, int iconResId) {
- return setIcon(packageContext.getPackageName(), iconResId);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconPackageName The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @return The builder.
- */
- public Builder setIcon(String iconPackageName, int iconResId) {
- return setIcon(iconPackageName, iconResId, NO_ICON_TINT);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param packageContext The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @param iconTint A color with which to tint this icon.
- * @return The builder.
- */
- public Builder setIcon(Context packageContext, int iconResId, int iconTint) {
- return setIcon(packageContext.getPackageName(), iconResId, iconTint);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconPackageName The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @param iconTint A color with which to tint this icon.
- * @return The builder.
- */
- public Builder setIcon(String iconPackageName, int iconResId, int iconTint) {
- this.mIconPackageName = iconPackageName;
- this.mIconResId = iconResId;
- this.mIconTint = iconTint;
- return this;
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconBitmap The icon bitmap.
- * @return The builder.
- */
- public Builder setIcon(Bitmap iconBitmap) {
- this.mIconBitmap = iconBitmap;
- this.mIconPackageName = null;
- this.mIconResId = NO_RESOURCE_ID;
- this.mIconTint = NO_ICON_TINT;
+ public Builder setIcon(Icon icon) {
+ mIcon = icon;
return this;
}
@@ -363,10 +303,7 @@
mAddress,
mSubscriptionAddress,
mCapabilities,
- mIconResId,
- mIconPackageName,
- mIconBitmap,
- mIconTint,
+ mIcon,
mHighlightColor,
mLabel,
mShortDescription,
@@ -379,10 +316,7 @@
Uri address,
Uri subscriptionAddress,
int capabilities,
- int iconResId,
- String iconPackageName,
- Bitmap iconBitmap,
- int iconTint,
+ Icon icon,
int highlightColor,
CharSequence label,
CharSequence shortDescription,
@@ -391,10 +325,7 @@
mAddress = address;
mSubscriptionAddress = subscriptionAddress;
mCapabilities = capabilities;
- mIconResId = iconResId;
- mIconPackageName = iconPackageName;
- mIconBitmap = iconBitmap;
- mIconTint = iconTint;
+ mIcon = icon;
mHighlightColor = highlightColor;
mLabel = label;
mShortDescription = shortDescription;
@@ -497,6 +428,15 @@
}
/**
+ * The icon to represent this {@code PhoneAccount}.
+ *
+ * @return The icon.
+ */
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ /**
* Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI
* scheme.
*
@@ -518,59 +458,6 @@
}
/**
- * The icon resource ID for the icon of this {@code PhoneAccount}.
- * <p>
- * Creators of a {@code PhoneAccount} who possess the icon in static resources should prefer
- * this method of indicating the icon rather than using {@link #getIconBitmap()}, since it
- * leads to less resource usage.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
- *
- * @return A resource ID.
- */
- public int getIconResId() {
- return mIconResId;
- }
-
- /**
- * The package name from which to load the icon of this {@code PhoneAccount}.
- * <p>
- * If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from
- * the package in the {@link ComponentName} of the {@link #getAccountHandle()}.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
- *
- * @return A package name.
- */
- public String getIconPackageName() {
- return mIconPackageName;
- }
-
- /**
- * A tint to apply to the icon of this {@code PhoneAccount}.
- *
- * @return A hexadecimal color value.
- */
- public int getIconTint() {
- return mIconTint;
- }
-
- /**
- * A literal icon bitmap to represent this {@code PhoneAccount} in a user interface.
- * <p>
- * If this property is specified, it is to be considered the preferred icon. Otherwise, the
- * resource specified by {@link #getIconResId()} should be used.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use
- * {@link #createIconDrawable(Context)}.
- *
- * @return A bitmap.
- */
- public Bitmap getIconBitmap() {
- return mIconBitmap;
- }
-
- /**
* A highlight color to use in displaying information about this {@code PhoneAccount}.
*
* @return A hexadecimal color value.
@@ -579,41 +466,6 @@
return mHighlightColor;
}
- /**
- * Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user
- * interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and
- * {@link #getIconBitmap()} as necessary.
- *
- * @param context A {@code Context} to use for loading {@code Drawable}s.
- *
- * @return An icon for this {@code PhoneAccount}.
- */
- public Drawable createIconDrawable(Context context) {
- if (mIconBitmap != null) {
- return new BitmapDrawable(context.getResources(), mIconBitmap);
- }
-
- if (mIconResId != 0) {
- try {
- Context packageContext = context.createPackageContext(mIconPackageName, 0);
- try {
- Drawable iconDrawable = packageContext.getDrawable(mIconResId);
- if (mIconTint != NO_ICON_TINT) {
- iconDrawable.setTint(mIconTint);
- }
- return iconDrawable;
- } catch (NotFoundException | MissingResourceException e) {
- Log.e(this, e, "Cannot find icon %d in package %s",
- mIconResId, mIconPackageName);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(this, "Cannot find package %s", mIconPackageName);
- }
- }
-
- return new ColorDrawable(Color.TRANSPARENT);
- }
-
//
// Parcelable implementation
//
@@ -644,19 +496,16 @@
mSubscriptionAddress.writeToParcel(out, flags);
}
out.writeInt(mCapabilities);
- out.writeInt(mIconResId);
- out.writeString(mIconPackageName);
- if (mIconBitmap == null) {
- out.writeInt(0);
- } else {
- out.writeInt(1);
- mIconBitmap.writeToParcel(out, flags);
- }
- out.writeInt(mIconTint);
out.writeInt(mHighlightColor);
out.writeCharSequence(mLabel);
out.writeCharSequence(mShortDescription);
out.writeStringList(mSupportedUriSchemes);
+ if (mIcon == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ mIcon.writeToParcel(out, flags);
+ }
}
public static final Creator<PhoneAccount> CREATOR
@@ -689,18 +538,15 @@
mSubscriptionAddress = null;
}
mCapabilities = in.readInt();
- mIconResId = in.readInt();
- mIconPackageName = in.readString();
- if (in.readInt() > 0) {
- mIconBitmap = Bitmap.CREATOR.createFromParcel(in);
- } else {
- mIconBitmap = null;
- }
- mIconTint = in.readInt();
mHighlightColor = in.readInt();
mLabel = in.readCharSequence();
mShortDescription = in.readCharSequence();
mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList());
+ if (in.readInt() > 0) {
+ mIcon = Icon.CREATOR.createFromParcel(in);
+ } else {
+ mIcon = null;
+ }
}
@Override
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index b2c036c..c8ed2b0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -333,16 +333,24 @@
* displayed to the user.
*/
- /** Property is displayed normally. */
+ /**
+ * Indicates that the address or number of a call is allowed to be displayed for caller ID.
+ */
public static final int PRESENTATION_ALLOWED = 1;
- /** Property was blocked. */
+ /**
+ * Indicates that the address or number of a call is blocked by the other party.
+ */
public static final int PRESENTATION_RESTRICTED = 2;
- /** Presentation was not specified or is unknown. */
+ /**
+ * Indicates that the address or number of a call is not specified or known by the carrier.
+ */
public static final int PRESENTATION_UNKNOWN = 3;
- /** Property should be displayed as a pay phone. */
+ /**
+ * Indicates that the address or number of a call belongs to a pay phone.
+ */
public static final int PRESENTATION_PAYPHONE = 4;
private static final String TAG = "TelecomManager";