diff options
Diffstat (limited to 'packages')
80 files changed, 2555 insertions, 938 deletions
diff --git a/packages/DefaultContainerService/Android.mk b/packages/DefaultContainerService/Android.mk new file mode 100755 index 0000000..2f1d6ab --- /dev/null +++ b/packages/DefaultContainerService/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := DefaultContainerService + +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml new file mode 100755 index 0000000..078daa7 --- /dev/null +++ b/packages/DefaultContainerService/AndroidManifest.xml @@ -0,0 +1,19 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.defcontainer"> + <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/> + <uses-permission android:name="android.permission.ASEC_ACCESS"/> + <uses-permission android:name="android.permission.ASEC_CREATE"/> + <uses-permission android:name="android.permission.ASEC_DESTROY"/> + <uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"/> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" /> + + <application android:label="@string/service_name"> + + <service android:name=".DefaultContainerService" + android:enabled="true" + android:exported="true" + android:permission="android.permission.COPY_PROTECTED_DATA"/> + </application> + +</manifest> diff --git a/packages/DefaultContainerService/res/values-cs/strings.xml b/packages/DefaultContainerService/res/values-cs/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-cs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-da/strings.xml b/packages/DefaultContainerService/res/values-da/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-da/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-de/strings.xml b/packages/DefaultContainerService/res/values-de/strings.xml new file mode 100644 index 0000000..5d12956 --- /dev/null +++ b/packages/DefaultContainerService/res/values-de/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Medien-Containerdienst"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-el/strings.xml b/packages/DefaultContainerService/res/values-el/strings.xml new file mode 100644 index 0000000..b0b5794 --- /dev/null +++ b/packages/DefaultContainerService/res/values-el/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Υπηρεσία Media Container"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-es-rUS/strings.xml b/packages/DefaultContainerService/res/values-es-rUS/strings.xml new file mode 100644 index 0000000..cf893de --- /dev/null +++ b/packages/DefaultContainerService/res/values-es-rUS/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Servicio de contención de medios"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-es/strings.xml b/packages/DefaultContainerService/res/values-es/strings.xml new file mode 100644 index 0000000..6817520 --- /dev/null +++ b/packages/DefaultContainerService/res/values-es/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Servicio de contenedor de medios"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-fr/strings.xml b/packages/DefaultContainerService/res/values-fr/strings.xml new file mode 100644 index 0000000..3b4a90d --- /dev/null +++ b/packages/DefaultContainerService/res/values-fr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Service de support multimédia"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-it/strings.xml b/packages/DefaultContainerService/res/values-it/strings.xml new file mode 100644 index 0000000..55bd6e5 --- /dev/null +++ b/packages/DefaultContainerService/res/values-it/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Servizio Media Container"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-ja/strings.xml b/packages/DefaultContainerService/res/values-ja/strings.xml new file mode 100644 index 0000000..dc1dfea --- /dev/null +++ b/packages/DefaultContainerService/res/values-ja/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"メディアコンテナサービス"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-ko/strings.xml b/packages/DefaultContainerService/res/values-ko/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-ko/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-nb/strings.xml b/packages/DefaultContainerService/res/values-nb/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-nb/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-nl/strings.xml b/packages/DefaultContainerService/res/values-nl/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-nl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-pl/strings.xml b/packages/DefaultContainerService/res/values-pl/strings.xml new file mode 100644 index 0000000..0c96f3d --- /dev/null +++ b/packages/DefaultContainerService/res/values-pl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Usługa kontenera multimediów"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-pt-rPT/strings.xml b/packages/DefaultContainerService/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-pt-rPT/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-pt/strings.xml b/packages/DefaultContainerService/res/values-pt/strings.xml new file mode 100644 index 0000000..00b90de --- /dev/null +++ b/packages/DefaultContainerService/res/values-pt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Serviço de recipiente de mídia"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-ru/strings.xml b/packages/DefaultContainerService/res/values-ru/strings.xml new file mode 100644 index 0000000..0179e85 --- /dev/null +++ b/packages/DefaultContainerService/res/values-ru/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Media Container Service"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-sv/strings.xml b/packages/DefaultContainerService/res/values-sv/strings.xml new file mode 100644 index 0000000..b097814 --- /dev/null +++ b/packages/DefaultContainerService/res/values-sv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Medietjänst"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-tr/strings.xml b/packages/DefaultContainerService/res/values-tr/strings.xml new file mode 100644 index 0000000..afd870f --- /dev/null +++ b/packages/DefaultContainerService/res/values-tr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"Ortam Kapsayıcı Hizmeti"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-zh-rCN/strings.xml b/packages/DefaultContainerService/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..4f99d1b --- /dev/null +++ b/packages/DefaultContainerService/res/values-zh-rCN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"媒体容器服务"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values-zh-rTW/strings.xml b/packages/DefaultContainerService/res/values-zh-rTW/strings.xml new file mode 100644 index 0000000..38870f6 --- /dev/null +++ b/packages/DefaultContainerService/res/values-zh-rTW/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="service_name" msgid="2260781993795858516">"媒體庫服務"</string> +</resources> diff --git a/packages/DefaultContainerService/res/values/strings.xml b/packages/DefaultContainerService/res/values/strings.xml new file mode 100644 index 0000000..2897f34 --- /dev/null +++ b/packages/DefaultContainerService/res/values/strings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2008, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- service name --> + <string name="service_name">Media Container Service</string> +</resources> diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java new file mode 100644 index 0000000..79c8f9a --- /dev/null +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -0,0 +1,454 @@ +/* + * Copyright (C) 2010 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.defcontainer; + +import com.android.internal.app.IMediaContainerService; +import com.android.internal.content.PackageHelper; +import android.content.Intent; +import android.content.pm.IPackageManager; +import android.content.pm.PackageInfo; +import android.content.pm.PackageInfoLite; +import android.content.pm.PackageManager; +import android.content.pm.PackageParser; +import android.net.Uri; +import android.os.Environment; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.StatFs; +import android.app.IntentService; +import android.util.DisplayMetrics; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import android.os.FileUtils; +import android.provider.Settings; + +/* + * This service copies a downloaded apk to a file passed in as + * a ParcelFileDescriptor or to a newly created container specified + * by parameters. The DownloadManager gives access to this process + * based on its uid. This process also needs the ACCESS_DOWNLOAD_MANAGER + * permission to access apks downloaded via the download manager. + */ +public class DefaultContainerService extends IntentService { + private static final String TAG = "DefContainer"; + private static final boolean localLOGV = true; + + private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() { + /* + * Creates a new container and copies resource there. + * @param paackageURI the uri of resource to be copied. Can be either + * a content uri or a file uri + * @param cid the id of the secure container that should + * be used for creating a secure container into which the resource + * will be copied. + * @param key Refers to key used for encrypting the secure container + * @param resFileName Name of the target resource file(relative to newly + * created secure container) + * @return Returns the new cache path where the resource has been copied into + * + */ + public String copyResourceToContainer(final Uri packageURI, + final String cid, + final String key, final String resFileName) { + if (packageURI == null || cid == null) { + return null; + } + return copyResourceInner(packageURI, cid, key, resFileName); + } + + /* + * Copy specified resource to output stream + * @param packageURI the uri of resource to be copied. Should be a + * file uri + * @param outStream Remote file descriptor to be used for copying + * @return Returns true if copy succeded or false otherwise. + */ + public boolean copyResource(final Uri packageURI, + ParcelFileDescriptor outStream) { + if (packageURI == null || outStream == null) { + return false; + } + ParcelFileDescriptor.AutoCloseOutputStream + autoOut = new ParcelFileDescriptor.AutoCloseOutputStream(outStream); + return copyFile(packageURI, autoOut); + } + + /* + * Determine the recommended install location for package + * specified by file uri location. + * @param fileUri the uri of resource to be copied. Should be a + * file uri + * @return Returns PackageInfoLite object containing + * the package info and recommended app location. + */ + public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags) { + PackageInfoLite ret = new PackageInfoLite(); + if (fileUri == null) { + Log.i(TAG, "Invalid package uri " + fileUri); + ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK; + return ret; + } + String scheme = fileUri.getScheme(); + if (scheme != null && !scheme.equals("file")) { + Log.w(TAG, "Falling back to installing on internal storage only"); + ret.recommendedInstallLocation = PackageHelper.RECOMMEND_INSTALL_INTERNAL; + return ret; + } + String archiveFilePath = fileUri.getPath(); + PackageParser packageParser = new PackageParser(archiveFilePath); + File sourceFile = new File(archiveFilePath); + DisplayMetrics metrics = new DisplayMetrics(); + metrics.setToDefaults(); + PackageParser.PackageLite pkg = packageParser.parsePackageLite( + archiveFilePath, 0); + ret.packageName = pkg.packageName; + ret.installLocation = pkg.installLocation; + // Nuke the parser reference right away and force a gc + packageParser = null; + Runtime.getRuntime().gc(); + if (pkg == null) { + Log.w(TAG, "Failed to parse package"); + ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK; + return ret; + } + ret.packageName = pkg.packageName; + ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath, flags); + return ret; + } + + public boolean checkFreeStorage(boolean external, Uri fileUri) { + return checkFreeStorageInner(external, fileUri); + } + }; + + public DefaultContainerService() { + super("DefaultContainerService"); + setIntentRedelivery(true); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) { + IPackageManager pm = IPackageManager.Stub.asInterface( + ServiceManager.getService("package")); + String pkg = null; + try { + while ((pkg=pm.nextPackageToClean(pkg)) != null) { + eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg)); + eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg)); + } + } catch (RemoteException e) { + } + } + } + + void eraseFiles(File path) { + if (path.isDirectory()) { + String[] files = path.list(); + if (files != null) { + for (String file : files) { + eraseFiles(new File(path, file)); + } + } + } + path.delete(); + } + + public IBinder onBind(Intent intent) { + return mBinder; + } + + private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) { + // Make sure the sdcard is mounted. + String status = Environment.getExternalStorageState(); + if (!status.equals(Environment.MEDIA_MOUNTED)) { + Log.w(TAG, "Make sure sdcard is mounted."); + return null; + } + // Create new container at newCachePath + String codePath = packageURI.getPath(); + File codeFile = new File(codePath); + String newCachePath = null; + // Create new container + if ((newCachePath = PackageHelper.createSdDir(codeFile, + newCid, key, Process.myUid())) == null) { + Log.e(TAG, "Failed to create container " + newCid); + return null; + } + if (localLOGV) Log.i(TAG, "Created container for " + newCid + + " at path : " + newCachePath); + File resFile = new File(newCachePath, resFileName); + if (!FileUtils.copyFile(new File(codePath), resFile)) { + Log.e(TAG, "Failed to copy " + codePath + " to " + resFile); + // Clean up container + PackageHelper.destroySdDir(newCid); + return null; + } + if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile); + if (!PackageHelper.finalizeSdDir(newCid)) { + Log.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath); + // Clean up container + PackageHelper.destroySdDir(newCid); + } + if (localLOGV) Log.i(TAG, "Finalized container " + newCid); + if (PackageHelper.isContainerMounted(newCid)) { + if (localLOGV) Log.i(TAG, "Unmounting " + newCid + + " at path " + newCachePath); + // Force a gc to avoid being killed. + Runtime.getRuntime().gc(); + PackageHelper.unMountSdDir(newCid); + } else { + if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted"); + } + return newCachePath; + } + + public static boolean copyToFile(InputStream inputStream, FileOutputStream out) { + try { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) >= 0) { + out.write(buffer, 0, bytesRead); + } + return true; + } catch (IOException e) { + Log.i(TAG, "Exception : " + e + " when copying file"); + return false; + } + } + + public static boolean copyToFile(File srcFile, FileOutputStream out) { + InputStream inputStream = null; + try { + inputStream = new FileInputStream(srcFile); + return copyToFile(inputStream, out); + } catch (IOException e) { + return false; + } finally { + try { if (inputStream != null) inputStream.close(); } catch (IOException e) {} + } + } + + private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) { + String scheme = pPackageURI.getScheme(); + if (scheme == null || scheme.equals("file")) { + final File srcPackageFile = new File(pPackageURI.getPath()); + // We copy the source package file to a temp file and then rename it to the + // destination file in order to eliminate a window where the package directory + // scanner notices the new package file but it's not completely copied yet. + if (!copyToFile(srcPackageFile, outStream)) { + Log.e(TAG, "Couldn't copy file: " + srcPackageFile); + return false; + } + } else if (scheme.equals("content")) { + ParcelFileDescriptor fd = null; + try { + fd = getContentResolver().openFileDescriptor(pPackageURI, "r"); + } catch (FileNotFoundException e) { + Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e); + return false; + } + if (fd == null) { + Log.e(TAG, "Couldn't open file descriptor from download service (null)."); + return false; + } else { + if (localLOGV) { + Log.v(TAG, "Opened file descriptor from download service."); + } + ParcelFileDescriptor.AutoCloseInputStream + dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd); + // We copy the source package file to a temp file and then rename it to the + // destination file in order to eliminate a window where the package directory + // scanner notices the new package file but it's not completely copied yet. + if (!copyToFile(dlStream, outStream)) { + Log.e(TAG, "Couldn't copy " + pPackageURI + " to temp file."); + return false; + } + } + } else { + Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI); + return false; + } + return true; + } + + // Constants related to app heuristics + // No-installation limit for internal flash: 10% or less space available + private static final double LOW_NAND_FLASH_TRESHOLD = 0.1; + + // SD-to-internal app size threshold: currently set to 1 MB + private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024); + private static final int ERR_LOC = -1; + + private int recommendAppInstallLocation(int installLocation, + String archiveFilePath, int flags) { + boolean checkInt = false; + boolean checkExt = false; + boolean checkBoth = false; + check_inner : { + // Check flags. + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { + // Check for forward locked app + checkInt = true; + break check_inner; + } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { + // Explicit flag to install internally. + // Check internal storage and return + checkInt = true; + break check_inner; + } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { + // Explicit flag to install externally. + // Check external storage and return + checkExt = true; + break check_inner; + } + // Check for manifest option + if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { + checkInt = true; + break check_inner; + } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { + checkExt = true; + checkBoth = true; + break check_inner; + } else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) { + checkInt = true; + checkBoth = true; + break check_inner; + } + // Pick user preference + int installPreference = Settings.System.getInt(getApplicationContext() + .getContentResolver(), + Settings.Secure.DEFAULT_INSTALL_LOCATION, + PackageHelper.APP_INSTALL_AUTO); + if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) { + checkInt = true; + break check_inner; + } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) { + checkExt = true; + break check_inner; + } + // Fall back to default policy if nothing else is specified. + checkInt = true; + } + + // Package size = code size + cache size + data size + // If code size > 1 MB, install on SD card. + // Else install on internal NAND flash, unless space on NAND is less than 10% + String status = Environment.getExternalStorageState(); + long availSDSize = -1; + boolean mediaAvailable = false; + if (status.equals(Environment.MEDIA_MOUNTED)) { + StatFs sdStats = new StatFs( + Environment.getExternalStorageDirectory().getPath()); + availSDSize = (long)sdStats.getAvailableBlocks() * + (long)sdStats.getBlockSize(); + mediaAvailable = true; + } + StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath()); + long totalInternalSize = (long)internalStats.getBlockCount() * + (long)internalStats.getBlockSize(); + long availInternalSize = (long)internalStats.getAvailableBlocks() * + (long)internalStats.getBlockSize(); + + double pctNandFree = (double)availInternalSize / (double)totalInternalSize; + + File apkFile = new File(archiveFilePath); + long pkgLen = apkFile.length(); + + // To make final copy + long reqInstallSize = pkgLen; + // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now. + long reqInternalSize = 0; + boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD); + boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize); + boolean fitsOnSd = false; + if (mediaAvailable && (reqInstallSize < availSDSize)) { + // If we do not have an internal size requirement + // don't do a threshold check. + if (reqInternalSize == 0) { + fitsOnSd = true; + } else if ((reqInternalSize < availInternalSize) && intThresholdOk) { + fitsOnSd = true; + } + } + boolean fitsOnInt = intThresholdOk && intAvailOk; + if (checkInt) { + // Check for internal memory availability + if (fitsOnInt) { + return PackageHelper.RECOMMEND_INSTALL_INTERNAL; + } + } else if (checkExt) { + if (fitsOnSd) { + return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; + } + } + if (checkBoth) { + // Check for internal first + if (fitsOnInt) { + return PackageHelper.RECOMMEND_INSTALL_INTERNAL; + } + // Check for external next + if (fitsOnSd) { + return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; + } + } + if (checkExt || checkBoth && !mediaAvailable) { + return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE; + } + return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; + } + + private boolean checkFreeStorageInner(boolean external, Uri packageURI) { + File apkFile = new File(packageURI.getPath()); + long size = apkFile.length(); + if (external) { + String status = Environment.getExternalStorageState(); + long availSDSize = -1; + if (status.equals(Environment.MEDIA_MOUNTED)) { + StatFs sdStats = new StatFs( + Environment.getExternalStorageDirectory().getPath()); + availSDSize = (long)sdStats.getAvailableBlocks() * + (long)sdStats.getBlockSize(); + } + return availSDSize > size; + } + StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath()); + long totalInternalSize = (long)internalStats.getBlockCount() * + (long)internalStats.getBlockSize(); + long availInternalSize = (long)internalStats.getAvailableBlocks() * + (long)internalStats.getBlockSize(); + + double pctNandFree = (double)availInternalSize / (double)totalInternalSize; + // To make final copy + long reqInstallSize = size; + // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now. + long reqInternalSize = 0; + boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD); + boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize); + return intThresholdOk && intAvailOk; + } +} diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk index 724e988..bf4ab1b 100644 --- a/packages/SettingsProvider/Android.mk +++ b/packages/SettingsProvider/Android.mk @@ -1,7 +1,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := user +LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index 1e1d729..d057ab7 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -2,8 +2,6 @@ package="com.android.providers.settings" android:sharedUserId="android.uid.system"> - <uses-permission android:name="android.permission.BACKUP_DATA" /> - <application android:allowClearUserData="false" android:label="@string/app_label" android:process="system" diff --git a/packages/SettingsProvider/etc/Android.mk b/packages/SettingsProvider/etc/Android.mk deleted file mode 100644 index 81ca4b1..0000000 --- a/packages/SettingsProvider/etc/Android.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (C) 2008 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. -# - -LOCAL_PATH := $(my-dir) - -######################## -include $(CLEAR_VARS) - -LOCAL_MODULE := bookmarks.xml - -LOCAL_MODULE_TAGS := user - -# This will install the file in /system/etc -# -LOCAL_MODULE_CLASS := ETC - -LOCAL_SRC_FILES := $(LOCAL_MODULE) - -include $(BUILD_PREBUILT) - diff --git a/packages/SettingsProvider/res/values-cs/strings.xml b/packages/SettingsProvider/res/values-cs/strings.xml index 2b089d9..a28ffa1 100644 --- a/packages/SettingsProvider/res/values-cs/strings.xml +++ b/packages/SettingsProvider/res/values-cs/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Paměť pro nastavení"</string> diff --git a/packages/SettingsProvider/res/values-da/strings.xml b/packages/SettingsProvider/res/values-da/strings.xml index bc160f3..ed450d5 100644 --- a/packages/SettingsProvider/res/values-da/strings.xml +++ b/packages/SettingsProvider/res/values-da/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Lagring af indstillinger"</string> diff --git a/packages/SettingsProvider/res/values-de/strings.xml b/packages/SettingsProvider/res/values-de/strings.xml index a293522..6effbae 100644 --- a/packages/SettingsProvider/res/values-de/strings.xml +++ b/packages/SettingsProvider/res/values-de/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Einstellungsspeicher"</string> diff --git a/packages/SettingsProvider/res/values-el/strings.xml b/packages/SettingsProvider/res/values-el/strings.xml index 1cac86d..5bd1fa6 100644 --- a/packages/SettingsProvider/res/values-el/strings.xml +++ b/packages/SettingsProvider/res/values-el/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Αποθηκευτικός χώρος ρυθμίσεων"</string> diff --git a/packages/SettingsProvider/res/values-es-rUS/strings.xml b/packages/SettingsProvider/res/values-es-rUS/strings.xml index de3958b..7a15d8b 100644 --- a/packages/SettingsProvider/res/values-es-rUS/strings.xml +++ b/packages/SettingsProvider/res/values-es-rUS/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Almacenamiento de configuración"</string> diff --git a/packages/SettingsProvider/res/values-es/strings.xml b/packages/SettingsProvider/res/values-es/strings.xml index de3958b..7a15d8b 100644 --- a/packages/SettingsProvider/res/values-es/strings.xml +++ b/packages/SettingsProvider/res/values-es/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Almacenamiento de configuración"</string> diff --git a/packages/SettingsProvider/res/values-fr/strings.xml b/packages/SettingsProvider/res/values-fr/strings.xml index 7a1386a..c90eb09 100644 --- a/packages/SettingsProvider/res/values-fr/strings.xml +++ b/packages/SettingsProvider/res/values-fr/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Stockage des paramètres"</string> diff --git a/packages/SettingsProvider/res/values-it/strings.xml b/packages/SettingsProvider/res/values-it/strings.xml index f88a654..40735cc 100644 --- a/packages/SettingsProvider/res/values-it/strings.xml +++ b/packages/SettingsProvider/res/values-it/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Archiviazione impostazioni"</string> diff --git a/packages/SettingsProvider/res/values-ja/strings.xml b/packages/SettingsProvider/res/values-ja/strings.xml index ffd57e6..d222ca9 100644 --- a/packages/SettingsProvider/res/values-ja/strings.xml +++ b/packages/SettingsProvider/res/values-ja/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"ストレージの設定"</string> diff --git a/packages/SettingsProvider/res/values-ko/strings.xml b/packages/SettingsProvider/res/values-ko/strings.xml index aab51d6..8e0cc75 100644 --- a/packages/SettingsProvider/res/values-ko/strings.xml +++ b/packages/SettingsProvider/res/values-ko/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"설정 저장소"</string> diff --git a/packages/SettingsProvider/res/values-nb/strings.xml b/packages/SettingsProvider/res/values-nb/strings.xml index c96b1eb..ad18f94 100644 --- a/packages/SettingsProvider/res/values-nb/strings.xml +++ b/packages/SettingsProvider/res/values-nb/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Lagring av innstillinger"</string> diff --git a/packages/SettingsProvider/res/values-nl/strings.xml b/packages/SettingsProvider/res/values-nl/strings.xml index 7a0e416..010fdb5 100644 --- a/packages/SettingsProvider/res/values-nl/strings.xml +++ b/packages/SettingsProvider/res/values-nl/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Opslagruimte voor instellingen"</string> diff --git a/packages/SettingsProvider/res/values-pl/strings.xml b/packages/SettingsProvider/res/values-pl/strings.xml index ccff82e3..9f81e63 100644 --- a/packages/SettingsProvider/res/values-pl/strings.xml +++ b/packages/SettingsProvider/res/values-pl/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Pamięć ustawień"</string> diff --git a/packages/SettingsProvider/res/values-pt-rPT/strings.xml b/packages/SettingsProvider/res/values-pt-rPT/strings.xml index 1e1dccb..6bd62e3 100644 --- a/packages/SettingsProvider/res/values-pt-rPT/strings.xml +++ b/packages/SettingsProvider/res/values-pt-rPT/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Armazenamento de Definições"</string> diff --git a/packages/SettingsProvider/res/values-pt/strings.xml b/packages/SettingsProvider/res/values-pt/strings.xml index c4af964..ade1746 100644 --- a/packages/SettingsProvider/res/values-pt/strings.xml +++ b/packages/SettingsProvider/res/values-pt/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Armazenamento de configurações"</string> diff --git a/packages/SettingsProvider/res/values-ru/strings.xml b/packages/SettingsProvider/res/values-ru/strings.xml index bcf92fa..4c15984 100644 --- a/packages/SettingsProvider/res/values-ru/strings.xml +++ b/packages/SettingsProvider/res/values-ru/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Хранилище настроек"</string> diff --git a/packages/SettingsProvider/res/values-sv/strings.xml b/packages/SettingsProvider/res/values-sv/strings.xml index fa3f5cb..b6de084 100644 --- a/packages/SettingsProvider/res/values-sv/strings.xml +++ b/packages/SettingsProvider/res/values-sv/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Lagring av inställningar"</string> diff --git a/packages/SettingsProvider/res/values-tr/strings.xml b/packages/SettingsProvider/res/values-tr/strings.xml index dc36cda..e99e99b 100644 --- a/packages/SettingsProvider/res/values-tr/strings.xml +++ b/packages/SettingsProvider/res/values-tr/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Ayarlar Deposu"</string> diff --git a/packages/SettingsProvider/res/values-zh-rCN/strings.xml b/packages/SettingsProvider/res/values-zh-rCN/strings.xml index daf1254..11c5d6c 100644 --- a/packages/SettingsProvider/res/values-zh-rCN/strings.xml +++ b/packages/SettingsProvider/res/values-zh-rCN/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"设置存储"</string> diff --git a/packages/SettingsProvider/res/values-zh-rTW/strings.xml b/packages/SettingsProvider/res/values-zh-rTW/strings.xml index 0700a76..977c9b9 100644 --- a/packages/SettingsProvider/res/values-zh-rTW/strings.xml +++ b/packages/SettingsProvider/res/values-zh-rTW/strings.xml @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 The Android Open Source Project +<!-- +/** + * Copyright (c) 2007, 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. + */ + --> - 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"設定儲存空間"</string> diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index ab93d8c..185d72a 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -51,4 +51,24 @@ <!-- Default value for whether or not to pulse the notification LED when there is a pending notification --> <bool name="def_notification_pulse">true</bool> + + <bool name="def_mount_play_notification_snd">true</bool> + <bool name="def_mount_ums_autostart">false</bool> + <bool name="def_mount_ums_prompt">true</bool> + <bool name="def_mount_ums_notify_enabled">true</bool> + + <!-- user interface sound effects --> + <integer name="def_power_sounds_enabled">1</integer> + <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string> + <integer name="def_dock_sounds_enabled">0</integer> + <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string> + <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string> + <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string> + <string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string> + <integer name="def_lockscreen_sounds_enabled">0</integer> + <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string> + <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string> + + <!-- Default for Settings.System.VIBRATE_IN_SILENT --> + <bool name="def_vibrate_in_silent">true</bool> </resources> diff --git a/packages/SettingsProvider/etc/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml index 734e0cd..dfaeeaf 100644 --- a/packages/SettingsProvider/etc/bookmarks.xml +++ b/packages/SettingsProvider/res/xml/bookmarks.xml @@ -32,8 +32,8 @@ class="com.google.android.gm.ConversationListActivityGmail" shortcut="g" /> <bookmark - package="com.android.providers.im" - class="com.android.providers.im.LandingPage" + package="com.android.im" + class="com.android.im.app.LandingPage" shortcut="i" /> <bookmark package="com.android.calendar" @@ -53,8 +53,4 @@ package="com.android.mms" class="com.android.mms.ui.ConversationList" shortcut="s" /> - <bookmark - package="com.google.android.youtube" - class="com.google.android.youtube.HomeActivity" - shortcut="y" /> </bookmarks> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 1a64e20..2b4714d 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -21,36 +21,33 @@ import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.res.Resources; +import android.content.res.XmlResourceParser; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteDoneException; -import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.media.AudioManager; import android.media.AudioService; import android.net.ConnectivityManager; -import android.os.Environment; import android.os.SystemProperties; import android.provider.Settings; +import android.provider.Settings.Secure; import android.text.TextUtils; +import android.util.AttributeSet; import android.util.Config; import android.util.Log; import android.util.Xml; -import com.android.internal.util.XmlUtils; -import com.android.internal.telephony.RILConstants; +import com.android.internal.content.PackageHelper; +import com.android.internal.telephony.RILConstants; +import com.android.internal.util.XmlUtils; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.util.List; @@ -59,11 +56,6 @@ import java.util.List; * Mostly just has a bit {@link #onCreate} to initialize the database. */ public class DatabaseHelper extends SQLiteOpenHelper { - /** - * Path to file containing default bookmarks, relative to ANDROID_ROOT. - */ - private static final String DEFAULT_BOOKMARKS_PATH = "etc/bookmarks.xml"; - private static final String TAG = "SettingsProvider"; private static final String DATABASE_NAME = "settings.db"; @@ -71,7 +63,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 43; + private static final int DATABASE_VERSION = 56; private Context mContext; @@ -100,13 +92,6 @@ public class DatabaseHelper extends SQLiteOpenHelper { createSecureTable(db); - db.execSQL("CREATE TABLE gservices (" + - "_id INTEGER PRIMARY KEY AUTOINCREMENT," + - "name TEXT UNIQUE ON CONFLICT REPLACE," + - "value TEXT" + - ");"); - db.execSQL("CREATE INDEX gservicesIndex1 ON gservices (name);"); - db.execSQL("CREATE TABLE bluetooth_devices (" + "_id INTEGER PRIMARY KEY," + "name TEXT," + @@ -159,7 +144,6 @@ public class DatabaseHelper extends SQLiteOpenHelper { * notification vibrate to on. */ loadVibrateSetting(db, true); - if (Config.LOGD) Log.d(TAG, "Reset system vibrate setting"); upgradeVersion = 21; } @@ -234,18 +218,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } if (upgradeVersion == 27) { - // Copy settings values from 'system' to 'secure' and delete them from 'system' - SQLiteStatement insertStmt = null; - SQLiteStatement deleteStmt = null; - - db.beginTransaction(); - try { - insertStmt = - db.compileStatement("INSERT INTO secure (name,value) SELECT name,value FROM " - + "system WHERE name=?"); - deleteStmt = db.compileStatement("DELETE FROM system WHERE name=?"); - - String[] settingsToMove = { + String[] settingsToMove = { Settings.Secure.ADB_ENABLED, Settings.Secure.ANDROID_ID, Settings.Secure.BLUETOOTH_ON, @@ -278,24 +251,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS, Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS, }; - - for (String setting : settingsToMove) { - insertStmt.bindString(1, setting); - insertStmt.execute(); - - deleteStmt.bindString(1, setting); - deleteStmt.execute(); - } - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - if (insertStmt != null) { - insertStmt.close(); - } - if (deleteStmt != null) { - deleteStmt.close(); - } - } + moveFromSystemToSecure(db, settingsToMove); upgradeVersion = 28; } @@ -347,18 +303,19 @@ public class DatabaseHelper extends SQLiteOpenHelper { * enabled or disabled based on product resources. */ db.beginTransaction(); + SQLiteStatement stmt = null; try { db.execSQL("DELETE FROM system WHERE name='" + Settings.System.WINDOW_ANIMATION_SCALE + "'"); db.execSQL("DELETE FROM system WHERE name='" + Settings.System.TRANSITION_ANIMATION_SCALE + "'"); - SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)" + stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);"); loadDefaultAnimationSettings(stmt); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 32; } @@ -395,14 +352,15 @@ public class DatabaseHelper extends SQLiteOpenHelper { if (upgradeVersion == 34) { db.beginTransaction(); + SQLiteStatement stmt = null; try { - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" + stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" + " VALUES(?,?);"); loadSecure35Settings(stmt); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 35; } @@ -437,15 +395,16 @@ public class DatabaseHelper extends SQLiteOpenHelper { if (upgradeVersion == 37) { db.beginTransaction(); + SQLiteStatement stmt = null; try { - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + " VALUES(?,?);"); loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, R.string.airplane_mode_toggleable_radios); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 38; } @@ -486,18 +445,19 @@ public class DatabaseHelper extends SQLiteOpenHelper { * All animations are now turned on by default! */ db.beginTransaction(); + SQLiteStatement stmt = null; try { db.execSQL("DELETE FROM system WHERE name='" + Settings.System.WINDOW_ANIMATION_SCALE + "'"); db.execSQL("DELETE FROM system WHERE name='" + Settings.System.TRANSITION_ANIMATION_SCALE + "'"); - SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)" + stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);"); loadDefaultAnimationSettings(stmt); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 41; } @@ -507,16 +467,17 @@ public class DatabaseHelper extends SQLiteOpenHelper { * Initialize newly public haptic feedback setting */ db.beginTransaction(); + SQLiteStatement stmt = null; try { db.execSQL("DELETE FROM system WHERE name='" + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'"); - SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)" + stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);"); loadDefaultHapticSettings(stmt); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 42; } @@ -526,19 +487,215 @@ public class DatabaseHelper extends SQLiteOpenHelper { * Initialize new notification pulse setting */ db.beginTransaction(); + SQLiteStatement stmt = null; try { - SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)" + stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);"); loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE, R.bool.def_notification_pulse); - stmt.close(); db.setTransactionSuccessful(); } finally { db.endTransaction(); + if (stmt != null) stmt.close(); } upgradeVersion = 43; } + if (upgradeVersion == 43) { + /* + * This upgrade stores bluetooth volume separately from voice volume + */ + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + + " VALUES(?,?);"); + loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + upgradeVersion = 44; + } + + if (upgradeVersion == 44) { + /* + * Gservices was moved into vendor/google. + */ + db.execSQL("DROP TABLE IF EXISTS gservices"); + db.execSQL("DROP INDEX IF EXISTS gservicesIndex1"); + upgradeVersion = 45; + } + + if (upgradeVersion == 45) { + /* + * New settings for MountService + */ + db.beginTransaction(); + try { + db.execSQL("INSERT INTO secure(name,value) values('" + + Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND + "','1');"); + db.execSQL("INSERT INTO secure(name,value) values('" + + Settings.Secure.MOUNT_UMS_AUTOSTART + "','0');"); + db.execSQL("INSERT INTO secure(name,value) values('" + + Settings.Secure.MOUNT_UMS_PROMPT + "','1');"); + db.execSQL("INSERT INTO secure(name,value) values('" + + Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED + "','1');"); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + upgradeVersion = 46; + } + + if (upgradeVersion == 46) { + /* + * The password mode constants have changed; reset back to no + * password. + */ + db.beginTransaction(); + try { + db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';"); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + upgradeVersion = 47; + } + + + if (upgradeVersion == 47) { + /* + * The password mode constants have changed again; reset back to no + * password. + */ + db.beginTransaction(); + try { + db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';"); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + upgradeVersion = 48; + } + + if (upgradeVersion == 48) { + /* + * Default recognition service no longer initialized here, + * moved to RecognitionManagerService. + */ + upgradeVersion = 49; + } + + if (upgradeVersion == 49) { + /* + * New settings for new user interface noises. + */ + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT INTO system(name,value)" + + " VALUES(?,?);"); + loadUISoundEffectsSettings(stmt); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + + upgradeVersion = 50; + } + + if (upgradeVersion == 50) { + /* + * Install location no longer initiated here. + */ + upgradeVersion = 51; + } + + if (upgradeVersion == 51) { + /* Move the lockscreen related settings to Secure, including some private ones. */ + String[] settingsToMove = { + Secure.LOCK_PATTERN_ENABLED, + Secure.LOCK_PATTERN_VISIBLE, + Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, + "lockscreen.password_type", + "lockscreen.lockoutattemptdeadline", + "lockscreen.patterneverchosen", + "lock_pattern_autolock", + "lockscreen.lockedoutpermanently", + "lockscreen.password_salt" + }; + moveFromSystemToSecure(db, settingsToMove); + upgradeVersion = 52; + } + + if (upgradeVersion == 52) { + // new vibration/silent mode settings + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT INTO system(name,value)" + + " VALUES(?,?);"); + loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT, + R.bool.def_vibrate_in_silent); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + + upgradeVersion = 53; + } + + if (upgradeVersion == 53) { + /* + * New settings for set install location UI no longer initiated here. + */ + upgradeVersion = 54; + } + + if (upgradeVersion == 54) { + /* + * Update the screen timeout value if set to never + */ + db.beginTransaction(); + try { + upgradeScreenTimeoutFromNever(db); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + upgradeVersion = 55; + } + + if (upgradeVersion == 55) { + /* Move the install location settings. */ + String[] settingsToMove = { + Secure.SET_INSTALL_LOCATION, + Secure.DEFAULT_INSTALL_LOCATION + }; + moveFromSystemToSecure(db, settingsToMove); + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT INTO system(name,value)" + + " VALUES(?,?);"); + loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 0); + loadSetting(stmt, Secure.DEFAULT_INSTALL_LOCATION, + PackageHelper.APP_INSTALL_AUTO); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + upgradeVersion = 56; + } + // *** Remember to update DATABASE_VERSION above! + if (upgradeVersion != currentVersion) { Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion + ", must wipe the settings provider"); @@ -554,6 +711,43 @@ public class DatabaseHelper extends SQLiteOpenHelper { db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2"); db.execSQL("DROP TABLE IF EXISTS favorites"); onCreate(db); + + // Added for diagnosing settings.db wipes after the fact + String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion; + db.execSQL("INSERT INTO secure(name,value) values('" + + "wiped_db_reason" + "','" + wipeReason + "');"); + } + } + + private void moveFromSystemToSecure(SQLiteDatabase db, String [] settingsToMove) { + // Copy settings values from 'system' to 'secure' and delete them from 'system' + SQLiteStatement insertStmt = null; + SQLiteStatement deleteStmt = null; + + db.beginTransaction(); + try { + insertStmt = + db.compileStatement("INSERT INTO secure (name,value) SELECT name,value FROM " + + "system WHERE name=?"); + deleteStmt = db.compileStatement("DELETE FROM system WHERE name=?"); + + + for (String setting : settingsToMove) { + insertStmt.bindString(1, setting); + insertStmt.execute(); + + deleteStmt.bindString(1, setting); + deleteStmt.execute(); + } + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (insertStmt != null) { + insertStmt.close(); + } + if (deleteStmt != null) { + deleteStmt.close(); + } } } @@ -566,7 +760,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { if (!TextUtils.isEmpty(lockPattern)) { // Convert lock pattern try { - LockPatternUtils lpu = new LockPatternUtils(mContext.getContentResolver()); + LockPatternUtils lpu = new LockPatternUtils(mContext); List<LockPatternView.Cell> cellPattern = LockPatternUtils.stringToPattern(lockPattern); lpu.saveLockPattern(cellPattern); @@ -581,44 +775,57 @@ public class DatabaseHelper extends SQLiteOpenHelper { } } + private void upgradeScreenTimeoutFromNever(SQLiteDatabase db) { + // See if the timeout is -1 (for "Never"). + Cursor c = db.query("system", new String[] { "_id", "value" }, "name=? AND value=?", + new String[] { Settings.System.SCREEN_OFF_TIMEOUT, "-1" }, + null, null, null); + + SQLiteStatement stmt = null; + if (c.getCount() > 0) { + c.close(); + try { + stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)" + + " VALUES(?,?);"); + + // Set the timeout to 30 minutes in milliseconds + loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, + Integer.toString(30 * 60 * 1000)); + } finally { + if (stmt != null) stmt.close(); + } + } else { + c.close(); + } + } + /** * Loads the default set of bookmarked shortcuts from an xml file. * * @param db The database to write the values into * @param startingIndex The zero-based position at which bookmarks in this file should begin - * @param subPath The relative path from ANDROID_ROOT to the file to read - * @param quiet If true, do no complain if the file is missing */ - private int loadBookmarks(SQLiteDatabase db, int startingIndex, String subPath, - boolean quiet) { - FileReader bookmarksReader; - - // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system". - final File favFile = new File(Environment.getRootDirectory(), subPath); - try { - bookmarksReader = new FileReader(favFile); - } catch (FileNotFoundException e) { - if (!quiet) { - Log.e(TAG, "Couldn't find or open bookmarks file " + favFile); - } - return 0; - } - + private int loadBookmarks(SQLiteDatabase db, int startingIndex) { Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); ContentValues values = new ContentValues(); PackageManager packageManager = mContext.getPackageManager(); - ActivityInfo info; int i = startingIndex; - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(bookmarksReader); + try { + XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks); XmlUtils.beginDocument(parser, "bookmarks"); - while (true) { - XmlUtils.nextElement(parser); + final int depth = parser.getDepth(); + int type; + + while (((type = parser.next()) != XmlPullParser.END_TAG || + parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } String name = parser.getName(); if (!"bookmark".equals(name)) { @@ -628,23 +835,36 @@ public class DatabaseHelper extends SQLiteOpenHelper { String pkg = parser.getAttributeValue(null, "package"); String cls = parser.getAttributeValue(null, "class"); String shortcutStr = parser.getAttributeValue(null, "shortcut"); + int shortcutValue = (int) shortcutStr.charAt(0); if (TextUtils.isEmpty(shortcutStr)) { Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls); } + + ActivityInfo info = null; + ComponentName cn = new ComponentName(pkg, cls); try { - ComponentName cn = new ComponentName(pkg, cls); info = packageManager.getActivityInfo(cn, 0); + } catch (PackageManager.NameNotFoundException e) { + String[] packages = packageManager.canonicalToCurrentPackageNames( + new String[] { pkg }); + cn = new ComponentName(packages[0], cls); + try { + info = packageManager.getActivityInfo(cn, 0); + } catch (PackageManager.NameNotFoundException e1) { + Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e); + } + } + + if (info != null) { intent.setComponent(cn); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - values.put(Settings.Bookmarks.INTENT, intent.toURI()); + values.put(Settings.Bookmarks.INTENT, intent.toUri(0)); values.put(Settings.Bookmarks.TITLE, info.loadLabel(packageManager).toString()); values.put(Settings.Bookmarks.SHORTCUT, shortcutValue); db.insert("bookmarks", null, values); i++; - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e); } } } catch (XmlPullParserException e) { @@ -662,7 +882,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { * @param db The database to write the values into */ private void loadBookmarks(SQLiteDatabase db) { - loadBookmarks(db, 0, DEFAULT_BOOKMARKS_PATH, false); + loadBookmarks(db, 0); } /** @@ -672,42 +892,50 @@ public class DatabaseHelper extends SQLiteOpenHelper { * @param db the database to insert the volume levels into */ private void loadVolumeLevels(SQLiteDatabase db) { - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" - + " VALUES(?,?);"); - - loadSetting(stmt, Settings.System.VOLUME_MUSIC, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]); - loadSetting(stmt, Settings.System.VOLUME_RING, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]); - loadSetting(stmt, Settings.System.VOLUME_SYSTEM, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]); - loadSetting( - stmt, - Settings.System.VOLUME_VOICE, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]); - loadSetting(stmt, Settings.System.VOLUME_ALARM, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]); - loadSetting( - stmt, - Settings.System.VOLUME_NOTIFICATION, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]); - loadSetting(stmt, Settings.System.MODE_RINGER, - AudioManager.RINGER_MODE_NORMAL); - - loadVibrateSetting(db, false); - - // By default, only the ring/notification and system streams are affected - loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED, - (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) | - (1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)); - - loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED, - ((1 << AudioManager.STREAM_MUSIC) | - (1 << AudioManager.STREAM_RING) | - (1 << AudioManager.STREAM_NOTIFICATION) | - (1 << AudioManager.STREAM_SYSTEM))); - - stmt.close(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + + " VALUES(?,?);"); + + loadSetting(stmt, Settings.System.VOLUME_MUSIC, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]); + loadSetting(stmt, Settings.System.VOLUME_RING, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]); + loadSetting(stmt, Settings.System.VOLUME_SYSTEM, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]); + loadSetting( + stmt, + Settings.System.VOLUME_VOICE, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]); + loadSetting(stmt, Settings.System.VOLUME_ALARM, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]); + loadSetting( + stmt, + Settings.System.VOLUME_NOTIFICATION, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]); + loadSetting( + stmt, + Settings.System.VOLUME_BLUETOOTH_SCO, + AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); + + loadSetting(stmt, Settings.System.MODE_RINGER, + AudioManager.RINGER_MODE_NORMAL); + + loadVibrateSetting(db, false); + + // By default, only the ring/notification and system streams are affected + loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED, + (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) | + (1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED)); + + loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED, + ((1 << AudioManager.STREAM_MUSIC) | + (1 << AudioManager.STREAM_RING) | + (1 << AudioManager.STREAM_NOTIFICATION) | + (1 << AudioManager.STREAM_SYSTEM))); + } finally { + if (stmt != null) stmt.close(); + } } private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) { @@ -715,16 +943,21 @@ public class DatabaseHelper extends SQLiteOpenHelper { db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'"); } - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" - + " VALUES(?,?);"); - - // Vibrate off by default for ringer, on for notification - int vibrate = 0; - vibrate = AudioService.getValueForVibrateSetting(vibrate, - AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON); - vibrate = AudioService.getValueForVibrateSetting(vibrate, - AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF); - loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + + " VALUES(?,?);"); + + // Vibrate off by default for ringer, on for notification + int vibrate = 0; + vibrate = AudioService.getValueForVibrateSetting(vibrate, + AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON); + vibrate = AudioService.getValueForVibrateSetting(vibrate, + AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF); + loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate); + } finally { + if (stmt != null) stmt.close(); + } } private void loadSettings(SQLiteDatabase db) { @@ -733,61 +966,96 @@ public class DatabaseHelper extends SQLiteOpenHelper { } private void loadSystemSettings(SQLiteDatabase db) { - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" - + " VALUES(?,?);"); - - Resources r = mContext.getResources(); - - loadBooleanSetting(stmt, Settings.System.DIM_SCREEN, - R.bool.def_dim_screen); - loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN, - "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0); - loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, - R.integer.def_screen_off_timeout); - - // Set default cdma emergency tone - loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0); - - // Set default cdma call auto retry - loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0); - - // Set default cdma DTMF type - loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0); - - // Set default hearing aid - loadSetting(stmt, Settings.System.HEARING_AID, 0); - - // Set default tty mode - loadSetting(stmt, Settings.System.TTY_MODE, 0); - - loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON, - R.bool.def_airplane_mode_on); - - loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS, - R.string.def_airplane_mode_radios); - - loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, - R.string.airplane_mode_toggleable_radios); - - loadBooleanSetting(stmt, Settings.System.AUTO_TIME, - R.bool.def_auto_time); // Sync time to NITZ - - loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS, - R.integer.def_screen_brightness); - - loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE, - R.bool.def_screen_brightness_automatic_mode); - - loadDefaultAnimationSettings(stmt); - - loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION, - R.bool.def_accelerometer_rotation); - - loadDefaultHapticSettings(stmt); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + + " VALUES(?,?);"); + + loadBooleanSetting(stmt, Settings.System.DIM_SCREEN, + R.bool.def_dim_screen); + loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN, + "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0); + loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, + R.integer.def_screen_off_timeout); + + // Set default cdma emergency tone + loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0); + + // Set default cdma call auto retry + loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0); + + // Set default cdma DTMF type + loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0); + + // Set default hearing aid + loadSetting(stmt, Settings.System.HEARING_AID, 0); + + // Set default tty mode + loadSetting(stmt, Settings.System.TTY_MODE, 0); + + loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON, + R.bool.def_airplane_mode_on); + + loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS, + R.string.def_airplane_mode_radios); + + loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, + R.string.airplane_mode_toggleable_radios); + + loadBooleanSetting(stmt, Settings.System.AUTO_TIME, + R.bool.def_auto_time); // Sync time to NITZ + + loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS, + R.integer.def_screen_brightness); + + loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE, + R.bool.def_screen_brightness_automatic_mode); + + loadDefaultAnimationSettings(stmt); + + loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION, + R.bool.def_accelerometer_rotation); + + loadDefaultHapticSettings(stmt); + + loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE, + R.bool.def_notification_pulse); + loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0); + loadSetting(stmt, Settings.Secure.DEFAULT_INSTALL_LOCATION, + PackageHelper.APP_INSTALL_AUTO); + + loadUISoundEffectsSettings(stmt); + + loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT, + R.bool.def_vibrate_in_silent); + } finally { + if (stmt != null) stmt.close(); + } + } - loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE, - R.bool.def_notification_pulse); - stmt.close(); + private void loadUISoundEffectsSettings(SQLiteStatement stmt) { + loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED, + R.integer.def_power_sounds_enabled); + loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND, + R.string.def_low_battery_sound); + + loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED, + R.integer.def_dock_sounds_enabled); + loadStringSetting(stmt, Settings.System.DESK_DOCK_SOUND, + R.string.def_desk_dock_sound); + loadStringSetting(stmt, Settings.System.DESK_UNDOCK_SOUND, + R.string.def_desk_undock_sound); + loadStringSetting(stmt, Settings.System.CAR_DOCK_SOUND, + R.string.def_car_dock_sound); + loadStringSetting(stmt, Settings.System.CAR_UNDOCK_SOUND, + R.string.def_car_undock_sound); + + loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, + R.integer.def_lockscreen_sounds_enabled); + loadStringSetting(stmt, Settings.System.LOCK_SOUND, + R.string.def_lock_sound); + loadStringSetting(stmt, Settings.System.UNLOCK_SOUND, + R.string.def_unlock_sound); } private void loadDefaultAnimationSettings(SQLiteStatement stmt) { @@ -803,77 +1071,92 @@ public class DatabaseHelper extends SQLiteOpenHelper { } private void loadSecureSettings(SQLiteDatabase db) { - SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" - + " VALUES(?,?);"); - - loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON, - R.bool.def_bluetooth_on); - - // Data roaming default, based on build - loadSetting(stmt, Settings.Secure.DATA_ROAMING, - "true".equalsIgnoreCase( - SystemProperties.get("ro.com.android.dataroaming", - "false")) ? 1 : 0); - - loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS, - R.bool.def_install_non_market_apps); - - loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, - R.string.def_location_providers_allowed); - - loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED, - R.bool.assisted_gps_enabled); - - loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE, - R.integer.def_network_preference); - - loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED, - R.bool.def_usb_mass_storage_enabled); - - loadBooleanSetting(stmt, Settings.Secure.WIFI_ON, - R.bool.def_wifi_on); - loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, - R.bool.def_networks_available_notification_on); - - String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist"); - if (!TextUtils.isEmpty(wifiWatchList)) { - loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" + + " VALUES(?,?);"); + + loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON, + R.bool.def_bluetooth_on); + + // Data roaming default, based on build + loadSetting(stmt, Settings.Secure.DATA_ROAMING, + "true".equalsIgnoreCase( + SystemProperties.get("ro.com.android.dataroaming", + "false")) ? 1 : 0); + + loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS, + R.bool.def_install_non_market_apps); + + loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, + R.string.def_location_providers_allowed); + + loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED, + R.bool.assisted_gps_enabled); + + loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE, + R.integer.def_network_preference); + + loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED, + R.bool.def_usb_mass_storage_enabled); + + loadBooleanSetting(stmt, Settings.Secure.WIFI_ON, + R.bool.def_wifi_on); + loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, + R.bool.def_networks_available_notification_on); + + String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist"); + if (!TextUtils.isEmpty(wifiWatchList)) { + loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList); + } + + // Set the preferred network mode to 0 = Global, CDMA default + int type = SystemProperties.getInt("ro.telephony.default_network", + RILConstants.PREFERRED_NETWORK_MODE); + loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type); + + // Enable or disable Cell Broadcast SMS + loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS, + RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED); + + // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available + loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION, + RILConstants.PREFERRED_CDMA_SUBSCRIPTION); + + // Don't do this. The SystemServer will initialize ADB_ENABLED from a + // persistent system property instead. + //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0); + + // Allow mock locations default, based on build + loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION, + "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0); + + loadSecure35Settings(stmt); + + loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND, + R.bool.def_mount_play_notification_snd); + + loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART, + R.bool.def_mount_ums_autostart); + + loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT, + R.bool.def_mount_ums_prompt); + + loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED, + R.bool.def_mount_ums_notify_enabled); + } finally { + if (stmt != null) stmt.close(); } - - // Set the preferred network mode to 0 = Global, CDMA default - int type = SystemProperties.getInt("ro.telephony.default_network", - RILConstants.PREFERRED_NETWORK_MODE); - loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type); - - // Enable or disable Cell Broadcast SMS - loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS, - RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED); - - // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available - loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION, - RILConstants.PREFERRED_CDMA_SUBSCRIPTION); - - // Don't do this. The SystemServer will initialize ADB_ENABLED from a - // persistent system property instead. - //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0); - - // Allow mock locations default, based on build - loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION, - "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0); - - loadSecure35Settings(stmt); - - stmt.close(); } private void loadSecure35Settings(SQLiteStatement stmt) { loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED, R.bool.def_backup_enabled); - + loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT, R.string.def_backup_transport); } - + private void loadSetting(SQLiteStatement stmt, String key, Object value) { stmt.bindString(1, key); stmt.bindString(2, value.toString()); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 2738efb..b98071e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -30,9 +30,9 @@ import java.io.IOException; import java.util.Arrays; import java.util.zip.CRC32; -import android.backup.BackupDataInput; -import android.backup.BackupDataOutput; -import android.backup.BackupHelperAgent; +import android.app.backup.BackupDataInput; +import android.app.backup.BackupDataOutput; +import android.app.backup.BackupAgentHelper; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -49,7 +49,7 @@ import android.util.Log; * Performs backup and restore of the System and Secure settings. * List of settings that are backed up are stored in the Settings.java file */ -public class SettingsBackupAgent extends BackupHelperAgent { +public class SettingsBackupAgent extends BackupAgentHelper { private static final boolean DEBUG = false; private static final String KEY_SYSTEM = "system"; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 153a5ea..0e75fbc 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -20,7 +20,8 @@ import java.util.Locale; import android.app.ActivityManagerNative; import android.app.IActivityManager; -import android.backup.BackupDataInput; +import android.app.backup.BackupDataInput; +import android.app.backup.IBackupManager; import android.content.ContentResolver; import android.content.Context; import android.content.IContentService; @@ -41,7 +42,6 @@ public class SettingsHelper { private AudioManager mAudioManager; private IContentService mContentService; private IPowerManager mPowerManager; - private static final String[] PROVIDERS = { "gmail-ls", "calendar", "contacts" }; private boolean mSilent; private boolean mVibrate; @@ -72,10 +72,22 @@ public class SettingsHelper { } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) { setGpsLocation(value); return false; + } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) { + setAutoRestore(Integer.parseInt(value) == 1); } return true; } + private void setAutoRestore(boolean enabled) { + try { + IBackupManager bm = IBackupManager.Stub.asInterface( + ServiceManager.getService(Context.BACKUP_SERVICE)); + if (bm != null) { + bm.setAutoRestore(enabled); + } + } catch (RemoteException e) {} + } + private void setGpsLocation(String value) { final String GPS = LocationManager.GPS_PROVIDER; boolean enabled = diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ab186cf..1019fa8 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -17,8 +17,13 @@ package com.android.providers.settings; import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.LinkedHashMap; +import java.util.Map; -import android.backup.BackupManager; +import android.app.backup.BackupManager; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; @@ -27,12 +32,12 @@ import android.content.pm.PackageManager; import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteQueryBuilder; -import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; +import android.os.Bundle; import android.os.ParcelFileDescriptor; -import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.DrmStore; import android.provider.MediaStore; @@ -47,6 +52,21 @@ public class SettingsProvider extends ContentProvider { private static final String TABLE_FAVORITES = "favorites"; private static final String TABLE_OLD_FAVORITES = "old_favorites"; + private static final String[] COLUMN_VALUE = new String[] { "value" }; + + // Cache for settings, access-ordered for acting as LRU. + // Guarded by themselves. + private static final int MAX_CACHE_ENTRIES = 50; + private static final SettingsCache sSystemCache = new SettingsCache(); + private static final SettingsCache sSecureCache = new SettingsCache(); + + // Over this size we don't reject loading or saving settings but + // we do consider them broken/malicious and don't keep them in + // memory at least: + private static final int MAX_CACHE_ENTRY_SIZE = 500; + + private static final Bundle NULL_SETTING = Bundle.forPair("value", null); + protected DatabaseHelper mOpenHelper; private BackupManager mBackupManager; @@ -71,8 +91,7 @@ public class SettingsProvider extends ContentProvider { throw new UnsupportedOperationException("WHERE clause not supported: " + url); } else { this.table = url.getPathSegments().get(0); - if ("gservices".equals(this.table) || "system".equals(this.table) - || "secure".equals(this.table)) { + if ("system".equals(this.table) || "secure".equals(this.table)) { this.where = Settings.NameValueTable.NAME + "=?"; this.args = new String[] { url.getPathSegments().get(1) }; } else { @@ -106,8 +125,7 @@ public class SettingsProvider extends ContentProvider { throw new IllegalArgumentException("Invalid URI: " + tableUri); } String table = tableUri.getPathSegments().get(0); - if ("gservices".equals(table) || "system".equals(table) - || "secure".equals(table)) { + if ("system".equals(table) || "secure".equals(table)) { String name = values.getAsString(Settings.NameValueTable.NAME); return Uri.withAppendedPath(tableUri, name); } else { @@ -135,8 +153,6 @@ public class SettingsProvider extends ContentProvider { } else if (table.equals("secure")) { property = Settings.Secure.SYS_PROP_SETTING_VERSION; backedUpDataChanged = true; - } else if (table.equals("gservices")) { - property = Settings.Gservices.SYS_PROP_SETTING_VERSION; } if (property != null) { @@ -167,21 +183,12 @@ public class SettingsProvider extends ContentProvider { */ private void checkWritePermissions(SqlArguments args) { if ("secure".equals(args.table) && - getContext().checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_SECURE_SETTINGS) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - String.format("Permission denial: writing to secure settings requires %1$s", - android.Manifest.permission.WRITE_SECURE_SETTINGS)); - - // TODO: Move gservices into its own provider so we don't need this nonsense. - } else if ("gservices".equals(args.table) && getContext().checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_GSERVICES) != - PackageManager.PERMISSION_GRANTED) { + android.Manifest.permission.WRITE_SECURE_SETTINGS) != + PackageManager.PERMISSION_GRANTED) { throw new SecurityException( - String.format("Permission denial: writing to gservices settings requires %1$s", - android.Manifest.permission.WRITE_GSERVICES)); + String.format("Permission denial: writing to secure settings requires %1$s", + android.Manifest.permission.WRITE_SECURE_SETTINGS)); } } @@ -189,9 +196,91 @@ public class SettingsProvider extends ContentProvider { public boolean onCreate() { mOpenHelper = new DatabaseHelper(getContext()); mBackupManager = new BackupManager(getContext()); + + if (!ensureAndroidIdIsSet()) { + return false; + } + return true; } + private boolean ensureAndroidIdIsSet() { + final Cursor c = query(Settings.Secure.CONTENT_URI, + new String[] { Settings.NameValueTable.VALUE }, + Settings.NameValueTable.NAME + "=?", + new String[] { Settings.Secure.ANDROID_ID }, null); + try { + final String value = c.moveToNext() ? c.getString(0) : null; + if (value == null) { + final SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + String serial = SystemProperties.get("ro.serialno"); + if (serial != null) { + try { + random.setSeed(serial.getBytes("UTF-8")); + } catch (UnsupportedEncodingException ignore) { + // stick with default seed + } + } + final String newAndroidIdValue = Long.toHexString(random.nextLong()); + Log.d(TAG, "Generated and saved new ANDROID_ID"); + final ContentValues values = new ContentValues(); + values.put(Settings.NameValueTable.NAME, Settings.Secure.ANDROID_ID); + values.put(Settings.NameValueTable.VALUE, newAndroidIdValue); + final Uri uri = insert(Settings.Secure.CONTENT_URI, values); + if (uri == null) { + return false; + } + } + return true; + } catch (NoSuchAlgorithmException e) { + return false; + } finally { + c.close(); + } + } + + /** + * Fast path that avoids the use of chatty remoted Cursors. + */ + @Override + public Bundle call(String method, String request, Bundle args) { + if (Settings.CALL_METHOD_GET_SYSTEM.equals(method)) { + return lookupValue("system", sSystemCache, request); + } + if (Settings.CALL_METHOD_GET_SECURE.equals(method)) { + return lookupValue("secure", sSecureCache, request); + } + return null; + } + + // Looks up value 'key' in 'table' and returns either a single-pair Bundle, + // possibly with a null value, or null on failure. + private Bundle lookupValue(String table, SettingsCache cache, String key) { + synchronized (cache) { + if (cache.containsKey(key)) { + return cache.get(key); + } + } + + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + Cursor cursor = null; + try { + cursor = db.query(table, COLUMN_VALUE, "name=?", new String[]{key}, + null, null, null, null); + if (cursor != null && cursor.getCount() == 1) { + cursor.moveToFirst(); + return cache.putIfAbsent(key, cursor.getString(0)); + } + } catch (SQLiteException e) { + Log.w(TAG, "settings lookup error", e); + return null; + } finally { + if (cursor != null) cursor.close(); + } + cache.putIfAbsent(key, null); + return NULL_SETTING; + } + @Override public Cursor query(Uri url, String[] select, String where, String[] whereArgs, String sort) { SqlArguments args = new SqlArguments(url, where, whereArgs); @@ -243,6 +332,7 @@ public class SettingsProvider extends ContentProvider { return 0; } checkWritePermissions(args); + SettingsCache cache = SettingsCache.forTable(args.table); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); @@ -250,6 +340,7 @@ public class SettingsProvider extends ContentProvider { int numValues = values.length; for (int i = 0; i < numValues; i++) { if (db.insert(args.table, null, values[i]) < 0) return 0; + SettingsCache.populate(cache, values[i]); if (LOCAL_LOGV) Log.v(TAG, args.table + " <- " + values[i]); } db.setTransactionSuccessful(); @@ -266,6 +357,9 @@ public class SettingsProvider extends ContentProvider { * This setting contains a list of the currently enabled location providers. * But helper functions in android.providers.Settings can enable or disable * a single provider by using a "+" or "-" prefix before the provider name. + * + * @returns whether the database needs to be updated or not, also modifying + * 'initialValues' if needed. */ private boolean parseProviderList(Uri url, ContentValues initialValues) { String value = initialValues.getAsString(Settings.Secure.VALUE); @@ -326,7 +420,7 @@ public class SettingsProvider extends ContentProvider { } } } - + return true; } @@ -345,10 +439,18 @@ public class SettingsProvider extends ContentProvider { if (!parseProviderList(url, initialValues)) return null; } + SettingsCache cache = SettingsCache.forTable(args.table); + String value = initialValues.getAsString(Settings.NameValueTable.VALUE); + if (SettingsCache.isRedundantSetValue(cache, name, value)) { + return Uri.withAppendedPath(url, name); + } + SQLiteDatabase db = mOpenHelper.getWritableDatabase(); final long rowId = db.insert(args.table, null, initialValues); if (rowId <= 0) return null; + SettingsCache.populate(cache, initialValues); // before we notify + if (LOCAL_LOGV) Log.v(TAG, args.table + " <- " + initialValues); url = getUriFor(url, initialValues, rowId); sendNotify(url); @@ -367,7 +469,10 @@ public class SettingsProvider extends ContentProvider { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count = db.delete(args.table, args.where, args.args); - if (count > 0) sendNotify(url); + if (count > 0) { + SettingsCache.wipe(args.table); // before we notify + sendNotify(url); + } if (LOCAL_LOGV) Log.v(TAG, args.table + ": " + count + " row(s) deleted"); return count; } @@ -382,7 +487,10 @@ public class SettingsProvider extends ContentProvider { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count = db.update(args.table, initialValues, args.where, args.args); - if (count > 0) sendNotify(url); + if (count > 0) { + SettingsCache.wipe(args.table); // before we notify + sendNotify(url); + } if (LOCAL_LOGV) Log.v(TAG, args.table + ": " + count + " row(s) <- " + initialValues); return count; } @@ -487,4 +595,103 @@ public class SettingsProvider extends ContentProvider { // Note that this will end up calling openFile() above. return super.openAssetFile(uri, mode); } + + /** + * In-memory LRU Cache of system and secure settings, along with + * associated helper functions to keep cache coherent with the + * database. + */ + private static final class SettingsCache extends LinkedHashMap<String, Bundle> { + + public SettingsCache() { + super(MAX_CACHE_ENTRIES, 0.75f /* load factor */, true /* access ordered */); + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > MAX_CACHE_ENTRIES; + } + + /** + * Atomic cache population, conditional on size of value and if + * we lost a race. + * + * @returns a Bundle to send back to the client from call(), even + * if we lost the race. + */ + public Bundle putIfAbsent(String key, String value) { + Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value); + if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) { + synchronized (this) { + if (!containsKey(key)) { + put(key, bundle); + } + } + } + return bundle; + } + + public static SettingsCache forTable(String tableName) { + if ("system".equals(tableName)) { + return SettingsProvider.sSystemCache; + } + if ("secure".equals(tableName)) { + return SettingsProvider.sSecureCache; + } + return null; + } + + /** + * Populates a key in a given (possibly-null) cache. + */ + public static void populate(SettingsCache cache, ContentValues contentValues) { + if (cache == null) { + return; + } + String name = contentValues.getAsString(Settings.NameValueTable.NAME); + if (name == null) { + Log.w(TAG, "null name populating settings cache."); + return; + } + String value = contentValues.getAsString(Settings.NameValueTable.VALUE); + synchronized (cache) { + if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) { + cache.put(name, Bundle.forPair(Settings.NameValueTable.VALUE, value)); + } else { + cache.remove(name); + } + } + } + + /** + * Used for wiping a whole cache on deletes when we're not + * sure what exactly was deleted or changed. + */ + public static void wipe(String tableName) { + SettingsCache cache = SettingsCache.forTable(tableName); + if (cache == null) { + return; + } + synchronized (cache) { + cache.clear(); + } + } + + /** + * For suppressing duplicate/redundant settings inserts early, + * checking our cache first (but without faulting it in), + * before going to sqlite with the mutation. + */ + public static boolean isRedundantSetValue(SettingsCache cache, String name, String value) { + if (cache == null) return false; + synchronized (cache) { + Bundle bundle = cache.get(name); + if (bundle == null) return false; + String oldValue = bundle.getPairValue(); + if (oldValue == null && value == null) return true; + if ((oldValue == null) != (value == null)) return false; + return oldValue.equals(value); + } + } + } } diff --git a/packages/TtsService/Android.mk b/packages/TtsService/Android.mk index 2737fb4..75b26a2 100644 --- a/packages/TtsService/Android.mk +++ b/packages/TtsService/Android.mk @@ -1,13 +1,15 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := user +LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) \ LOCAL_PACKAGE_NAME := TtsService LOCAL_CERTIFICATE := platform +LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags + include $(BUILD_PACKAGE) include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp index 0ec8dab..1d69361 100644 --- a/packages/TtsService/jni/android_tts_SynthProxy.cpp +++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_NDEBUG 0 #include <stdio.h> #include <unistd.h> @@ -42,12 +41,13 @@ #define FILTER_TRANSITION_FREQ 1100.0f // in Hz #define FILTER_SHELF_SLOPE 1.0f // Q #define FILTER_GAIN 5.5f // linear gain -// such a huge gain is justified by how much energy in the low frequencies is "wasted" at the output -// of the synthesis. The low shelving filter removes it, leaving room for amplification. #define USAGEMODE_PLAY_IMMEDIATELY 0 #define USAGEMODE_WRITE_TO_FILE 1 +#define SYNTHPLAYSTATE_IS_STOPPED 0 +#define SYNTHPLAYSTATE_IS_PLAYING 1 + using namespace android; // ---------------------------------------------------------------------------- @@ -81,13 +81,19 @@ double out0;// y[n] double out1;// y[n-1] double out2;// y[n-2] +static float fFilterLowshelfAttenuation = FILTER_LOWSHELF_ATTENUATION; +static float fFilterTransitionFreq = FILTER_TRANSITION_FREQ; +static float fFilterShelfSlope = FILTER_SHELF_SLOPE; +static float fFilterGain = FILTER_GAIN; +static bool bUseFilter = false; + void initializeEQ() { - amp = float(pow(10.0, FILTER_LOWSHELF_ATTENUATION / 40.0)); - w = 2.0 * M_PI * (FILTER_TRANSITION_FREQ / DEFAULT_TTS_RATE); + amp = float(pow(10.0, fFilterLowshelfAttenuation / 40.0)); + w = 2.0 * M_PI * (fFilterTransitionFreq / DEFAULT_TTS_RATE); sinw = float(sin(w)); cosw = float(cos(w)); - beta = float(sqrt(amp)/FILTER_SHELF_SLOPE); + beta = float(sqrt(amp)/fFilterShelfSlope); // initialize low-shelf parameters b0 = amp * ((amp+1.0F) - ((amp-1.0F)*cosw) + (beta*sinw)); @@ -97,9 +103,9 @@ void initializeEQ() { a1 = 2.0F * ((amp-1.0F) + ((amp+1.0F)*cosw)); a2 = -((amp+1.0F) + ((amp-1.0F)*cosw) - (beta*sinw)); - m_fa = FILTER_GAIN * b0/a0; - m_fb = FILTER_GAIN * b1/a0; - m_fc = FILTER_GAIN * b2/a0; + m_fa = fFilterGain * b0/a0; + m_fb = fFilterGain * b1/a0; + m_fc = fFilterGain * b2/a0; m_fd = a1/a0; m_fe = a2/a0; } @@ -151,6 +157,8 @@ class SynthProxyJniStorage { TtsEngine* mNativeSynthInterface; void* mEngineLibHandle; AudioTrack* mAudioOut; + int8_t mPlayState; + Mutex mPlayLock; AudioSystem::stream_type mStreamType; uint32_t mSampleRate; uint32_t mAudFormat; @@ -163,6 +171,7 @@ class SynthProxyJniStorage { mNativeSynthInterface = NULL; mEngineLibHandle = NULL; mAudioOut = NULL; + mPlayState = SYNTHPLAYSTATE_IS_STOPPED; mStreamType = DEFAULT_TTS_STREAM_TYPE; mSampleRate = DEFAULT_TTS_RATE; mAudFormat = DEFAULT_TTS_FORMAT; @@ -220,6 +229,7 @@ class SynthProxyJniStorage { if (minBufCount < 2) minBufCount = 2; int minFrameCount = (afFrameCount * rate * minBufCount)/afSampleRate; + mPlayLock.lock(); mAudioOut = new AudioTrack(mStreamType, rate, format, (channel == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, minFrameCount > 4096 ? minFrameCount : 4096, @@ -231,10 +241,10 @@ class SynthProxyJniStorage { mAudioOut = NULL; } else { //LOGI("AudioTrack OK"); - mAudioOut->setVolume(2.0f, 2.0f); - mAudioOut->start(); - LOGV("AudioTrack started"); + mAudioOut->setVolume(1.0f, 1.0f); + LOGV("AudioTrack ready"); } + mPlayLock.unlock(); } }; @@ -286,7 +296,15 @@ static tts_callback_status ttsSynthDoneCB(void *& userdata, uint32_t rate, if (bufferSize > 0) { prepAudioTrack(pJniData, pForAfter->streamType, rate, (AudioSystem::audio_format)format, channel); if (pJniData->mAudioOut) { - applyFilter((int16_t*)wav, bufferSize/2); + pJniData->mPlayLock.lock(); + if(pJniData->mAudioOut->stopped() + && (pJniData->mPlayState == SYNTHPLAYSTATE_IS_PLAYING)) { + pJniData->mAudioOut->start(); + } + pJniData->mPlayLock.unlock(); + if (bUseFilter) { + applyFilter((int16_t*)wav, bufferSize/2); + } pJniData->mAudioOut->write(wav, bufferSize); memset(wav, 0, bufferSize); //LOGV("AudioTrack wrote: %d bytes", bufferSize); @@ -302,7 +320,9 @@ static tts_callback_status ttsSynthDoneCB(void *& userdata, uint32_t rate, return TTS_CALLBACK_HALT; } if (bufferSize > 0){ - applyFilter((int16_t*)wav, bufferSize/2); + if (bUseFilter) { + applyFilter((int16_t*)wav, bufferSize/2); + } fwrite(wav, 1, bufferSize, pForAfter->outputFile); memset(wav, 0, bufferSize); } @@ -336,23 +356,51 @@ static tts_callback_status ttsSynthDoneCB(void *& userdata, uint32_t rate, // ---------------------------------------------------------------------------- -static void +static int +android_tts_SynthProxy_setLowShelf(JNIEnv *env, jobject thiz, jboolean applyFilter, + jfloat filterGain, jfloat attenuationInDb, jfloat freqInHz, jfloat slope) +{ + int result = TTS_SUCCESS; + + bUseFilter = applyFilter; + if (applyFilter) { + fFilterLowshelfAttenuation = attenuationInDb; + fFilterTransitionFreq = freqInHz; + fFilterShelfSlope = slope; + fFilterGain = filterGain; + + if (fFilterShelfSlope != 0.0f) { + initializeEQ(); + } else { + LOGE("Invalid slope, can't be null"); + result = TTS_FAILURE; + } + } + + return result; +} + +// ---------------------------------------------------------------------------- +static int android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz, - jobject weak_this, jstring nativeSoLib) + jobject weak_this, jstring nativeSoLib, jstring engConfig) { + int result = TTS_FAILURE; + + bUseFilter = false; + SynthProxyJniStorage* pJniStorage = new SynthProxyJniStorage(); prepAudioTrack(pJniStorage, DEFAULT_TTS_STREAM_TYPE, DEFAULT_TTS_RATE, DEFAULT_TTS_FORMAT, DEFAULT_TTS_NB_CHANNELS); - const char *nativeSoLibNativeString = - env->GetStringUTFChars(nativeSoLib, 0); + const char *nativeSoLibNativeString = env->GetStringUTFChars(nativeSoLib, 0); + const char *engConfigString = env->GetStringUTFChars(engConfig, 0); void *engine_lib_handle = dlopen(nativeSoLibNativeString, RTLD_NOW | RTLD_LOCAL); if (engine_lib_handle == NULL) { LOGE("android_tts_SynthProxy_native_setup(): engine_lib_handle == NULL"); - // TODO report error so the TTS can't be used } else { TtsEngine *(*get_TtsEngine)() = reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine")); @@ -362,20 +410,22 @@ android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz, if (pJniStorage->mNativeSynthInterface) { Mutex::Autolock l(engineMutex); - pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB); + pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB, engConfigString); } + + result = TTS_SUCCESS; } // we use a weak reference so the SynthProxy object can be garbage collected. pJniStorage->tts_ref = env->NewGlobalRef(weak_this); // save the JNI resources so we can use them (and free them) later - env->SetIntField(thiz, javaTTSFields.synthProxyFieldJniData, - (int)pJniStorage); - - initializeEQ(); + env->SetIntField(thiz, javaTTSFields.synthProxyFieldJniData, (int)pJniStorage); env->ReleaseStringUTFChars(nativeSoLib, nativeSoLibNativeString); + env->ReleaseStringUTFChars(engConfig, engConfigString); + + return result; } @@ -434,6 +484,29 @@ android_tts_SynthProxy_isLanguageAvailable(JNIEnv *env, jobject thiz, jint jniDa return result; } +static int +android_tts_SynthProxy_setConfig(JNIEnv *env, jobject thiz, jint jniData, jstring engineConfig) +{ + int result = TTS_FAILURE; + + if (jniData == 0) { + LOGE("android_tts_SynthProxy_setConfig(): invalid JNI data"); + return result; + } + + Mutex::Autolock l(engineMutex); + + SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; + const char *engineConfigNativeString = env->GetStringUTFChars(engineConfig, 0); + + if (pSynthData->mNativeSynthInterface) { + result = pSynthData->mNativeSynthInterface->setProperty(ANDROID_TTS_ENGINE_PROPERTY_CONFIG, + engineConfigNativeString, strlen(engineConfigNativeString)); + } + env->ReleaseStringUTFChars(engineConfig, engineConfigNativeString); + + return result; +} static int android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData, @@ -503,7 +576,7 @@ android_tts_SynthProxy_setSpeechRate(JNIEnv *env, jobject thiz, jint jniData, return result; } - int bufSize = 10; + int bufSize = 12; char buffer [bufSize]; sprintf(buffer, "%d", speechRate); @@ -533,7 +606,7 @@ android_tts_SynthProxy_setPitch(JNIEnv *env, jobject thiz, jint jniData, Mutex::Autolock l(engineMutex); - int bufSize = 10; + int bufSize = 12; char buffer [bufSize]; sprintf(buffer, "%d", pitch); @@ -677,9 +750,9 @@ android_tts_SynthProxy_speak(JNIEnv *env, jobject thiz, jint jniData, SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; - if (pSynthData->mAudioOut) { - pSynthData->mAudioOut->start(); - } + pSynthData->mPlayLock.lock(); + pSynthData->mPlayState = SYNTHPLAYSTATE_IS_PLAYING; + pSynthData->mPlayLock.unlock(); afterSynthData_t* pForAfter = new (afterSynthData_t); pForAfter->jniStorage = jniData; @@ -710,9 +783,13 @@ android_tts_SynthProxy_stop(JNIEnv *env, jobject thiz, jint jniData) SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; + pSynthData->mPlayLock.lock(); + pSynthData->mPlayState = SYNTHPLAYSTATE_IS_STOPPED; if (pSynthData->mAudioOut) { pSynthData->mAudioOut->stop(); } + pSynthData->mPlayLock.unlock(); + if (pSynthData->mNativeSynthInterface) { result = pSynthData->mNativeSynthInterface->stop(); } @@ -815,6 +892,10 @@ static JNINativeMethod gMethods[] = { "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*)android_tts_SynthProxy_isLanguageAvailable }, + { "native_setConfig", + "(ILjava/lang/String;)I", + (void*)android_tts_SynthProxy_setConfig + }, { "native_setLanguage", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*)android_tts_SynthProxy_setLanguage @@ -844,9 +925,13 @@ static JNINativeMethod gMethods[] = { (void*)android_tts_SynthProxy_shutdown }, { "native_setup", - "(Ljava/lang/Object;Ljava/lang/String;)V", + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)I", (void*)android_tts_SynthProxy_native_setup }, + { "native_setLowShelf", + "(ZFFFF)I", + (void*)android_tts_SynthProxy_setLowShelf + }, { "native_finalize", "(I)V", (void*)android_tts_SynthProxy_native_finalize diff --git a/packages/TtsService/proguard.flags b/packages/TtsService/proguard.flags new file mode 100644 index 0000000..e8bee6b --- /dev/null +++ b/packages/TtsService/proguard.flags @@ -0,0 +1,5 @@ +-keep class android.tts.SynthProxy { + int mJniData; + # keep all declarations for native methods + <methods>; +} diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java index 1d37ba0..525a504 100755 --- a/packages/TtsService/src/android/tts/SynthProxy.java +++ b/packages/TtsService/src/android/tts/SynthProxy.java @@ -32,6 +32,15 @@ import java.lang.ref.WeakReference; @SuppressWarnings("unused") public class SynthProxy { + // Default parameters of a filter to be applied when using the Pico engine. + // Such a huge filter gain is justified by how much energy in the low frequencies is "wasted" at + // the output of the synthesis. The low shelving filter removes it, leaving room for + // amplification. + private final static float PICO_FILTER_GAIN = 5.0f; // linear gain + private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -18.0f; // in dB + private final static float PICO_FILTER_TRANSITION_FREQ = 1100.0f; // in Hz + private final static float PICO_FILTER_SHELF_SLOPE = 1.0f; // Q + // // External API // @@ -39,9 +48,12 @@ public class SynthProxy { /** * Constructor; pass the location of the native TTS .so to use. */ - public SynthProxy(String nativeSoLib) { - Log.v(TtsService.SERVICE_TAG, "TTS is loading " + nativeSoLib); - native_setup(new WeakReference<SynthProxy>(this), nativeSoLib); + public SynthProxy(String nativeSoLib, String engineConfig) { + boolean applyFilter = nativeSoLib.toLowerCase().contains("pico"); + Log.v(TtsService.SERVICE_TAG, "About to load "+ nativeSoLib + ", applyFilter="+applyFilter); + native_setup(new WeakReference<SynthProxy>(this), nativeSoLib, engineConfig); + native_setLowShelf(applyFilter, PICO_FILTER_GAIN, PICO_FILTER_LOWSHELF_ATTENUATION, + PICO_FILTER_TRANSITION_FREQ, PICO_FILTER_SHELF_SLOPE); } /** @@ -93,6 +105,13 @@ public class SynthProxy { } /** + * Updates the engine configuration. + */ + public int setConfig(String engineConfig) { + return native_setConfig(mJniData, engineConfig); + } + + /** * Sets the language. */ public int setLanguage(String language, String country, String variant) { @@ -161,8 +180,11 @@ public class SynthProxy { */ private int mJniData = 0; - private native final void native_setup(Object weak_this, - String nativeSoLib); + private native final int native_setup(Object weak_this, String nativeSoLib, + String engineConfig); + + private native final int native_setLowShelf(boolean applyFilter, float filterGain, + float attenuationInDb, float freqInHz, float slope); private native final void native_finalize(int jniData); @@ -183,6 +205,8 @@ public class SynthProxy { private native final int native_loadLanguage(int jniData, String language, String country, String variant); + private native final int native_setConfig(int jniData, String engineConfig); + private native final int native_setSpeechRate(int jniData, int speechRate); private native final int native_setPitch(int jniData, int speechRate); diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java index 217d3bb..c977ba3 100755 --- a/packages/TtsService/src/android/tts/TtsService.java +++ b/packages/TtsService/src/android/tts/TtsService.java @@ -20,8 +20,11 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; +import android.database.Cursor; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; @@ -36,9 +39,11 @@ import android.speech.tts.TextToSpeech; import android.util.Log; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.TimeUnit; @@ -118,7 +123,8 @@ public class TtsService extends Service implements OnCompletionListener { private static final int MAX_FILENAME_LENGTH = 250; // TODO use the TTS stream type when available private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_MUSIC; - + // TODO use TextToSpeech.DEFAULT_SYNTH once it is unhidden + private static final String DEFAULT_SYNTH = "com.svox.pico"; private static final String ACTION = "android.intent.action.START_TTS_SERVICE"; private static final String CATEGORY = "android.intent.category.TTS"; private static final String PKGNAME = "android.tts"; @@ -130,6 +136,7 @@ public class TtsService extends Service implements OnCompletionListener { private HashMap<String, ITtsCallback> mCallbacksMap; private Boolean mIsSpeaking; + private Boolean mSynthBusy; private ArrayList<SpeechItem> mSpeechQueue; private HashMap<String, SoundResource> mEarcons; private HashMap<String, SoundResource> mUtterances; @@ -146,6 +153,8 @@ public class TtsService extends Service implements OnCompletionListener { private final ReentrantLock synthesizerLock = new ReentrantLock(); private static SynthProxy sNativeSynth = null; + private String currentSpeechEngineSOFile = ""; + @Override public void onCreate() { super.onCreate(); @@ -153,13 +162,12 @@ public class TtsService extends Service implements OnCompletionListener { mResolver = getContentResolver(); - String soLibPath = "/system/lib/libttspico.so"; - if (sNativeSynth == null) { - sNativeSynth = new SynthProxy(soLibPath); - } + currentSpeechEngineSOFile = ""; + setEngine(getDefaultEngine()); mSelf = this; mIsSpeaking = false; + mSynthBusy = false; mEarcons = new HashMap<String, SoundResource>(); mUtterances = new HashMap<String, SoundResource>(); @@ -194,6 +202,94 @@ public class TtsService extends Service implements OnCompletionListener { } + private int setEngine(String enginePackageName) { + String soFilename = ""; + if (isDefaultEnforced()) { + enginePackageName = getDefaultEngine(); + } + + // Make sure that the engine has been allowed by the user + if (!enginePackageName.equals(DEFAULT_SYNTH)) { + String[] enabledEngines = android.provider.Settings.Secure.getString(mResolver, + android.provider.Settings.Secure.TTS_ENABLED_PLUGINS).split(" "); + boolean isEnabled = false; + for (int i=0; i<enabledEngines.length; i++) { + if (enabledEngines[i].equals(enginePackageName)) { + isEnabled = true; + break; + } + } + if (!isEnabled) { + // Do not use an engine that the user has not enabled; fall back + // to using the default synthesizer. + enginePackageName = DEFAULT_SYNTH; + } + } + + // The SVOX TTS is an exception to how the TTS packaging scheme works + // because it is part of the system and not a 3rd party add-on; thus + // its binary is actually located under /system/lib/ + if (enginePackageName.equals(DEFAULT_SYNTH)) { + soFilename = "/system/lib/libttspico.so"; + } else { + // Find the package + Intent intent = new Intent("android.intent.action.START_TTS_ENGINE"); + intent.setPackage(enginePackageName); + ResolveInfo[] enginesArray = new ResolveInfo[0]; + PackageManager pm = getPackageManager(); + List <ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); + if ((resolveInfos == null) || resolveInfos.isEmpty()) { + Log.e(SERVICE_TAG, "Invalid TTS Engine Package: " + enginePackageName); + return TextToSpeech.ERROR; + } + enginesArray = resolveInfos.toArray(enginesArray); + // Generate the TTS .so filename from the package + ActivityInfo aInfo = enginesArray[0].activityInfo; + soFilename = aInfo.name.replace(aInfo.packageName + ".", "") + ".so"; + soFilename = soFilename.toLowerCase(); + soFilename = "/data/data/" + aInfo.packageName + "/lib/libtts" + soFilename; + } + + if (currentSpeechEngineSOFile.equals(soFilename)) { + return TextToSpeech.SUCCESS; + } + + File f = new File(soFilename); + if (!f.exists()) { + Log.e(SERVICE_TAG, "Invalid TTS Binary: " + soFilename); + return TextToSpeech.ERROR; + } + + if (sNativeSynth != null) { + sNativeSynth.stopSync(); + sNativeSynth.shutdown(); + sNativeSynth = null; + } + + // Load the engineConfig from the plugin if it has any special configuration + // to be loaded. By convention, if an engine wants the TTS framework to pass + // in any configuration, it must put it into its content provider which has the URI: + // content://<packageName>.providers.SettingsProvider + // That content provider must provide a Cursor which returns the String that + // is to be passed back to the native .so file for the plugin when getString(0) is + // called on it. + // Note that the TTS framework does not care what this String data is: it is something + // that comes from the engine plugin and is consumed only by the engine plugin itself. + String engineConfig = ""; + Cursor c = getContentResolver().query(Uri.parse("content://" + enginePackageName + + ".providers.SettingsProvider"), null, null, null, null); + if (c != null){ + c.moveToFirst(); + engineConfig = c.getString(0); + c.close(); + } + sNativeSynth = new SynthProxy(soFilename, engineConfig); + currentSpeechEngineSOFile = soFilename; + return TextToSpeech.SUCCESS; + } + + + private void setDefaultSettings() { setLanguage("", this.getDefaultLanguage(), getDefaultCountry(), getDefaultLocVariant()); @@ -209,6 +305,15 @@ public class TtsService extends Service implements OnCompletionListener { == 1 ); } + private String getDefaultEngine() { + String defaultEngine = android.provider.Settings.Secure.getString(mResolver, + android.provider.Settings.Secure.TTS_DEFAULT_SYNTH); + if (defaultEngine == null) { + return TextToSpeech.Engine.DEFAULT_SYNTH; + } else { + return defaultEngine; + } + } private int getDefaultRate() { return android.provider.Settings.Secure.getInt(mResolver, @@ -216,6 +321,10 @@ public class TtsService extends Service implements OnCompletionListener { TextToSpeech.Engine.DEFAULT_RATE); } + private int getDefaultPitch() { + // Pitch is not user settable; the default pitch is always 100. + return 100; + } private String getDefaultLanguage() { String defaultLang = android.provider.Settings.Secure.getString(mResolver, @@ -596,22 +705,27 @@ public class TtsService extends Service implements OnCompletionListener { } } - public void onCompletion(MediaPlayer arg0) { - String callingApp = mCurrentSpeechItem.mCallingApp; - ArrayList<String> params = mCurrentSpeechItem.mParams; - String utteranceId = ""; - if (params != null){ - for (int i = 0; i < params.size() - 1; i = i + 2){ - String param = params.get(i); - if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ - utteranceId = params.get(i+1); - } - } - } - if (utteranceId.length() > 0){ - dispatchUtteranceCompletedCallback(utteranceId, callingApp); - } - processSpeechQueue(); + public void onCompletion(MediaPlayer arg0) {
+ // mCurrentSpeechItem may become null if it is stopped at the same
+ // time it completes.
+ SpeechItem currentSpeechItemCopy = mCurrentSpeechItem;
+ if (currentSpeechItemCopy != null) {
+ String callingApp = currentSpeechItemCopy.mCallingApp;
+ ArrayList<String> params = currentSpeechItemCopy.mParams;
+ String utteranceId = "";
+ if (params != null) {
+ for (int i = 0; i < params.size() - 1; i = i + 2) {
+ String param = params.get(i);
+ if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)) {
+ utteranceId = params.get(i + 1);
+ }
+ }
+ }
+ if (utteranceId.length() > 0) {
+ dispatchUtteranceCompletedCallback(utteranceId, callingApp);
+ }
+ }
+ processSpeechQueue();
} private int playSilence(String callingApp, long duration, int queueMode, @@ -663,10 +777,11 @@ public class TtsService extends Service implements OnCompletionListener { try { synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { + mSynthBusy = true; Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); + mSynthBusy = false; return; } int streamType = DEFAULT_STREAM_TYPE; @@ -674,6 +789,8 @@ public class TtsService extends Service implements OnCompletionListener { String country = ""; String variant = ""; String speechRate = ""; + String engine = ""; + String pitch = ""; if (speechItem.mParams != null){ for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); @@ -695,17 +812,36 @@ public class TtsService extends Service implements OnCompletionListener { } catch (NumberFormatException e) { streamType = DEFAULT_STREAM_TYPE; } + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) { + engine = speechItem.mParams.get(i + 1); + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_PITCH)) { + pitch = speechItem.mParams.get(i + 1); } } } } // Only do the synthesis if it has not been killed by a subsequent utterance. if (mKillList.get(speechItem) == null) { + if (engine.length() > 0) { + setEngine(engine); + } else { + setEngine(getDefaultEngine()); + } if (language.length() > 0){ setLanguage("", language, country, variant); + } else { + setLanguage("", getDefaultLanguage(), getDefaultCountry(), + getDefaultLocVariant()); } if (speechRate.length() > 0){ setSpeechRate("", Integer.parseInt(speechRate)); + } else { + setSpeechRate("", getDefaultRate()); + } + if (pitch.length() > 0){ + setPitch("", Integer.parseInt(pitch)); + } else { + setPitch("", getDefaultPitch()); } try { sNativeSynth.speak(speechItem.mText, streamType); @@ -726,8 +862,8 @@ public class TtsService extends Service implements OnCompletionListener { } if (synthAvailable) { synthesizerLock.unlock(); + processSpeechQueue(); } - processSpeechQueue(); } } } @@ -745,16 +881,23 @@ public class TtsService extends Service implements OnCompletionListener { try { synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { + synchronized (this) { + mSynthBusy = true; + } Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); + synchronized (this) { + mSynthBusy = false; + } return; } String language = ""; String country = ""; String variant = ""; String speechRate = ""; + String engine = ""; + String pitch = ""; if (speechItem.mParams != null){ for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); @@ -769,17 +912,36 @@ public class TtsService extends Service implements OnCompletionListener { variant = speechItem.mParams.get(i+1); } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = speechItem.mParams.get(i+1); + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) { + engine = speechItem.mParams.get(i + 1); + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_PITCH)) { + pitch = speechItem.mParams.get(i + 1); } } } } // Only do the synthesis if it has not been killed by a subsequent utterance. if (mKillList.get(speechItem) == null){ + if (engine.length() > 0) { + setEngine(engine); + } else { + setEngine(getDefaultEngine()); + } if (language.length() > 0){ setLanguage("", language, country, variant); + } else { + setLanguage("", getDefaultLanguage(), getDefaultCountry(), + getDefaultLocVariant()); } if (speechRate.length() > 0){ setSpeechRate("", Integer.parseInt(speechRate)); + } else { + setSpeechRate("", getDefaultRate()); + } + if (pitch.length() > 0){ + setPitch("", Integer.parseInt(pitch)); + } else { + setPitch("", getDefaultPitch()); } try { sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename); @@ -800,8 +962,8 @@ public class TtsService extends Service implements OnCompletionListener { } if (synthAvailable) { synthesizerLock.unlock(); + processSpeechQueue(); } - processSpeechQueue(); } } } @@ -877,6 +1039,12 @@ public class TtsService extends Service implements OnCompletionListener { private void processSpeechQueue() { boolean speechQueueAvailable = false; + synchronized (this) { + if (mSynthBusy){ + // There is already a synth thread waiting to run. + return; + } + } try { speechQueueAvailable = speechQueueLock.tryLock(SPEECHQUEUELOCK_TIMEOUT, TimeUnit.MILLISECONDS); @@ -999,7 +1167,7 @@ public class TtsService extends Service implements OnCompletionListener { * @param filename * The string that gives the full output filename; it should be * something like "/sdcard/myappsounds/mysound.wav". - * @return A boolean that indicates if the synthesis succeeded + * @return A boolean that indicates if the synthesis can be started */ private boolean synthesizeToFile(String callingApp, String text, ArrayList<String> params, String filename) { @@ -1012,6 +1180,22 @@ public class TtsService extends Service implements OnCompletionListener { if (text.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH){ return false; } + // Check that the output file can be created + try { + File tempFile = new File(filename); + if (tempFile.exists()) { + Log.v("TtsService", "File " + filename + " exists, deleting."); + tempFile.delete(); + } + if (!tempFile.createNewFile()) { + Log.e("TtsService", "Unable to synthesize to file: can't create " + filename); + return false; + } + tempFile.delete(); + } catch (IOException e) { + Log.e("TtsService", "Can't create " + filename + " due to exception " + e); + return false; + } mSpeechQueue.add(new SpeechItem(callingApp, text, params, SpeechItem.TEXT_TO_FILE, filename)); if (!mIsSpeaking) { processSpeechQueue(); @@ -1213,7 +1397,17 @@ public class TtsService extends Service implements OnCompletionListener { * TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE as defined in * android.speech.tts.TextToSpeech. */ - public int isLanguageAvailable(String lang, String country, String variant) { + public int isLanguageAvailable(String lang, String country, String variant, + String[] params) { + for (int i = 0; i < params.length - 1; i = i + 2){ + String param = params[i]; + if (param != null) { + if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) { + mSelf.setEngine(params[i + 1]); + break; + } + } + } return mSelf.isLanguageAvailable(lang, country, variant); } @@ -1261,6 +1455,36 @@ public class TtsService extends Service implements OnCompletionListener { return mSelf.synthesizeToFile(callingApp, text, speakingParams, filename); } + /** + * Sets the speech synthesis engine for the TTS by specifying its packagename + * + * @param packageName the packageName of the speech synthesis engine (ie, "com.svox.pico") + * + * @return SUCCESS or ERROR as defined in android.speech.tts.TextToSpeech. + */ + public int setEngineByPackageName(String packageName) {
+ return mSelf.setEngine(packageName);
+ } + + /** + * Returns the packagename of the default speech synthesis engine. + * + * @return Packagename of the TTS engine that the user has chosen as their default. + */ + public String getDefaultEngine() { + return mSelf.getDefaultEngine(); + } + + /** + * Returns whether or not the user is forcing their defaults to override the + * Text-To-Speech settings set by applications. + * + * @return Whether or not defaults are enforced. + */ + public boolean areDefaultsEnforced() { + return mSelf.isDefaultEnforced(); + } + }; } diff --git a/packages/VpnServices/Android.mk b/packages/VpnServices/Android.mk index eb27ed5..6cdf674 100644 --- a/packages/VpnServices/Android.mk +++ b/packages/VpnServices/Android.mk @@ -1,7 +1,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := user +LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) diff --git a/packages/VpnServices/res/values-cs/strings.xml b/packages/VpnServices/res/values-cs/strings.xml index 9e20c19..96d4cc5 100644 --- a/packages/VpnServices/res/values-cs/strings.xml +++ b/packages/VpnServices/res/values-cs/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string> diff --git a/packages/VpnServices/res/values-da/strings.xml b/packages/VpnServices/res/values-da/strings.xml index fb5ddf9..0f05bbc 100644 --- a/packages/VpnServices/res/values-da/strings.xml +++ b/packages/VpnServices/res/values-da/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string> diff --git a/packages/VpnServices/res/values-de/strings.xml b/packages/VpnServices/res/values-de/strings.xml index f120253..b907be8 100644 --- a/packages/VpnServices/res/values-de/strings.xml +++ b/packages/VpnServices/res/values-de/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-Dienste"</string> diff --git a/packages/VpnServices/res/values-el/strings.xml b/packages/VpnServices/res/values-el/strings.xml index 06f907c..d96f3e0 100644 --- a/packages/VpnServices/res/values-el/strings.xml +++ b/packages/VpnServices/res/values-el/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Υπηρεσίες VPN"</string> diff --git a/packages/VpnServices/res/values-es-rUS/strings.xml b/packages/VpnServices/res/values-es-rUS/strings.xml index f6ace53..8f5053c 100644 --- a/packages/VpnServices/res/values-es-rUS/strings.xml +++ b/packages/VpnServices/res/values-es-rUS/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string> diff --git a/packages/VpnServices/res/values-es/strings.xml b/packages/VpnServices/res/values-es/strings.xml index 2864c75..9182459 100644 --- a/packages/VpnServices/res/values-es/strings.xml +++ b/packages/VpnServices/res/values-es/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string> diff --git a/packages/VpnServices/res/values-fr/strings.xml b/packages/VpnServices/res/values-fr/strings.xml index 519a9ab..80fefa4 100644 --- a/packages/VpnServices/res/values-fr/strings.xml +++ b/packages/VpnServices/res/values-fr/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Services VPN"</string> diff --git a/packages/VpnServices/res/values-it/strings.xml b/packages/VpnServices/res/values-it/strings.xml index fd6e76b..1c7a588 100644 --- a/packages/VpnServices/res/values-it/strings.xml +++ b/packages/VpnServices/res/values-it/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Servizi VPN"</string> diff --git a/packages/VpnServices/res/values-ja/strings.xml b/packages/VpnServices/res/values-ja/strings.xml index 2bad0e3..548d8a9 100644 --- a/packages/VpnServices/res/values-ja/strings.xml +++ b/packages/VpnServices/res/values-ja/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPNサービス"</string> diff --git a/packages/VpnServices/res/values-ko/strings.xml b/packages/VpnServices/res/values-ko/strings.xml index a48eff6..4185291 100644 --- a/packages/VpnServices/res/values-ko/strings.xml +++ b/packages/VpnServices/res/values-ko/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN 서비스"</string> diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml index 9aac828..4790600 100644 --- a/packages/VpnServices/res/values-nb/strings.xml +++ b/packages/VpnServices/res/values-nb/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string> diff --git a/packages/VpnServices/res/values-nl/strings.xml b/packages/VpnServices/res/values-nl/strings.xml index d5a55e8..175c7dd 100644 --- a/packages/VpnServices/res/values-nl/strings.xml +++ b/packages/VpnServices/res/values-nl/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-services"</string> diff --git a/packages/VpnServices/res/values-pl/strings.xml b/packages/VpnServices/res/values-pl/strings.xml index 6626c69..565d249 100644 --- a/packages/VpnServices/res/values-pl/strings.xml +++ b/packages/VpnServices/res/values-pl/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Usługi VPN"</string> diff --git a/packages/VpnServices/res/values-pt-rPT/strings.xml b/packages/VpnServices/res/values-pt-rPT/strings.xml index 182e600..020188f 100644 --- a/packages/VpnServices/res/values-pt-rPT/strings.xml +++ b/packages/VpnServices/res/values-pt-rPT/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Serviços VPN"</string> diff --git a/packages/VpnServices/res/values-pt/strings.xml b/packages/VpnServices/res/values-pt/strings.xml index a2877d6..f47652a 100644 --- a/packages/VpnServices/res/values-pt/strings.xml +++ b/packages/VpnServices/res/values-pt/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Serviços de VPN"</string> diff --git a/packages/VpnServices/res/values-ru/strings.xml b/packages/VpnServices/res/values-ru/strings.xml index 7458f0c..8a839c3 100644 --- a/packages/VpnServices/res/values-ru/strings.xml +++ b/packages/VpnServices/res/values-ru/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"Службы VPN"</string> diff --git a/packages/VpnServices/res/values-sv/strings.xml b/packages/VpnServices/res/values-sv/strings.xml index ba541b8..24f9f58 100644 --- a/packages/VpnServices/res/values-sv/strings.xml +++ b/packages/VpnServices/res/values-sv/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN-tjänster"</string> diff --git a/packages/VpnServices/res/values-tr/strings.xml b/packages/VpnServices/res/values-tr/strings.xml index 41a0b4e..8666b35 100644 --- a/packages/VpnServices/res/values-tr/strings.xml +++ b/packages/VpnServices/res/values-tr/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN Hizmetleri"</string> diff --git a/packages/VpnServices/res/values-zh-rCN/strings.xml b/packages/VpnServices/res/values-zh-rCN/strings.xml index ee8878f..cad08e1 100644 --- a/packages/VpnServices/res/values-zh-rCN/strings.xml +++ b/packages/VpnServices/res/values-zh-rCN/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"虚拟专用网服务"</string> diff --git a/packages/VpnServices/res/values-zh-rTW/strings.xml b/packages/VpnServices/res/values-zh-rTW/strings.xml index 931d4ed..ee5a42b 100644 --- a/packages/VpnServices/res/values-zh-rTW/strings.xml +++ b/packages/VpnServices/res/values-zh-rTW/strings.xml @@ -1,18 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright (C) 2009 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. ---> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4589592829302498102">"VPN 服務"</string> diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java index e5be847..5672a01 100644 --- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java +++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java @@ -26,7 +26,9 @@ import android.net.vpn.PptpProfile; import android.net.vpn.VpnManager; import android.net.vpn.VpnProfile; import android.net.vpn.VpnState; +import android.os.Environment; import android.os.IBinder; +import android.os.SystemProperties; import android.util.Log; import java.io.File; @@ -45,11 +47,15 @@ public class VpnServiceBinder extends Service { private static final String TAG = VpnServiceBinder.class.getSimpleName(); private static final boolean DBG = true; - private static final String STATES_FILE_PATH = "/data/misc/vpn/.states"; + private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states"; // The actual implementation is delegated to the VpnService class. private VpnService<? extends VpnProfile> mService; + private static String getStateFilePath() { + return Environment.getDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH; + } + private final IBinder mBinder = new IVpnService.Stub() { public boolean connect(VpnProfile p, String username, String password) { return VpnServiceBinder.this.connect(p, username, password); @@ -84,14 +90,14 @@ public class VpnServiceBinder extends Service { void saveStates() throws IOException { if (DBG) Log.d("VpnServiceBinder", " saving states"); ObjectOutputStream oos = - new ObjectOutputStream(new FileOutputStream(STATES_FILE_PATH)); + new ObjectOutputStream(new FileOutputStream(getStateFilePath())); oos.writeObject(mService); oos.close(); } void removeStates() { try { - File f = new File(STATES_FILE_PATH); + File f = new File(getStateFilePath()); if (f.exists()) f.delete(); } catch (Throwable e) { if (DBG) Log.d("VpnServiceBinder", " remove states: " + e); @@ -134,7 +140,7 @@ public class VpnServiceBinder extends Service { private void checkSavedStates() { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( - STATES_FILE_PATH)); + getStateFilePath())); mService = (VpnService<? extends VpnProfile>) ois.readObject(); mService.recover(this); ois.close(); |