Merge "StagefrighRecorder:check mWriter before using fd"
diff --git a/media/libmedia/xsd/Android.bp b/media/libmedia/xsd/Android.bp
new file mode 100644
index 0000000..1635f70
--- /dev/null
+++ b/media/libmedia/xsd/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2019 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.
+//
+
+xsd_config {
+ name: "media_profiles",
+ srcs: ["media_profiles.xsd"],
+ package_name: "media.profiles",
+}
diff --git a/media/libmedia/xsd/api/current.txt b/media/libmedia/xsd/api/current.txt
new file mode 100644
index 0000000..0924dd9
--- /dev/null
+++ b/media/libmedia/xsd/api/current.txt
@@ -0,0 +1,140 @@
+// Signature format: 2.0
+package media.profiles {
+
+ public class Audio {
+ ctor public Audio();
+ method public int getBitRate();
+ method public int getChannels();
+ method public String getCodec();
+ method public int getSampleRate();
+ method public void setBitRate(int);
+ method public void setChannels(int);
+ method public void setCodec(String);
+ method public void setSampleRate(int);
+ }
+
+ public class AudioDecoderCap {
+ ctor public AudioDecoderCap();
+ method public boolean getEnabled();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setName(String);
+ }
+
+ public class AudioEncoderCap {
+ ctor public AudioEncoderCap();
+ method public boolean getEnabled();
+ method public int getMaxBitRate();
+ method public int getMaxChannels();
+ method public int getMaxSampleRate();
+ method public int getMinBitRate();
+ method public int getMinChannels();
+ method public int getMinSampleRate();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setMaxBitRate(int);
+ method public void setMaxChannels(int);
+ method public void setMaxSampleRate(int);
+ method public void setMinBitRate(int);
+ method public void setMinChannels(int);
+ method public void setMinSampleRate(int);
+ method public void setName(String);
+ }
+
+ public class CamcorderProfiles {
+ ctor public CamcorderProfiles();
+ method public int getCameraId();
+ method public java.util.List<media.profiles.EncoderProfile> getEncoderProfile();
+ method public java.util.List<media.profiles.CamcorderProfiles.ImageEncoding> getImageEncoding();
+ method public void setCameraId(int);
+ }
+
+ public static class CamcorderProfiles.ImageEncoding {
+ ctor public CamcorderProfiles.ImageEncoding();
+ method public int getQuality();
+ method public void setQuality(int);
+ }
+
+ public class EncoderProfile {
+ ctor public EncoderProfile();
+ method public java.util.List<media.profiles.Audio> getAudio();
+ method public int getDuration();
+ method public String getFileFormat();
+ method public String getQuality();
+ method public java.util.List<media.profiles.Video> getVideo();
+ method public void setDuration(int);
+ method public void setFileFormat(String);
+ method public void setQuality(String);
+ }
+
+ public class MediaSettings {
+ ctor public MediaSettings();
+ method public java.util.List<media.profiles.AudioDecoderCap> getAudioDecoderCap();
+ method public java.util.List<media.profiles.AudioEncoderCap> getAudioEncoderCap();
+ method public java.util.List<media.profiles.CamcorderProfiles> getCamcorderProfiles();
+ method public java.util.List<media.profiles.MediaSettings.EncoderOutputFileFormat> getEncoderOutputFileFormat();
+ method public java.util.List<media.profiles.VideoDecoderCap> getVideoDecoderCap();
+ method public java.util.List<media.profiles.VideoEncoderCap> getVideoEncoderCap();
+ }
+
+ public static class MediaSettings.EncoderOutputFileFormat {
+ ctor public MediaSettings.EncoderOutputFileFormat();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Video {
+ ctor public Video();
+ method public int getBitRate();
+ method public String getCodec();
+ method public int getFrameRate();
+ method public int getHeight();
+ method public int getWidth();
+ method public void setBitRate(int);
+ method public void setCodec(String);
+ method public void setFrameRate(int);
+ method public void setHeight(int);
+ method public void setWidth(int);
+ }
+
+ public class VideoDecoderCap {
+ ctor public VideoDecoderCap();
+ method public boolean getEnabled();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setName(String);
+ }
+
+ public class VideoEncoderCap {
+ ctor public VideoEncoderCap();
+ method public boolean getEnabled();
+ method public int getMaxBitRate();
+ method public int getMaxFrameHeight();
+ method public int getMaxFrameRate();
+ method public int getMaxFrameWidth();
+ method public int getMinBitRate();
+ method public int getMinFrameHeight();
+ method public int getMinFrameRate();
+ method public int getMinFrameWidth();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setMaxBitRate(int);
+ method public void setMaxFrameHeight(int);
+ method public void setMaxFrameRate(int);
+ method public void setMaxFrameWidth(int);
+ method public void setMinBitRate(int);
+ method public void setMinFrameHeight(int);
+ method public void setMinFrameRate(int);
+ method public void setMinFrameWidth(int);
+ method public void setName(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static media.profiles.MediaSettings read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/media/libmedia/xsd/api/last_current.txt b/media/libmedia/xsd/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_current.txt
diff --git a/media/libmedia/xsd/api/last_removed.txt b/media/libmedia/xsd/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_removed.txt
diff --git a/media/libmedia/xsd/api/removed.txt b/media/libmedia/xsd/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libmedia/xsd/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libmedia/xsd/media_profiles.xsd b/media/libmedia/xsd/media_profiles.xsd
new file mode 100644
index 0000000..a9687b0
--- /dev/null
+++ b/media/libmedia/xsd/media_profiles.xsd
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="MediaSettings">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="CamcorderProfiles" type="CamcorderProfiles" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="EncoderOutputFileFormat" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="VideoEncoderCap" type="VideoEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="AudioEncoderCap" type="AudioEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="VideoDecoderCap" type="VideoDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="AudioDecoderCap" type="AudioDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="CamcorderProfiles">
+ <xs:sequence>
+ <xs:element name="EncoderProfile" type="EncoderProfile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="ImageEncoding" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="quality" type="xs:int"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="cameraId" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="EncoderProfile">
+ <xs:sequence>
+ <xs:element name="Video" type="Video" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="Audio" type="Audio" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="quality" type="xs:string"/>
+ <xs:attribute name="fileFormat" type="xs:string"/>
+ <xs:attribute name="duration" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="Video">
+ <xs:attribute name="codec" type="xs:string"/>
+ <xs:attribute name="bitRate" type="xs:int"/>
+ <xs:attribute name="width" type="xs:int"/>
+ <xs:attribute name="height" type="xs:int"/>
+ <xs:attribute name="frameRate" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="Audio">
+ <xs:attribute name="codec" type="xs:string"/>
+ <xs:attribute name="bitRate" type="xs:int"/>
+ <xs:attribute name="sampleRate" type="xs:int"/>
+ <xs:attribute name="channels" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="VideoEncoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ <xs:attribute name="minBitRate" type="xs:int"/>
+ <xs:attribute name="maxBitRate" type="xs:int"/>
+ <xs:attribute name="minFrameWidth" type="xs:int"/>
+ <xs:attribute name="maxFrameWidth" type="xs:int"/>
+ <xs:attribute name="minFrameHeight" type="xs:int"/>
+ <xs:attribute name="maxFrameHeight" type="xs:int"/>
+ <xs:attribute name="minFrameRate" type="xs:int"/>
+ <xs:attribute name="maxFrameRate" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="AudioEncoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ <xs:attribute name="minBitRate" type="xs:int"/>
+ <xs:attribute name="maxBitRate" type="xs:int"/>
+ <xs:attribute name="minSampleRate" type="xs:int"/>
+ <xs:attribute name="maxSampleRate" type="xs:int"/>
+ <xs:attribute name="minChannels" type="xs:int"/>
+ <xs:attribute name="maxChannels" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="VideoDecoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ </xs:complexType>
+ <xs:complexType name="AudioDecoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index bebfb3b..202e964 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -46,3 +46,9 @@
}
+xsd_config {
+ name: "media_codecs",
+ srcs: ["media_codecs.xsd"],
+ package_name: "media.codecs",
+}
+
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
new file mode 100644
index 0000000..f5245c1
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -0,0 +1,108 @@
+// Signature format: 2.0
+package media.codecs {
+
+ public class Decoders {
+ ctor public Decoders();
+ method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+ }
+
+ public class Encoders {
+ ctor public Encoders();
+ method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+ }
+
+ public class Feature {
+ ctor public Feature();
+ method public String getName();
+ method public String getOptional();
+ method public String getRequired();
+ method public String getValue();
+ method public void setName(String);
+ method public void setOptional(String);
+ method public void setRequired(String);
+ method public void setValue(String);
+ }
+
+ public class Limit {
+ ctor public Limit();
+ method public String getIn();
+ method public String getMax();
+ method public String getMin();
+ method public String getName();
+ method public String getRange();
+ method public String getRanges();
+ method public String getScale();
+ method public String getValue();
+ method public String get_default();
+ method public void setIn(String);
+ method public void setMax(String);
+ method public void setMin(String);
+ method public void setName(String);
+ method public void setRange(String);
+ method public void setRanges(String);
+ method public void setScale(String);
+ method public void setValue(String);
+ method public void set_default(String);
+ }
+
+ public class MediaCodec {
+ ctor public MediaCodec();
+ method public java.util.List<media.codecs.Feature> getFeature();
+ method public java.util.List<media.codecs.Limit> getLimit();
+ method public String getName();
+ method public java.util.List<media.codecs.Quirk> getQuirk();
+ method public java.util.List<media.codecs.Type> getType();
+ method public String getType();
+ method public String getUpdate();
+ method public void setName(String);
+ method public void setType(String);
+ method public void setUpdate(String);
+ }
+
+ public class MediaCodecs {
+ ctor public MediaCodecs();
+ method public java.util.List<media.codecs.Decoders> getDecoders();
+ method public java.util.List<media.codecs.Encoders> getEncoders();
+ method public java.util.List<media.codecs.Settings> getSettings();
+ }
+
+ public class Quirk {
+ ctor public Quirk();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Setting {
+ ctor public Setting();
+ method public String getName();
+ method public String getUpdate();
+ method public String getValue();
+ method public void setName(String);
+ method public void setUpdate(String);
+ method public void setValue(String);
+ }
+
+ public class Settings {
+ ctor public Settings();
+ method public java.util.List<media.codecs.Setting> getSetting();
+ }
+
+ public class Type {
+ ctor public Type();
+ method public java.util.List<media.codecs.Feature> getFeature();
+ method public java.util.List<media.codecs.Limit> getLimit();
+ method public String getName();
+ method public String getUpdate();
+ method public void setName(String);
+ method public void setUpdate(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static media.codecs.MediaCodecs read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/media/libstagefright/xmlparser/api/last_current.txt b/media/libstagefright/xmlparser/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_current.txt
diff --git a/media/libstagefright/xmlparser/api/last_removed.txt b/media/libstagefright/xmlparser/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_removed.txt
diff --git a/media/libstagefright/xmlparser/api/removed.txt b/media/libstagefright/xmlparser/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libstagefright/xmlparser/media_codecs.xsd b/media/libstagefright/xmlparser/media_codecs.xsd
new file mode 100644
index 0000000..4faba87
--- /dev/null
+++ b/media/libstagefright/xmlparser/media_codecs.xsd
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="MediaCodecs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Decoders" type="Decoders" maxOccurs="unbounded"/>
+ <xs:element name="Encoders" type="Encoders" maxOccurs="unbounded"/>
+ <xs:element name="Settings" type="Settings" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="Decoders">
+ <xs:sequence>
+ <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="Encoders">
+ <xs:sequence>
+ <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="Settings">
+ <xs:sequence>
+ <xs:element name="Setting" type="Setting" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="MediaCodec">
+ <xs:sequence>
+ <xs:element name="Quirk" type="Quirk" maxOccurs="unbounded"/>
+ <xs:element name="Type" type="Type" maxOccurs="unbounded"/>
+ <xs:element name="Limit" type="Limit" maxOccurs="unbounded"/>
+ <xs:element name="Feature" type="Feature" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="type" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Quirk">
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Type">
+ <xs:sequence>
+ <xs:element name="Limit" type="Limit" maxOccurs="unbounded"/>
+ <xs:element name="Feature" type="Feature" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Limit">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="default" type="xs:string"/>
+ <xs:attribute name="in" type="xs:string"/>
+ <xs:attribute name="max" type="xs:string"/>
+ <xs:attribute name="min" type="xs:string"/>
+ <xs:attribute name="range" type="xs:string"/>
+ <xs:attribute name="ranges" type="xs:string"/>
+ <xs:attribute name="scale" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Feature">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="optional" type="xs:string"/>
+ <xs:attribute name="required" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Setting">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 62ec955..51d0682 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2180,31 +2180,37 @@
return mp;
}
-void CameraService::loadSound() {
+void CameraService::increaseSoundRef() {
+ Mutex::Autolock lock(mSoundLock);
+ mSoundRef++;
+}
+
+void CameraService::loadSoundLocked(sound_kind kind) {
ATRACE_CALL();
- Mutex::Autolock lock(mSoundLock);
- LOG1("CameraService::loadSound ref=%d", mSoundRef);
- if (mSoundRef++) return;
-
- mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
- if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
- mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
- }
- mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
- if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
- mSoundPlayer[SOUND_RECORDING_START] =
+ LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef);
+ if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) {
+ mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
+ if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
+ mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
+ }
+ } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] == NULL) {
+ mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
+ if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
+ mSoundPlayer[SOUND_RECORDING_START] =
newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
- }
- mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
- if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
- mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+ }
+ } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) {
+ mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
+ if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
+ mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+ }
}
}
-void CameraService::releaseSound() {
+void CameraService::decreaseSoundRef() {
Mutex::Autolock lock(mSoundLock);
- LOG1("CameraService::releaseSound ref=%d", mSoundRef);
+ LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef);
if (--mSoundRef) return;
for (int i = 0; i < NUM_SOUNDS; i++) {
@@ -2220,6 +2226,7 @@
LOG1("playSound(%d)", kind);
Mutex::Autolock lock(mSoundLock);
+ loadSoundLocked(kind);
sp<MediaPlayer> player = mSoundPlayer[kind];
if (player != 0) {
player->seekTo(0);
@@ -2249,7 +2256,7 @@
mRemoteCallback = cameraClient;
- cameraService->loadSound();
+ cameraService->increaseSoundRef();
LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
}
@@ -2259,7 +2266,7 @@
ALOGV("~Client");
mDestructionStarted = true;
- sCameraService->releaseSound();
+ sCameraService->decreaseSoundRef();
// unconditionally disconnect. function is idempotent
Client::disconnect();
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 65727ec..344dd92 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -192,10 +192,10 @@
NUM_SOUNDS
};
- void loadSound();
void playSound(sound_kind kind);
- void releaseSound();
-
+ void loadSoundLocked(sound_kind kind);
+ void decreaseSoundRef();
+ void increaseSoundRef();
/**
* Update the state of a given camera device (open/close/active/idle) with
* the camera proxy service in the system service