Merge "Add support of advertising through standard instance.(1/4)" into lmp-sprout-dev
diff --git a/Android.mk b/Android.mk
index b323650..7362803 100644
--- a/Android.mk
+++ b/Android.mk
@@ -422,85 +422,160 @@
include $(CLEAR_VARS)
aidl_files := \
- frameworks/base/core/java/android/accounts/IAccountManager.aidl \
- frameworks/base/core/java/android/accounts/IAccountManagerResponse.aidl \
- frameworks/base/core/java/android/accounts/IAccountAuthenticator.aidl \
- frameworks/base/core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
- frameworks/base/core/java/android/app/Notification.aidl \
- frameworks/base/core/java/android/app/PendingIntent.aidl \
- frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
- frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
- frameworks/base/core/java/android/bluetooth/BluetoothHealthAppConfiguration.aidl \
- frameworks/base/core/java/android/content/ComponentName.aidl \
- frameworks/base/core/java/android/content/ContentValues.aidl \
- frameworks/base/core/java/android/content/Intent.aidl \
- frameworks/base/core/java/android/content/IntentSender.aidl \
- frameworks/base/core/java/android/content/PeriodicSync.aidl \
- frameworks/base/core/java/android/content/SyncRequest.aidl \
- frameworks/base/core/java/android/content/SyncStats.aidl \
- frameworks/base/core/java/android/content/res/Configuration.aidl \
- frameworks/base/core/java/android/database/CursorWindow.aidl \
- frameworks/base/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl \
- frameworks/base/core/java/android/net/Uri.aidl \
- frameworks/base/core/java/android/nfc/NdefMessage.aidl \
- frameworks/base/core/java/android/nfc/NdefRecord.aidl \
- frameworks/base/core/java/android/nfc/Tag.aidl \
- frameworks/base/core/java/android/os/Bundle.aidl \
- frameworks/base/core/java/android/os/DropBoxManager.aidl \
- frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
- frameworks/base/core/java/android/os/ParcelUuid.aidl \
- frameworks/base/core/java/android/os/PersistableBundle.aidl \
- frameworks/base/core/java/android/print/PrinterInfo.aidl \
+ frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
+ frameworks/base/telephony/java/android/telephony/CellInfo.aidl \
+ frameworks/base/telephony/java/android/telephony/SignalStrength.aidl \
+ frameworks/base/telephony/java/android/telephony/IccOpenLogicalChannelResponse.aidl \
+ frameworks/base/telephony/java/android/telephony/NeighboringCellInfo.aidl \
+ frameworks/base/location/java/android/location/Location.aidl \
+ frameworks/base/location/java/android/location/Address.aidl \
+ frameworks/base/location/java/android/location/Criteria.aidl \
+ frameworks/base/media/java/android/media/MediaMetadata.aidl \
+ frameworks/base/media/java/android/media/MediaDescription.aidl \
+ frameworks/base/media/java/android/media/Rating.aidl \
+ frameworks/base/media/java/android/media/AudioAttributes.aidl \
+ frameworks/base/media/java/android/media/session/PlaybackState.aidl \
+ frameworks/base/media/java/android/media/session/MediaSession.aidl \
+ frameworks/base/media/java/android/media/tv/TvInputInfo.aidl \
+ frameworks/base/media/java/android/media/tv/TvTrackInfo.aidl \
+ frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
+ frameworks/base/wifi/java/android/net/wifi/ScanSettings.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl \
+ frameworks/base/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl \
+ frameworks/base/wifi/java/android/net/wifi/WpsInfo.aidl \
+ frameworks/base/wifi/java/android/net/wifi/ScanResult.aidl \
+ frameworks/base/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl \
+ frameworks/base/wifi/java/android/net/wifi/WifiConfiguration.aidl \
+ frameworks/base/wifi/java/android/net/wifi/WifiInfo.aidl \
+ frameworks/base/graphics/java/android/graphics/Region.aidl \
+ frameworks/base/graphics/java/android/graphics/Bitmap.aidl \
+ frameworks/base/graphics/java/android/graphics/Point.aidl \
+ frameworks/base/graphics/java/android/graphics/PointF.aidl \
+ frameworks/base/graphics/java/android/graphics/RectF.aidl \
+ frameworks/base/graphics/java/android/graphics/Rect.aidl \
+ frameworks/base/core/java/android/accounts/AuthenticatorDescription.aidl \
+ frameworks/base/core/java/android/accounts/Account.aidl \
+ frameworks/base/core/java/android/print/PrintDocumentInfo.aidl \
frameworks/base/core/java/android/print/PageRange.aidl \
frameworks/base/core/java/android/print/PrintAttributes.aidl \
frameworks/base/core/java/android/print/PrinterCapabilitiesInfo.aidl \
frameworks/base/core/java/android/print/PrinterId.aidl \
- frameworks/base/core/java/android/print/PrintJobId.aidl \
frameworks/base/core/java/android/print/PrintJobInfo.aidl \
- frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
- frameworks/base/core/java/android/view/accessibility/AccessibilityEvent.aidl \
+ frameworks/base/core/java/android/print/PrinterInfo.aidl \
+ frameworks/base/core/java/android/print/PrintJobId.aidl \
+ frameworks/base/core/java/android/hardware/usb/UsbDevice.aidl \
+ frameworks/base/core/java/android/hardware/usb/UsbInterface.aidl \
+ frameworks/base/core/java/android/hardware/usb/UsbEndpoint.aidl \
+ frameworks/base/core/java/android/hardware/usb/UsbAccessory.aidl \
+ frameworks/base/core/java/android/os/Messenger.aidl \
+ frameworks/base/core/java/android/os/PatternMatcher.aidl \
+ frameworks/base/core/java/android/os/Message.aidl \
+ frameworks/base/core/java/android/os/UserHandle.aidl \
+ frameworks/base/core/java/android/os/ParcelUuid.aidl \
+ frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
+ frameworks/base/core/java/android/os/ResultReceiver.aidl \
+ frameworks/base/core/java/android/os/PersistableBundle.aidl \
+ frameworks/base/core/java/android/os/WorkSource.aidl \
+ frameworks/base/core/java/android/os/DropBoxManager.aidl \
+ frameworks/base/core/java/android/os/Bundle.aidl \
+ frameworks/base/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl \
+ frameworks/base/core/java/android/net/Network.aidl \
+ frameworks/base/core/java/android/net/RouteInfo.aidl \
+ frameworks/base/core/java/android/net/NetworkInfo.aidl \
+ frameworks/base/core/java/android/net/IpPrefix.aidl \
+ frameworks/base/core/java/android/net/NetworkCapabilities.aidl \
+ frameworks/base/core/java/android/net/DhcpInfo.aidl \
+ frameworks/base/core/java/android/net/ProxyInfo.aidl \
+ frameworks/base/core/java/android/net/LinkProperties.aidl \
+ frameworks/base/core/java/android/net/Uri.aidl \
+ frameworks/base/core/java/android/net/NetworkRequest.aidl \
+ frameworks/base/core/java/android/net/LinkAddress.aidl \
+ frameworks/base/core/java/android/view/Surface.aidl \
+ frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
+ frameworks/base/core/java/android/view/InputDevice.aidl \
+ frameworks/base/core/java/android/view/InputEvent.aidl \
+ frameworks/base/core/java/android/view/inputmethod/InputMethodSubtype.aidl \
+ frameworks/base/core/java/android/view/inputmethod/CursorAnchorInfo.aidl \
+ frameworks/base/core/java/android/view/inputmethod/CompletionInfo.aidl \
+ frameworks/base/core/java/android/view/inputmethod/ExtractedText.aidl \
+ frameworks/base/core/java/android/view/inputmethod/EditorInfo.aidl \
+ frameworks/base/core/java/android/view/inputmethod/InputMethodInfo.aidl \
+ frameworks/base/core/java/android/view/inputmethod/CorrectionInfo.aidl \
+ frameworks/base/core/java/android/view/inputmethod/InputBinding.aidl \
+ frameworks/base/core/java/android/view/inputmethod/ExtractedTextRequest.aidl \
+ frameworks/base/core/java/android/view/DragEvent.aidl \
+ frameworks/base/core/java/android/view/KeyEvent.aidl \
+ frameworks/base/core/java/android/view/WindowAnimationFrameStats.aidl \
+ frameworks/base/core/java/android/view/MotionEvent.aidl \
frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl \
frameworks/base/core/java/android/view/accessibility/AccessibilityRecord.aidl \
frameworks/base/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl \
- frameworks/base/core/java/android/view/KeyEvent.aidl \
- frameworks/base/core/java/android/view/MotionEvent.aidl \
- frameworks/base/core/java/android/view/Surface.aidl \
- frameworks/base/core/java/android/view/WindowManager.aidl \
- frameworks/base/core/java/android/view/WindowAnimationFrameStats.aidl \
- frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
+ frameworks/base/core/java/android/view/accessibility/AccessibilityEvent.aidl \
+ frameworks/base/core/java/android/view/textservice/SpellCheckerSubtype.aidl \
+ frameworks/base/core/java/android/view/textservice/TextInfo.aidl \
+ frameworks/base/core/java/android/view/textservice/SpellCheckerInfo.aidl \
+ frameworks/base/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl \
+ frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
+ frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
+ frameworks/base/core/java/android/speech/tts/Voice.aidl \
+ frameworks/base/core/java/android/app/usage/UsageEvents.aidl \
+ frameworks/base/core/java/android/app/Notification.aidl \
+ frameworks/base/core/java/android/app/WallpaperInfo.aidl \
+ frameworks/base/core/java/android/app/AppOpsManager.aidl \
+ frameworks/base/core/java/android/app/ActivityManager.aidl \
+ frameworks/base/core/java/android/app/PendingIntent.aidl \
+ frameworks/base/core/java/android/app/AlarmManager.aidl \
+ frameworks/base/core/java/android/app/SearchableInfo.aidl \
+ frameworks/base/core/java/android/app/job/JobParameters.aidl \
+ frameworks/base/core/java/android/app/job/JobInfo.aidl \
+ frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
+ frameworks/base/core/java/android/content/ClipDescription.aidl \
+ frameworks/base/core/java/android/content/IntentFilter.aidl \
+ frameworks/base/core/java/android/content/Intent.aidl \
+ frameworks/base/core/java/android/content/res/Configuration.aidl \
+ frameworks/base/core/java/android/content/res/ObbInfo.aidl \
+ frameworks/base/core/java/android/content/RestrictionEntry.aidl \
+ frameworks/base/core/java/android/content/ClipData.aidl \
+ frameworks/base/core/java/android/content/SyncAdapterType.aidl \
+ frameworks/base/core/java/android/content/SyncRequest.aidl \
+ frameworks/base/core/java/android/content/PeriodicSync.aidl \
+ frameworks/base/core/java/android/content/SyncResult.aidl \
+ frameworks/base/core/java/android/content/pm/FeatureInfo.aidl \
+ frameworks/base/core/java/android/content/pm/InstrumentationInfo.aidl \
+ frameworks/base/core/java/android/content/pm/PackageInstaller.aidl \
+ frameworks/base/core/java/android/content/pm/ServiceInfo.aidl \
+ frameworks/base/core/java/android/content/pm/Signature.aidl \
+ frameworks/base/core/java/android/content/pm/ApplicationInfo.aidl \
+ frameworks/base/core/java/android/content/pm/PermissionInfo.aidl \
+ frameworks/base/core/java/android/content/pm/ActivityInfo.aidl \
+ frameworks/base/core/java/android/content/pm/PackageInfo.aidl \
+ frameworks/base/core/java/android/content/pm/ResolveInfo.aidl \
+ frameworks/base/core/java/android/content/pm/ProviderInfo.aidl \
+ frameworks/base/core/java/android/content/pm/PackageStats.aidl \
+ frameworks/base/core/java/android/content/pm/PermissionGroupInfo.aidl \
+ frameworks/base/core/java/android/content/ComponentName.aidl \
+ frameworks/base/core/java/android/content/SyncStats.aidl \
+ frameworks/base/core/java/android/content/ContentValues.aidl \
+ frameworks/base/core/java/android/content/SyncInfo.aidl \
+ frameworks/base/core/java/android/content/IntentSender.aidl \
frameworks/base/core/java/android/widget/RemoteViews.aidl \
- frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
- frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
- frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
- frameworks/base/core/java/com/android/internal/textservice/ITextServicesManager.aidl \
- frameworks/base/core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
- frameworks/base/core/java/com/android/internal/view/IInputContext.aidl \
- frameworks/base/core/java/com/android/internal/view/IInputMethod.aidl \
- frameworks/base/core/java/com/android/internal/view/IInputMethodClient.aidl \
- frameworks/base/core/java/com/android/internal/view/IInputMethodManager.aidl \
- frameworks/base/core/java/com/android/internal/view/IInputMethodSession.aidl \
- frameworks/base/graphics/java/android/graphics/Bitmap.aidl \
- frameworks/base/graphics/java/android/graphics/Rect.aidl \
- frameworks/base/graphics/java/android/graphics/Region.aidl \
- frameworks/base/location/java/android/location/Criteria.aidl \
- frameworks/base/location/java/android/location/Geofence.aidl \
- frameworks/base/location/java/android/location/Location.aidl \
- frameworks/base/location/java/android/location/LocationRequest.aidl \
- frameworks/base/location/java/android/location/FusedBatchOptions.aidl \
- frameworks/base/location/java/com/android/internal/location/ProviderProperties.aidl \
- frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
- frameworks/base/media/java/android/media/AudioAttributes.aidl \
- frameworks/base/media/java/android/media/MediaDescription.aidl \
- frameworks/base/media/java/android/media/MediaMetadata.aidl \
- frameworks/base/media/java/android/media/Rating.aidl \
- frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
- frameworks/base/media/java/android/media/session/MediaSession.aidl \
- frameworks/base/media/java/android/media/session/PlaybackState.aidl \
- frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
- frameworks/base/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
- frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl \
- frameworks/base/wifi/java/android/net/wifi/BatchedScanSettings.aidl \
- frameworks/base/wifi/java/android/net/wifi/BatchedScanResult.aidl \
+ frameworks/base/core/java/android/text/style/SuggestionSpan.aidl \
+ frameworks/base/core/java/android/nfc/Tag.aidl \
+ frameworks/base/core/java/android/nfc/NdefRecord.aidl \
+ frameworks/base/core/java/android/nfc/NdefMessage.aidl \
+ frameworks/base/core/java/android/bluetooth/BluetoothHealthAppConfiguration.aidl \
+ frameworks/base/core/java/android/bluetooth/le/AdvertiseSettings.aidl \
+ frameworks/base/core/java/android/bluetooth/le/ScanSettings.aidl \
+ frameworks/base/core/java/android/bluetooth/le/AdvertiseData.aidl \
+ frameworks/base/core/java/android/bluetooth/le/ScanFilter.aidl \
+ frameworks/base/core/java/android/bluetooth/le/ScanResult.aidl \
+ frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
+ frameworks/base/core/java/android/database/CursorWindow.aidl
gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
$(gen): PRIVATE_SRC_FILES := $(aidl_files)
@@ -631,6 +706,7 @@
-since $(SRC_API_DIR)/18.txt 18 \
-since $(SRC_API_DIR)/19.txt 19 \
-since $(SRC_API_DIR)/20.txt 20 \
+ -since $(SRC_API_DIR)/21.txt 21 \
-werror -hide 111 -hide 113 \
-overview $(LOCAL_PATH)/core/java/overview.html
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index cc0d51c..ba11a81 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -114,11 +114,7 @@
" am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
" [--user <USER_ID> | current]\n" +
- " [--no-window-animation]\n" +
- " [--abi <ABI>]\n : Launch the instrumented process with the " +
- " selected ABI. This assumes that the process supports the" +
- " selected ABI." +
- " <COMPONENT>\n" +
+ " [--no-window-animation] [--abi <ABI>] <COMPONENT>\n" +
" am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
" am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
" am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
@@ -194,6 +190,8 @@
" --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
" current user if not specified.\n" +
" --no-window-animation: turn off window animations while running.\n" +
+ " --abi <ABI>: Launch the instrumented process with the selected ABI.\n" +
+ " This assumes that the process supports the selected ABI.\n" +
"\n" +
"am profile: start and stop profiler on a process. The given <PROCESS> argument\n" +
" may be either a process name or pid. Options are:\n" +
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9f683e3..0e98175 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3498,14 +3498,24 @@
* <p>You can override this function to force global search, e.g. in response to a dedicated
* search key, or to block search entirely (by simply returning false).
*
- * @return Returns {@code true} if search launched, and {@code false} if activity blocks it.
- * The default implementation always returns {@code true}.
+ * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION}, the default
+ * implementation changes to simply return false and you must supply your own custom
+ * implementation if you want to support search.</p>
+ *
+ * @return Returns {@code true} if search launched, and {@code false} if the activity does
+ * not respond to search. The default implementation always returns {@code true}, except
+ * when in {@link Configuration#UI_MODE_TYPE_TELEVISION} mode where it returns false.
*
* @see android.app.SearchManager
*/
public boolean onSearchRequested() {
- startSearch(null, false, null, false);
- return true;
+ if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK)
+ != Configuration.UI_MODE_TYPE_TELEVISION) {
+ startSearch(null, false, null, false);
+ return true;
+ } else {
+ return false;
+ }
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2cd7379..37e8aa4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2621,17 +2621,17 @@
public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new FastPrintWriter(fout);
+ dumpService(pw, fd, "package", new String[] { packageName });
+ pw.println();
dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] {
"-a", "package", packageName });
pw.println();
- dumpService(pw, fd, "meminfo", new String[] { "--local", packageName });
+ dumpService(pw, fd, "meminfo", new String[] { "--local", "--package", packageName });
pw.println();
- dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { "-a", packageName });
+ dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
pw.println();
dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
pw.println();
- dumpService(pw, fd, "package", new String[] { packageName });
- pw.println();
dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName });
pw.flush();
}
@@ -2649,7 +2649,7 @@
tp = new TransferPipe();
tp.setBufferPrefix(" ");
service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
- tp.go(fd);
+ tp.go(fd, 10000);
} catch (Throwable e) {
if (tp != null) {
tp.kill();
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 11470e3..6c67c09 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1929,7 +1929,7 @@
case IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IIntentSender r = IIntentSender.Stub.asInterface(
- data.readStrongBinder());
+ data.readStrongBinder());
boolean res = isIntentSenderTargetedToPackage(r);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
@@ -2102,6 +2102,18 @@
return true;
}
+ case LAUNCH_ASSIST_INTENT_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ Intent intent = Intent.CREATOR.createFromParcel(data);
+ int requestType = data.readInt();
+ String hint = data.readString();
+ int userHandle = data.readInt();
+ boolean res = launchAssistIntent(intent, requestType, hint, userHandle);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case KILL_UID_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int uid = data.readInt();
@@ -5039,6 +5051,23 @@
reply.recycle();
}
+ public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ intent.writeToParcel(data, 0);
+ data.writeInt(requestType);
+ data.writeString(hint);
+ data.writeInt(userHandle);
+ mRemote.transact(LAUNCH_ASSIST_INTENT_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void killUid(int uid, String reason) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index aa5fea0..b72addf 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -417,6 +417,9 @@
public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
+ public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
+ throws RemoteException;
+
public void killUid(int uid, String reason) throws RemoteException;
public void hang(IBinder who, boolean allowRestart) throws RemoteException;
@@ -777,4 +780,5 @@
int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
+ int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
}
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 074d343..03e7ff4 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -31,4 +31,5 @@
ComponentName getGlobalSearchActivity();
ComponentName getWebSearchActivity();
ComponentName getAssistIntent(int userHandle);
+ boolean launchAssistAction(int requestType, String hint, int userHandle);
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 261b15d..a40b29a 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -23,6 +23,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
@@ -624,9 +625,13 @@
return;
}
- ensureSearchDialog();
+ UiModeManager uiModeManager = new UiModeManager();
+ // Don't show search dialog on televisions.
+ if (uiModeManager.getCurrentModeType() != Configuration.UI_MODE_TYPE_TELEVISION) {
+ ensureSearchDialog();
- mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData);
+ mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData);
+ }
}
private void ensureSearchDialog() {
@@ -984,4 +989,20 @@
return null;
}
}
+
+ /**
+ * Launch an assist action for the current top activity.
+ * @hide
+ */
+ public boolean launchAssistAction(int requestType, String hint, int userHandle) {
+ try {
+ if (mService == null) {
+ return false;
+ }
+ return mService.launchAssistAction(requestType, hint, userHandle);
+ } catch (RemoteException re) {
+ Log.e(TAG, "launchAssistAction() failed: " + re);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index ec9960d..c8e0031 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -192,7 +192,7 @@
* When running low on memory and needing to kill existing processes, the
* priority of a process hosting the service will be the higher of the
* following possibilities:
- *
+ *
* <ul>
* <li><p>If the service is currently executing code in its
* {@link #onCreate onCreate()}, {@link #onStartCommand onStartCommand()},
@@ -203,11 +203,19 @@
* to be less important than any processes that are currently visible to the
* user on-screen, but more important than any process not visible. Because
* only a few processes are generally visible to the user, this means that
- * the service should not be killed except in extreme low memory conditions.
+ * the service should not be killed except in low memory conditions. However, since
+ * the user is not directly aware of a background service, in that state it <em>is</em>
+ * considered a valid candidate to kill, and you should be prepared for this to
+ * happen. In particular, long-running services will be increasingly likely to
+ * kill and are guaranteed to be killed (and restarted if appropriate) if they
+ * remain started long enough.
* <li><p>If there are clients bound to the service, then the service's hosting
* process is never less important than the most important client. That is,
* if one of its clients is visible to the user, then the service itself is
- * considered to be visible.
+ * considered to be visible. The way a client's importance impacts the service's
+ * importance can be adjusted through {@link Context#BIND_ABOVE_CLIENT},
+ * {@link Context#BIND_ALLOW_OOM_MANAGEMENT}, {@link Context#BIND_WAIVE_PRIORITY},
+ * {@link Context#BIND_IMPORTANT}, and {@link Context#BIND_ADJUST_WITH_ACTIVITY}.
* <li><p>A started service can use the {@link #startForeground(int, Notification)}
* API to put the service in a foreground state, where the system considers
* it to be something the user is actively aware of and thus not a candidate
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 75a5237..a55cc2b 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -44,6 +44,16 @@
// device's preferred wallpaper image dimensions.
private static final boolean REJECT_OUTSIZED_RESTORE = true;
+ // When outsized restore rejection is enabled, this is the maximum ratio between the
+ // source and target image heights that will be permitted. The ratio is checked both
+ // ways (i.e. >= MAX, or <= 1/MAX) to validate restores from both largeer-than-target
+ // and smaller-than-target sources.
+ private static final double MAX_HEIGHT_RATIO = 1.35;
+
+ // The height ratio check when applying larger images on smaller screens is separate;
+ // in current policy we accept any such restore regardless of the relative dimensions.
+ private static final double MIN_HEIGHT_RATIO = 0;
+
// This path must match what the WallpaperManagerService uses
// TODO: Will need to change if backing up non-primary user's wallpaper
public static final String WALLPAPER_IMAGE =
@@ -142,8 +152,8 @@
// letterboxing.
final double heightRatio = mDesiredMinHeight / options.outHeight;
if (options.outWidth < mDesiredMinWidth
- || heightRatio <= 0
- || heightRatio >= 1.33) {
+ || heightRatio >= MAX_HEIGHT_RATIO
+ || heightRatio <= MIN_HEIGHT_RATIO) {
// Not wide enough for the screen, or too short/tall to be a good fit
// for the height of the screen, broken image file, or the system's
// desires for wallpaper size are in a bad state. Probably one of the
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index bbf6ed8..b4a4624 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -31,15 +31,32 @@
* Base class for a remotable object, the core part of a lightweight
* remote procedure call mechanism defined by {@link IBinder}.
* This class is an implementation of IBinder that provides
- * the standard support creating a local implementation of such an object.
- *
+ * standard local implementation of such an object.
+ *
* <p>Most developers will not implement this class directly, instead using the
* <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
* interface, having it generate the appropriate Binder subclass. You can,
* however, derive directly from Binder to implement your own custom RPC
* protocol or simply instantiate a raw Binder object directly to use as a
* token that can be shared across processes.
- *
+ *
+ * <p>This class is just a basic IPC primitive; it has no impact on an application's
+ * lifecycle, and is valid only as long as the process that created it continues to run.
+ * To use this correctly, you must be doing so within the context of a top-level
+ * application component (a {@link android.app.Service}, {@link android.app.Activity},
+ * or {@link android.content.ContentProvider}) that lets the system know your process
+ * should remain running.</p>
+ *
+ * <p>You must keep in mind the situations in which your process
+ * could go away, and thus require that you later re-create a new Binder and re-attach
+ * it when the process starts again. For example, if you are using this within an
+ * {@link android.app.Activity}, your activity's process may be killed any time the
+ * activity is not started; if the activity is later re-created you will need to
+ * create a new Binder and hand it back to the correct place again; you need to be
+ * aware that your process may be started for another reason (for example to receive
+ * a broadcast) that will not involve re-creating the activity and thus run its code
+ * to create a new Binder.</p>
+ *
* @see IBinder
*/
public class Binder implements IBinder {
diff --git a/core/java/android/os/Messenger.java b/core/java/android/os/Messenger.java
index ad55abdd..f362f56 100644
--- a/core/java/android/os/Messenger.java
+++ b/core/java/android/os/Messenger.java
@@ -21,6 +21,13 @@
* This allows for the implementation of message-based communication across
* processes, by creating a Messenger pointing to a Handler in one process,
* and handing that Messenger to another process.
+ *
+ * <p>Note: the implementation underneath is just a simple wrapper around
+ * a {@link Binder} that is used to perform the communication. This means
+ * semantically you should treat it as such: this class does not impact process
+ * lifecycle management (you must be using some higher-level component to tell
+ * the system that your process needs to continue running), the connection will
+ * break if your process goes away for any reason, etc.</p>
*/
public final class Messenger implements Parcelable {
private final IMessenger mTarget;
diff --git a/core/java/android/os/ResultReceiver.java b/core/java/android/os/ResultReceiver.java
index 711d4d9e..34a66b6 100644
--- a/core/java/android/os/ResultReceiver.java
+++ b/core/java/android/os/ResultReceiver.java
@@ -23,6 +23,13 @@
* by creating a subclass and implement {@link #onReceiveResult}, which you can
* then pass to others and send through IPC, and receive results they
* supply with {@link #send}.
+ *
+ * <p>Note: the implementation underneath is just a simple wrapper around
+ * a {@link Binder} that is used to perform the communication. This means
+ * semantically you should treat it as such: this class does not impact process
+ * lifecycle management (you must be using some higher-level component to tell
+ * the system that your process needs to continue running), the connection will
+ * break if your process goes away for any reason, etc.</p>
*/
public class ResultReceiver implements Parcelable {
final boolean mLocal;
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
index 0a44ba2..0da5fb6 100644
--- a/core/java/android/transition/ChangeBounds.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -118,7 +118,7 @@
private void captureValues(TransitionValues values) {
View view = values.view;
- if (view.isLaidOut()) {
+ if (view.isLaidOut() || view.getWidth() != 0 || view.getHeight() != 0) {
values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
view.getRight(), view.getBottom()));
values.values.put(PROPNAME_PARENT, values.view.getParent());
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 78986d9..3770b8a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -250,7 +250,7 @@
// double-lock, but that won't happen if mNativeObject was updated. We can't
// abandon the old mLockedObject because it might still be in use, so instead
// we just refuse to re-lock the Surface.
- throw new IllegalStateException("Surface was already locked");
+ throw new IllegalArgumentException("Surface was already locked");
}
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
@@ -279,9 +279,12 @@
if (mLockedObject == 0) {
throw new IllegalStateException("Surface was not locked");
}
- nativeUnlockCanvasAndPost(mLockedObject, canvas);
- nativeRelease(mLockedObject);
- mLockedObject = 0;
+ try {
+ nativeUnlockCanvasAndPost(mLockedObject, canvas);
+ } finally {
+ nativeRelease(mLockedObject);
+ mLockedObject = 0;
+ }
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b586caa..4116b6b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7106,7 +7106,7 @@
ViewLocationHolder holder = ViewLocationHolder.obtain(parent, child);
holders.add(holder);
}
- Collections.sort(holders);
+ sort(holders);
for (int i = 0; i < childCount; i++) {
ViewLocationHolder holder = holders.get(i);
children.set(i, holder.mView);
@@ -7116,6 +7116,23 @@
}
}
+ private void sort(ArrayList<ViewLocationHolder> holders) {
+ // This is gross but the least risky solution. The current comparison
+ // strategy breaks transitivity but produces very good results. Coming
+ // up with a new strategy requires time which we do not have, so ...
+ try {
+ ViewLocationHolder.setComparisonStrategy(
+ ViewLocationHolder.COMPARISON_STRATEGY_STRIPE);
+ Collections.sort(holders);
+ } catch (IllegalArgumentException iae) {
+ // Note that in practice this occurs extremely rarely in a couple
+ // of pathological cases.
+ ViewLocationHolder.setComparisonStrategy(
+ ViewLocationHolder.COMPARISON_STRATEGY_LOCATION);
+ Collections.sort(holders);
+ }
+ }
+
private void clear() {
mChildren.clear();
}
@@ -7134,6 +7151,12 @@
private static final SynchronizedPool<ViewLocationHolder> sPool =
new SynchronizedPool<ViewLocationHolder>(MAX_POOL_SIZE);
+ public static final int COMPARISON_STRATEGY_STRIPE = 1;
+
+ public static final int COMPARISON_STRATEGY_LOCATION = 2;
+
+ private static int sComparisonStrategy = COMPARISON_STRATEGY_STRIPE;
+
private final Rect mLocation = new Rect();
public View mView;
@@ -7149,6 +7172,10 @@
return holder;
}
+ public static void setComparisonStrategy(int strategy) {
+ sComparisonStrategy = strategy;
+ }
+
public void recycle() {
clear();
sPool.release(this);
@@ -7160,6 +7187,18 @@
if (another == null) {
return 1;
}
+
+ if (sComparisonStrategy == COMPARISON_STRATEGY_STRIPE) {
+ // First is above second.
+ if (mLocation.bottom - another.mLocation.top <= 0) {
+ return -1;
+ }
+ // First is below second.
+ if (mLocation.top - another.mLocation.bottom >= 0) {
+ return 1;
+ }
+ }
+
// We are ordering left-to-right, top-to-bottom.
if (mLayoutDirection == LAYOUT_DIRECTION_LTR) {
final int leftDifference = mLocation.left - another.mLocation.left;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index db8fc6f..7cf3cb5 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1355,9 +1355,10 @@
public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
throw new MustOverrideException();
}
+
/**
* Sets the default text encoding name to use when decoding html pages.
- * The default is "Latin-1".
+ * The default is "UTF-8".
*
* @param encoding the text encoding name
*/
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index a92cb74..e3e5647 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -2159,13 +2159,14 @@
boolean dumpAll, boolean activeOnly) {
long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
mStartTime, now);
+ boolean sepNeeded = false;
if (mSysMemUsageTable != null) {
pw.println("System memory usage:");
dumpSysMemUsage(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
+ sepNeeded = true;
}
ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
boolean printedHeader = false;
- boolean sepNeeded = false;
for (int ip=0; ip<pkgMap.size(); ip++) {
final String pkgName = pkgMap.keyAt(ip);
final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
@@ -2193,6 +2194,7 @@
}
if (NPROCS > 0 || NSRVS > 0) {
if (!printedHeader) {
+ if (sepNeeded) pw.println();
pw.println("Per-Package Stats:");
printedHeader = true;
sepNeeded = true;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 66390d3..6e48351 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -413,7 +413,7 @@
<!-- @hide -->
<permission android:name="android.permission.RECEIVE_BLUETOOTH_MAP"
android:permissionGroup="android.permission-group.MESSAGES"
- android:protectionLevel="dangerous"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_receiveBluetoothMap"
android:description="@string/permdesc_receiveBluetoothMap" />
@@ -1239,7 +1239,7 @@
@hide Pending API council approval -->
<permission android:name="android.permission.READ_PRECISE_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
- android:protectionLevel="dangerous"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_readPrecisePhoneState"
android:description="@string/permdesc_readPrecisePhoneState" />
diff --git a/core/res/res/layout/app_permission_item_money.xml b/core/res/res/layout/app_permission_item_money.xml
index 7e1aca1..2056285 100644
--- a/core/res/res/layout/app_permission_item_money.xml
+++ b/core/res/res/layout/app_permission_item_money.xml
@@ -57,6 +57,8 @@
android:layout_alignParentStart="true"
android:layout_alignBottom="@+id/perm_money_label"
android:scaleType="fitCenter"
+ android:tint="@color/perms_costs_money"
+ android:tintMode="src_in"
android:src="@android:drawable/ic_coins_s" />
<TextView
android:id="@+id/perm_money_label"
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2a75617..60c6416 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -378,8 +378,8 @@
<string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"به برنامه اجازه میدهد پنجرههایی را ایجاد کند که میخواهد توسط رابط کاربر سیستم داخلی استفاده شود. برای استفاده برنامههای عادی نیست."</string>
<string name="permlab_systemAlertWindow" msgid="3543347980839518613">"ترسیم روی برنامههای دیگر"</string>
<string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"به برنامه اجازه میدهد که در بالا یا بخشهایی از رابط کاربری دیگر برنامههای کاربردی متصل شود. این کار میتواند در استفاده شما از رابط هر برنامه کاربردی تداخل ایجاد کند یا آنچه را که به نظر خود در دیگر برنامههای کاربردی میبینید، تغییر دهد."</string>
- <string name="permlab_setAnimationScale" msgid="2805103241153907174">"اصلاح سرعت انیمیشن کلی"</string>
- <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"به برنامه اجازه میدهد سرعت کلی انیمیشن را هر زمان که بخواهد تغییر دهد (انیمیشنهای سریعتر یا آهستهتر)."</string>
+ <string name="permlab_setAnimationScale" msgid="2805103241153907174">"اصلاح سرعت پویانمایی کلی"</string>
+ <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"به برنامه اجازه میدهد سرعت پویانمایی کلی را هر زمان که بخواهد تغییر دهد (پویانماییهای تندتر و کندتر)."</string>
<string name="permlab_manageAppTokens" msgid="1286505717050121370">"مدیریت نشانههای برنامه"</string>
<string name="permdesc_manageAppTokens" msgid="8043431713014395671">"به برنامه اجازه میدهد با ایجاد کنارگذر از سفارش عادی Z، نشانههای خود را ایجاد و مدیریت کند. برای برنامههای عادی مورد نیاز است."</string>
<string name="permlab_freezeScreen" msgid="4708181184441880175">"ثابت نگه داشتن صفحه"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b950781..3928a6a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1261,7 +1261,7 @@
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
<string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
+ <string name="ringtone_silent" msgid="7937634392408977062">"Aucun"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string>
<plurals name="wifi_available">
@@ -1774,7 +1774,7 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Demander le code PIN avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
- <string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement les applications d\'e-mail, de SMS/MMS et les autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque votre appareil est en charge."</string>
+ <string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement vos applications d\'e-mail, de messagerie instantanée et autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque votre appareil est en charge."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Jusqu\'à ce que le temps d\'arrêt se termine à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Pendant une minute"</item>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 461d084..b5e56e2 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -469,8 +469,8 @@
<string name="permdesc_writeSettings" msgid="7775723441558907181">"ऐप्स को सिस्टम सेटिंग डेटा संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके सिस्टम के कॉन्फ़िगरेशन को दूषित कर सकते हैं."</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"सुरक्षित सिस्टम सेटिंग बदलें"</string>
<string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"ऐप्स को सिस्टम के सुरक्षित सेटिंग डेटा को संशोधित करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
- <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं नक्शा बदलें"</string>
- <string name="permdesc_writeGservices" msgid="1287309437638380229">"ऐप्स को Google सेवाओं का नक्शे संशोधित करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
+ <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं मानचित्र बदलें"</string>
+ <string name="permdesc_writeGservices" msgid="1287309437638380229">"ऐप्स को Google सेवाओं का मानचित्र संशोधित करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
<string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"प्रारंभ होने पर चलाएं"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ऐप्स को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः आरंभ करने देता है. इससे टेबलेट को आरंभ होने में अधिक समय लग सकता है और ऐप्स को निरंतर चलाकर संपूर्ण टेबलेट को धीमा करने देता है."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"ऐप्स को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः प्रारंभ होने देता है. इससे फ़ोन को प्रारंभ होने में अधिक समय लग सकता है और ऐप्स के निरंतर चलते रहने से संपूर्ण फ़ोन प्रक्रियाएं धीमी हो सकती हैं."</string>
@@ -666,9 +666,9 @@
<string name="permlab_bluetoothPriv" msgid="4009494246009513828">"एप्लिकेशन के द्वारा ब्लूटूथ युग्मन करने देती है"</string>
<string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"एप्लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्थ डिवाइस के साथ युग्मित करने देती है."</string>
<string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"एप्लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्थ डिवाइस के साथ युग्मित करने देती है."</string>
- <string name="permlab_bluetoothMap" msgid="6372198338939197349">"ब्लूटूथ नक्शा डेटा एक्सेस करें"</string>
- <string name="permdesc_bluetoothMap" product="tablet" msgid="5784090105926959958">"ऐप्स को ब्लूटूथ नक्शा डेटा एक्सेस करने दें."</string>
- <string name="permdesc_bluetoothMap" product="default" msgid="5784090105926959958">"ऐप्स को ब्लूटूथ नक्शा डेटा एक्सेस करने दें."</string>
+ <string name="permlab_bluetoothMap" msgid="6372198338939197349">"ब्लूटूथ मानचित्र डेटा एक्सेस करें"</string>
+ <string name="permdesc_bluetoothMap" product="tablet" msgid="5784090105926959958">"ऐप्स को ब्लूटूथ मानचित्र डेटा एक्सेस करने दें."</string>
+ <string name="permdesc_bluetoothMap" product="default" msgid="5784090105926959958">"ऐप्स को ब्लूटूथ मानचित्र डेटा एक्सेस करने दें."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX से कनेक्ट और डिस्कनेक्ट करें"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ऐप्स को WiMAX सक्षम है या नहीं और कनेक्ट किए गए किसी WiMAX नेटवर्क के बारे में जानकारी निर्धारित करने देता है."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX स्थिति बदलें"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 22f5dff..b00610c 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -68,7 +68,7 @@
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
<string name="ClirMmi" msgid="7784673673446833091">"លេខសម្គាល់អ្នកហៅចេញ"</string>
<string name="ColpMmi" msgid="3065121483740183974">"បានភ្ជាប់លេខសម្គាល់បន្ទាត់"</string>
<string name="ColrMmi" msgid="4996540314421889589">"បានភ្ជាប់ការដាក់កម្រិតលេខសម្គាល់បន្ទាត់"</string>
@@ -127,7 +127,7 @@
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិនបានបញ្ជូនបន្ត"</string>
<string name="fcComplete" msgid="3118848230966886575">"កូដលក្ខណៈពេញលេញ។"</string>
<string name="fcError" msgid="3327560126588500777">"បញ្ហាការតភ្ជាប់ ឬកូដលក្ខណៈមិនត្រឹមត្រូវ។"</string>
- <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
+ <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
<string name="httpError" msgid="7956392511146698522">"មានកំហុសបណ្ដាញ។"</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"រកមិនឃើញ URL ។"</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"គ្រោងការណ៍ផ្ទៀងផ្ទាត់តំបន់បណ្ដាញមិនត្រូវបានគាំទ្រ។"</string>
@@ -185,7 +185,7 @@
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើកសំឡេង"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"ពេលជិះយន្តហោះ"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"បានបើករបៀបពេលជិះយន្តហោះ"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"ការកំណត់"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោឥឡូវនេះ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -198,7 +198,7 @@
<string name="permgrouplab_messages" msgid="7521249148445456662">"សាររបស់អ្នក"</string>
<string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និងសរសេរសារ SMS, អ៊ីមែល និងសារផ្សេងៗទៀតរបស់អ្នក។"</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នក"</string>
- <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
+ <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មានសង្គមរបស់អ្នក"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីទំនាក់ទំនង និងការភ្ជាប់សង្គមរបស់អ្នក។"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំងរបស់អ្នក"</string>
@@ -391,7 +391,7 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យកម្មវិធីមើលគ្រាប់ចុចដែលអ្នកចុចពេលមានអន្តរកម្មជាមួយកម្មវិធីផ្សេង (ដូចជា បញ្ចូលពាក្យសម្ងាត់)។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចងទៅវិធីសាស្ត្របញ្ចូល"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃវិធីសាស្ត្របញ្ចូល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មភាពងាយស្រួល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ចងសេវាកម្មបោះពុម្ព"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -411,7 +411,7 @@
<string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"អនុញ្ញាតឲ្យម្ចាស់គ្រប់គ្រងឃ្លាសម្រាប់ការរកឃើញពាក្យជាសំឡេង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់ទៅការបង្ហាញពីចម្ងាយ"</string>
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃការបង្ហាញពីចម្ងាយ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទងជាមួយអ្នកគ្រប់គ្រងឧបករណ៍"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យម្ចាស់ផ្ញើគោលបំណងទៅអ្នកគ្រប់គ្រងឧបករណ៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -419,7 +419,7 @@
<string name="permdesc_bindTvInput" msgid="2371008331852001924">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតខ្ពស់នៃការបញ្ចូលទូរទស្សន៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_modifyParentalControls" msgid="4611318225997592242">"កែប្រែការត្រួតពិនិត្យមាតាបិតា"</string>
<string name="permdesc_modifyParentalControls" msgid="7438482894162282039">"អនុញ្ញាតឲ្យម្ចាស់កែប្រែទិន្នន័យការត្រួតពិនិត្យមាតាបិតារបស់ប្រព័ន្ធ។ គួរតែមិនត្រូវការសម្រាប់កម្មវិធីធម្មតា។"</string>
- <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
+ <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
<string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាតឲ្យម្ចាស់បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍សកម្មចេញ។ មិនគួរប្រើសម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរទិសអេក្រង់"</string>
<string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យកម្មវិធីប្ដូរការបង្វិលអេក្រង់នៅពេលណាមួយ។ មិនចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -431,9 +431,9 @@
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ឲ្យកម្មវិធីស្នើសញ្ញាដែលបានផ្ដល់ត្រូវផ្ញើទៅដំណើរការស្ថិតស្ថេរទាំងអស់។"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើឲ្យកម្មវិធីដំណើរការជានិច្ច"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យកម្មវិធីធ្វើជាផ្នែកស្ថិតស្ថេរដោយខ្លួនឯងក្នុងអង្គចងចាំ។ វាអាចកំណត់អង្គចងចាំដែលអាចប្រើបានចំពោះកម្មវិធីផ្សេងៗ ដោយធ្វើឲ្យកុំព្យូទ័របន្ទះយឺត។"</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"លុបកម្មវិធី"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។"</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។ "</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"លុបទិន្នន័យរបស់កម្មវិធីផ្សេង"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យកម្មវិធីសម្អាតទិន្នន័យអ្នកប្រើ។"</string>
<string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុបឃ្លាំងសម្ងាត់កម្មវិធីផ្សេងៗ"</string>
@@ -484,7 +484,7 @@
<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងកុំព្យូទ័របន្ទះ រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនងជាក់លាក់។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬបានទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនាក់ជាក់លាក់។ សិទ្ធិនេះឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"អានកំណត់ហេតុហៅ"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យកម្មវិធីអានបញ្ជីហៅទូរស័ព្ទរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរបញ្ជីហៅ"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យកម្មវិធីកែបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នករួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីហៅរបស់អ្នក។"</string>
@@ -624,7 +624,7 @@
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ឲ្យកម្មវិធីកំណត់ជំនួយទំហំផ្ទាំងរូបភាពប្រព័ន្ធ។"</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"កំណត់ប្រព័ន្ធទៅលំនាំដើមរោងចក្រឡើងវិញ"</string>
<string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យកម្មវិធីកំណត់ប្រព័ន្ធដូចការកំណត់ចេញពីរោងចក្រឡើងវិញពេញលេញ ដោយលុបទិន្នន័យ ការកំណត់រចនាសម្ព័ន្ធ និងកម្មវិធីបានដំឡើង។"</string>
- <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
+ <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យកម្មវិធីប្ដូរម៉ោងកុំព្យូទ័របន្ទះ។"</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យកម្មវិធីប្ដូរម៉ោងទូរស័ព្ទ។"</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"កំណត់តំបន់ពេលវេលា"</string>
@@ -801,7 +801,7 @@
<string-array name="organizationTypes">
<item msgid="7546335612189115615">"កន្លែងធ្វើការ"</item>
<item msgid="4378074129049520373">"ផ្សេងៗ"</item>
- <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
+ <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="8595261363518459565">"AIM"</item>
@@ -817,7 +817,7 @@
<string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"ចល័ត"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែងធ្វើការ"</string>
- <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
<string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារផ្ទះ"</string>
<string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
@@ -944,7 +944,7 @@
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ដើម្បីដោះសោ ចូលគណនី Google របស់អ្នក។"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ឈ្មោះអ្នកប្រើ (អ៊ីមែល)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ចូល"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -989,7 +989,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"បានបរាជ័យក្នុងការសាកល្បងរោងចក្រ"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវបានគាំទ្រសម្រាប់តែកញ្ចប់បានដំឡើងក្នុង /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"រកមិនឃើញកញ្ចប់ដែលផ្ដល់សកម្មភាព FACTORY_TEST ។"</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"ទំព័រមានចំណងជើង \"<xliff:g id="TITLE">%s</xliff:g>\" សរសេរ៖"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"បញ្ជាក់ការរុករក"</string>
@@ -1051,7 +1051,7 @@
<string name="prepend_shortcut_label" msgid="2572214461676015642">"ម៉ឺនុយ +"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"ដកឃ្លា"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
- <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
<string name="search_go" msgid="8298016669822141719">"ស្វែងរក"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"ស្វែងរក"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"ស្វែងរកសំណួរ"</string>
@@ -1135,18 +1135,18 @@
<string name="preposition_for_date" msgid="9093949757757445117">"នៅ <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"នៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"ក្នុងឆ្នាំ <xliff:g id="YEAR">%s</xliff:g>"</string>
- <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
+ <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
<string name="days" msgid="4774547661021344602">"ថ្ងៃ"</string>
<string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
<string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
- <string name="minute" msgid="9148878657703769868">"នាទី"</string>
+ <string name="minute" msgid="9148878657703769868">"នាទី"</string>
<string name="minutes" msgid="5646001005827034509">"នាទី"</string>
- <string name="second" msgid="3184235808021478">"វិនាទី"</string>
+ <string name="second" msgid="3184235808021478">"វិនាទី"</string>
<string name="seconds" msgid="3161515347216589235">"វិនាទី"</string>
- <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
- <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
- <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
- <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
+ <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+ <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+ <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+ <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
<plurals name="duration_seconds">
<item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
<item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
@@ -1162,12 +1162,12 @@
<string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហាវីដេអូ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូនេះមិនត្រឹមត្រូវសម្រាប់ចរន្តចូលឧបករណ៍នេះ។"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិនអាចចាក់វីដេអូនេះ។"</string>
- <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
+ <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"រសៀល"</string>
<string name="Noon" msgid="3342127745230013127">"រសៀល"</string>
<string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
- <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
+ <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="6876518925844129331">"ជ្រើសទាំងអស់"</string>
@@ -1184,14 +1184,14 @@
<string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្របញ្ចូល"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាពអត្ថបទ"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់ទំហំផ្ទុក"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"មិនមានទំហំផ្ទុកគ្រប់គ្រាន់សម្រាប់ប្រព័ន្ធ។ សូមប្រាកដថាអ្នកមានទំហំទំនេរ 250MB ហើយចាប់ផ្ដើមឡើងវិញ។"</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការ"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"ប៉ះ ដើម្បីមើលព័ត៌មានបន្ថែម ឬបញ្ឈប់កម្មវិធី។"</string>
- <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
- <string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
- <string name="yes" msgid="5362982303337969312">"យល់ព្រម"</string>
- <string name="no" msgid="5141531044935541497">"បោះបង់"</string>
+ <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
+ <string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
+ <string name="yes" msgid="5362982303337969312">"យល់ព្រម"</string>
+ <string name="no" msgid="5141531044935541497">"បោះបង់"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"ប្រយ័ត្ន"</string>
<string name="loading" msgid="7933681260296021180">"កំពុងផ្ទុក..."</string>
<string name="capital_on" msgid="1544682755514494298">"បើក"</string>
@@ -1211,7 +1211,7 @@
<string name="alwaysUse" msgid="4583018368000610438">"ប្រើតាមលំនាំដើមសម្រាប់សកម្មភាពនេះ។"</string>
<string name="use_a_different_app" msgid="8134926230585710243">"ប្រើកម្មវិធីផ្សេង"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាតលំនាំដើមក្នុងការកំណត់ប្រព័ន្ធ > កម្មវិធី > ទាញយក។"</string>
- <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើសកម្មវិធីសម្រាប់ឧបករណ៍យូអេសប៊ី"</string>
<string name="noApplications" msgid="2991814273936504689">"គ្មានកម្មវិធីអាចអនុវត្តសកម្មភាពនេះ។"</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
@@ -1222,7 +1222,7 @@
<string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
<string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិនឆ្លើយតប។ តើអ្នកចង់បិទវា?"</string>
<string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិនឆ្លើយតប។ \n\nតើអ្នកចង់បិទវាឬ?"</string>
- <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
+ <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
<string name="report" msgid="4060218260984795706">"រាយការណ៍"</string>
<string name="wait" msgid="7147118217226317732">"រង់ចាំ"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"ទំព័រក្លាយជាមិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
@@ -1304,7 +1304,7 @@
<string name="sms_short_code_details" msgid="5873295990846059400">"វា "<b>"អាចគិតលុយ"</b>" លើគណនីចល័តរបស់អ្នក។"</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"វានឹងគិតលុយគណនីចល័តរបស់អ្នក។"</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ផ្ញើ"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ចងចាំជម្រើសរបស់ខ្ញុំ"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"អ្នកអាចប្ដូរវាពេលក្រោយក្នុងការកំណត់ > កម្មវិធី"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាតជានិច្ច"</string>
@@ -1315,8 +1315,8 @@
<string name="sim_added_title" msgid="3719670512889674693">"បានបន្ថែមស៊ីមកាត"</string>
<string name="sim_added_message" msgid="7797975656153714319">"ចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ ដើម្បីចូលប្រើបណ្ដាញចល័ត។"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើមឡើងវិញ"</string>
- <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
- <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
+ <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
+ <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
<string name="date_time_set" msgid="5777075614321087758">"កំណត់"</string>
<string name="date_time_done" msgid="2507683751759308828">"រួចរាល់"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"ថ្មី៖ "</font></string>
@@ -1394,7 +1394,7 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យកម្មវិធីដកសេវាកម្មនៃកម្មវិធីផ្ទុកលំនាំដើម ដើម្បីចម្លងមាតិកា។ មិនសម្រាប់ប្រើដោយកម្មវិធីលំនាំដើម។"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"នាំផ្លូវលទ្ធផលមេឌៀ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យកម្មវិធីនាំផ្លូវលទ្ធផលមេឌៀទៅឧបករណ៍ខាងក្រៅផ្សេង។"</string>
- <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យកម្មវិធីចូលការផ្ទុកមានសុវត្ថិភាព keguard ។"</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យការបង្ហាញ និងលាក់ការការពារ"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យកម្មវិធីគ្រប់គ្រង keguard ។"</string>
@@ -1417,7 +1417,7 @@
<string name="ime_action_go" msgid="8320845651737369027">"ទៅ"</string>
<string name="ime_action_search" msgid="658110271822807811">"ស្វែងរក"</string>
<string name="ime_action_send" msgid="2316166556349314424">"ផ្ញើ"</string>
- <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
<string name="ime_action_done" msgid="8971516117910934605">"រួចរាល់"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"មុន"</string>
<string name="ime_action_default" msgid="2840921885558045721">"អនុវត្ត"</string>
@@ -1426,7 +1426,7 @@
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធីមួយ ឬច្រើនដូចខាងក្រោមស្នើសិទ្ធិ ដើម្បីចូលគណនីរបស់អ្នកឥឡូវ និងពេលអនាគត។"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"តើអ្នកចង់អនុញ្ញាតសំណើនេះ?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"ស្នើចូល"</string>
- <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
+ <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
<string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"បានស្នើសិទ្ធិ"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"បានស្នើសិទ្ធិ\nសម្រាប់គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</string>
@@ -1451,12 +1451,12 @@
<string name="no_file_chosen" msgid="6363648562170759465">"គ្មានឯកសារបានជ្រើស"</string>
<string name="reset" msgid="2448168080964209908">"កំណត់ឡើងវិញ"</string>
<string name="submit" msgid="1602335572089911941">"ដាក់ស្នើ"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ប៉ះ ដើម្បីចេញពីរបៀបរថយន្ត។"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ ដើម្បីរៀបចំ។"</string>
<string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
- <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
<string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
<string name="no_matches" msgid="8129421908915840737">"គ្មានការផ្គូផ្គង"</string>
<string name="find_on_page" msgid="1946799233822820384">"រកក្នុងទំព័រ"</string>
@@ -1478,7 +1478,7 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍ផ្ទុកយូអេសប៊ីបច្ចុប្បន្នកំពុងប្រើដោយកុំព្យូទ័រ។"</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្នកាតអេសឌីកំពុងប្រើដោយកុំព្យូទ័រ"</string>
<string name="media_unknown_state" msgid="729192782197290385">"មិនស្គាល់ស្ថានភាពមេឌៀខាងក្រៅ។"</string>
- <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
+ <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
<string name="find" msgid="4808270900322985960">"រក"</string>
<string name="websearch" msgid="4337157977400211589">"ស្វែងរកតាមបណ្ដាញ"</string>
<string name="find_next" msgid="5742124618942193978">"រកបន្ទាប់"</string>
@@ -1494,7 +1494,7 @@
<string name="sync_undo_deletes" msgid="2941317360600338602">"មិនធ្វើការលុបវិញ"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"មិនធ្វើអ្វីទេឥឡូវ"</string>
<string name="choose_account_label" msgid="5655203089746423927">"ជ្រើសគណនី"</string>
- <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែមគណនី"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
<string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
@@ -1513,15 +1513,15 @@
<string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើនឆ្នាំ"</string>
<string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយឆ្នាំ"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"មិនអាចចាប់ផ្ដើម <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែករំលែកជាមួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រងការរុញ។ ប៉ះ & សង្កត់។"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស ដើម្បីដោះសោ។"</string>
@@ -1535,7 +1535,7 @@
<string name="storage_internal" msgid="4891916833657929263">"ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"កាតអេសឌី"</string>
<string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍ផ្ទុកយូអេសប៊ី"</string>
- <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមានប្រើទិន្នន័យ"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បីមើលការប្រើ និងការកំណត់។"</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"បានដល់ដែនកំណត់ទិន្នន័យ 2G-3G"</string>
@@ -1593,7 +1593,7 @@
<string name="media_route_status_available" msgid="6983258067194649391">"ទំនេរ"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"មិនទំនេរ"</string>
<string name="media_route_status_in_use" msgid="4533786031090198063">"កំពុងប្រើ"</string>
- <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
+ <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"អេក្រង់ HDMI"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួតគ្នា"</string>
<string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
@@ -1620,7 +1620,7 @@
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -1730,7 +1730,7 @@
<string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
<string name="mediasize_unknown_portrait" msgid="3088043641616409762">"មិនស្គាល់បញ្ឈរ"</string>
<string name="mediasize_unknown_landscape" msgid="4876995327029361552">"មិនស្គាល់ទេសភាព"</string>
- <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
+ <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុសក្នុងការសរសេរមាតិកា"</string>
<string name="reason_unknown" msgid="6048913880184628119">"មិនស្គាល់"</string>
<string name="reason_service_unavailable" msgid="7824008732243903268">"មិនបានបើកសេវាកម្មបោះពុម្ព"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 982e75c..ed673c2 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1740,7 +1740,7 @@
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະຈຸບັນ"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</string>
- <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ບໍ່ກົງກັນ. ລອງໃໝ່ອີກຄັ້ງ."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ສັ້ນເກີນໄປ. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ."</string>
<plurals name="restr_pin_countdown">
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index af899ad..45a803e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -436,15 +436,15 @@
<string name="permdesc_deletePackages" msgid="7411480275167205081">"Приложение сможет удалять пакеты Android. Вредоносные программы смогут таким образом удалять важные программы."</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"Удаление данных других приложений"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Приложение сможет удалять пользовательские данные."</string>
- <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"Удаление данных из кэш-памяти других приложений"</string>
- <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Приложение сможет удалять файлы из кэша."</string>
+ <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"Удаление данных из кеш-памяти других приложений"</string>
+ <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Приложение сможет удалять файлы из кеша."</string>
<string name="permlab_getPackageSize" msgid="7472921768357981986">"Вычисление объема памяти приложений"</string>
- <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Приложение сможет получать сведения о размере кода, данных и кэша."</string>
+ <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Приложение сможет получать сведения о размере кода, данных и кеша."</string>
<string name="permlab_installPackages" msgid="2199128482820306924">"Прямая установка приложений"</string>
<string name="permdesc_installPackages" msgid="5628530972548071284">"Приложение сможет устанавливать новые или обновленные пакеты Android. Вредоносные программы смогут таким образом добавлять новые программы с любыми разрешениями."</string>
- <string name="permlab_clearAppCache" msgid="7487279391723526815">"Очистка кэша приложений"</string>
- <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Разрешает приложению освобождать место на планшетном ПК, удаляя кэшированные файлы других программ. В результате другие приложения могут запускаться медленнее, так как им потребуется повторно извлекать необходимые данные."</string>
- <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Разрешает приложению освобождать место на телефоне, удаляя кэшированные файлы других программ. В результате другие приложения могут запускаться медленнее, так как им потребуется повторно извлекать необходимые данные."</string>
+ <string name="permlab_clearAppCache" msgid="7487279391723526815">"Очистка кеша приложений"</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Разрешает приложению освобождать место на планшетном ПК, удаляя кешированные файлы других программ. В результате другие приложения могут запускаться медленнее, так как им потребуется повторно извлекать необходимые данные."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Разрешает приложению освобождать место на телефоне, удаляя кешированные файлы других программ. В результате другие приложения могут запускаться медленнее, так как им потребуется повторно извлекать необходимые данные."</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"Перемещение ресурсов приложения"</string>
<string name="permdesc_movePackage" msgid="319562217778244524">"Приложение сможет перемещать ресурсы из внутреннего накопителя на внешний и наоборот."</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"Просмотр конфиденциальных данных в журнале"</string>
@@ -712,8 +712,8 @@
<string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Приложение сможет управлять хранением документов."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Доступ к внешним накопителям из всех аккаунтов"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Приложение сможет обращаться к внешним накопителям из всех аккаунтов."</string>
- <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Доступ к файловой системе кэша"</string>
- <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Приложение сможет выполнять чтение и запись в файловую систему кэша."</string>
+ <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Доступ к файловой системе кеша"</string>
+ <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Приложение сможет выполнять чтение и запись в файловую систему кеша."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"Входящие и исходящие вызовы SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Разрешить вызовы по протоколу SIP."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Управление экраном во время разговора"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b8f6126..a7ea2e5 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -834,7 +834,7 @@
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Роб. пейджер"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Помічник"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
- <string name="eventTypeCustom" msgid="7837586198458073404">"Спеціальні"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"Указати"</string>
<string name="eventTypeBirthday" msgid="2813379844211390740">"День нар."</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Річниця"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"Інші"</string>
@@ -864,7 +864,7 @@
<string name="orgTypeWork" msgid="29268870505363872">"Роб."</string>
<string name="orgTypeOther" msgid="3951781131570124082">"Інше"</string>
<string name="orgTypeCustom" msgid="225523415372088322">"Указати"</string>
- <string name="relationTypeCustom" msgid="3542403679827297300">"Спеціальні"</string>
+ <string name="relationTypeCustom" msgid="3542403679827297300">"Указати"</string>
<string name="relationTypeAssistant" msgid="6274334825195379076">"Помічник"</string>
<string name="relationTypeBrother" msgid="8757913506784067713">"Брат"</string>
<string name="relationTypeChild" msgid="1890746277276881626">"Дитина"</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index cbaf54f..235bf84 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -85,7 +85,7 @@
<color name="perms_dangerous_grp_color">#33b5e5</color>
<color name="perms_dangerous_perm_color">#33b5e5</color>
<color name="shadow">#cc222222</color>
- <color name="perms_costs_money">#ffffbb33</color>
+ <color name="perms_costs_money">#fff4511e</color>
<!-- For search-related UIs -->
<color name="search_url_text_normal">#7fa87f</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b45237b..a0ac3af 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1779,9 +1779,6 @@
<string-array translatable="false" name="config_cdma_home_system" />
- <!-- Default text encoding for WebSettings. @hide @SystemApi -->
- <string name="config_webSettingsDefaultTextEncoding">UTF-8</string>
-
<!--From SmsMessage-->
<!--Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
string that's stored in 8-bit unpacked format) characters.-->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8ebcd6d..7568252 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2545,8 +2545,6 @@
<!-- @hide This really shouldn't be public; clients using it should use @* to ref it. -->
<public type="style" name="Theme.Leanback.FormWizard" id="0x010302d0" />
- <public type="string" name="config_webSettingsDefaultTextEncoding" id="0x01040018" />
-
<public type="array" name="config_keySystemUuidMapping" id="0x01070005" />
<!-- An interpolator which accelerates fast but decelerates slowly. -->
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 04bc67a..09055c6 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -70,10 +70,15 @@
<family name="monospace">
<font weight="400" style="normal">DroidSansMono.ttf</font>
</family>
- <alias name="courier" to="monospace" />
- <alias name="courier new" to="monospace" />
+ <alias name="sans-serif-monospace" to="monospace" />
<alias name="monaco" to="monospace" />
+ <family name="serif-monospace">
+ <font weight="400" style="normal">CutiveMono.ttf</font>
+ </family>
+ <alias name="courier" to="serif-monospace" />
+ <alias name="courier new" to="serif-monospace" />
+
<family name="casual">
<font weight="400" style="normal">ComingSoon.ttf</font>
</family>
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
index 8c59fea..2a48faa 100644
--- a/data/fonts/system_fonts.xml
+++ b/data/fonts/system_fonts.xml
@@ -129,8 +129,7 @@
<family>
<nameset>
<name>monospace</name>
- <name>courier</name>
- <name>courier new</name>
+ <name>sans-serif-monospace</name>
<name>monaco</name>
</nameset>
<fileset>
@@ -140,6 +139,17 @@
<family>
<nameset>
+ <name>serif-monospace</name>
+ <name>courier</name>
+ <name>courier new</name>
+ </nameset>
+ <fileset>
+ <file>CutiveMono.ttf</file>
+ </fileset>
+ </family>
+
+ <family>
+ <nameset>
<name>casual</name>
</nameset>
<fileset>
diff --git a/docs/html/design/design_toc.cs b/docs/html/design/design_toc.cs
index 885f336..1a6ee7a 100644
--- a/docs/html/design/design_toc.cs
+++ b/docs/html/design/design_toc.cs
@@ -23,7 +23,15 @@
<li><a href="<?cs var:toroot ?>design/wear/style.html">Style</a></li>
</ul>
</li>
- <li><a href="<?cs var:toroot ?>design/tv/index.html">TV</a></li>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>design/tv/index.html">TV</a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>design/tv/principles.html">Creative Vision</a></li>
+ <li><a href="<?cs var:toroot ?>design/tv/patterns.html">UI Patterns</a></li>
+ <li><a href="<?cs var:toroot ?>design/tv/style.html">Style</a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>design/auto/index.html">Auto</a></li>
</ul>
</li>
diff --git a/docs/html/preview/tv/design/images/apps-games-rows.jpg b/docs/html/design/tv/images/apps-games-rows.jpg
similarity index 100%
rename from docs/html/preview/tv/design/images/apps-games-rows.jpg
rename to docs/html/design/tv/images/apps-games-rows.jpg
Binary files differ
diff --git a/docs/html/preview/tv/design/images/atv-framed-med.png b/docs/html/design/tv/images/atv-framed-med.png
similarity index 100%
rename from docs/html/preview/tv/design/images/atv-framed-med.png
rename to docs/html/design/tv/images/atv-framed-med.png
Binary files differ
diff --git a/docs/html/preview/tv/design/images/atv-home.jpg b/docs/html/design/tv/images/atv-home.jpg
similarity index 100%
rename from docs/html/preview/tv/design/images/atv-home.jpg
rename to docs/html/design/tv/images/atv-home.jpg
Binary files differ
diff --git a/docs/html/preview/tv/design/images/focus.png b/docs/html/design/tv/images/focus.png
similarity index 100%
rename from docs/html/preview/tv/design/images/focus.png
rename to docs/html/design/tv/images/focus.png
Binary files differ
diff --git a/docs/html/preview/tv/design/images/icon.png b/docs/html/design/tv/images/icon.png
similarity index 100%
rename from docs/html/preview/tv/design/images/icon.png
rename to docs/html/design/tv/images/icon.png
Binary files differ
diff --git a/docs/html/preview/tv/design/images/overscan.png b/docs/html/design/tv/images/overscan.png
similarity index 100%
rename from docs/html/preview/tv/design/images/overscan.png
rename to docs/html/design/tv/images/overscan.png
Binary files differ
diff --git a/docs/html/preview/tv/design/images/recommendations.png b/docs/html/design/tv/images/recommendations.png
similarity index 100%
rename from docs/html/preview/tv/design/images/recommendations.png
rename to docs/html/design/tv/images/recommendations.png
Binary files differ
diff --git a/docs/html/preview/tv/design/images/search.jpg b/docs/html/design/tv/images/search.jpg
similarity index 100%
rename from docs/html/preview/tv/design/images/search.jpg
rename to docs/html/design/tv/images/search.jpg
Binary files differ
diff --git a/docs/html/preview/tv/design/images/settings.jpg b/docs/html/design/tv/images/settings.jpg
similarity index 100%
rename from docs/html/preview/tv/design/images/settings.jpg
rename to docs/html/design/tv/images/settings.jpg
Binary files differ
diff --git a/docs/html/design/tv/index.jd b/docs/html/design/tv/index.jd
index d144ff01..483c24f 100644
--- a/docs/html/design/tv/index.jd
+++ b/docs/html/design/tv/index.jd
@@ -2,14 +2,67 @@
@jd:body
-<img src="{@docRoot}design/media/android-tv.png"
- width="460" style="float:right;margin:0 0 40px 40px" />
+<p>The Android TV platform user interface provides the launch pad for your app's big screen
+ experience. It's important to understand how your app is presented in the main user interface and
+ how your app can help users get to the content they want quickly.</p>
+
+<p class="note">
+ <strong>Important:</strong> There are specific design requirements your app must meet to qualify
+ as an Android TV app on Google Play. For more information, see the requirements listed in
+ <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
+</p>
+
+<h2>Home Screen</h2>
+
+<p>The Home Screen is the start of the user experience, providing search, content
+ recommendations, and access to apps and settings. This screen provides a rich and cinematic
+ overview of apps and content.</p>
+
+<img src="{@docRoot}design/tv/images/atv-home.jpg" alt="TV Home screen" />
-<p>Android TV is <strong>coming soon</strong> and lets you engage your users in a new, shared environment.</p>
+<h2>Search</h2>
-<p>Users bring a specific set of expectations to the experience of watching TV, versus interacting
-with a phone or tablet. So find out how to get your app ready for its big-screen debut
-later this year by reading the
-<a href="{@docRoot}preview/tv/design/index.html">Android TV Design Guide</a>
-in the L Developer Preview.</p>
\ No newline at end of file
+<p>By bringing the power of Google search to the big screen, Android TV makes new, dynamic
+ connections between content. A favorite movie may lead to the discovery of a new music artist;
+ planning a trip to Paris might surface new YouTube content and photos.</p>
+
+<img src="{@docRoot}design/tv/images/search.jpg" alt="Recommendations Row" />
+
+<p>To learn more about searching within your app, see
+ <a href="{@docRoot}training/tv/discovery/in-app-search.html">Searching within TV Apps</a>.
+
+<h2>Recommendations</h2>
+
+<p>The recommendations row on Android TV is a central feature of the Home Screen that allows
+ users quick access to dynamic and relevant content for their media-consumption activities. The
+ row is optimized for quick browsing of personalized content and activity resumption (on the
+ device and across devices), while also providing a way for users to act on meaningful new
+ content.</p>
+
+<img src="{@docRoot}design/tv/images/recommendations.png" alt="Recommendations Row" />
+
+<p>
+ Recommendations are based on the user’s recent and frequent usage behaviors, as well as
+ expressed content preferences. They appear as cards that represent a system or app action,
+ notification, activity, or piece of actionable media. Your app can provide suggestions for the
+ recommendations row to help get your content noticed. To learn more, see
+ <a href="{@docRoot}training/tv/discovery/recommendations.html">Recommending TV Content</a>.
+</p>
+
+
+<h2>Apps and Games</h2>
+
+<p>Apps and Games rows both have special areas on the Home Screen. Within their respective
+ areas, Apps and Games titles are ordered to reflect the user’s recent usage.</p>
+
+<img src="{@docRoot}design/tv/images/apps-games-rows.jpg" alt="Apps and Games Rows" />
+
+
+<h2>Settings</h2>
+
+<p>Users can access Android and device-specific settings from the bottom of the Home Screen. From
+ here, the user can access Android and device-specific settings.
+</p>
+
+<img src="{@docRoot}design/tv/images/settings.jpg" alt="Settings Row" />
diff --git a/docs/html/preview/tv/design/patterns.jd b/docs/html/design/tv/patterns.jd
similarity index 71%
rename from docs/html/preview/tv/design/patterns.jd
rename to docs/html/design/tv/patterns.jd
index 48faee9..51bb699 100644
--- a/docs/html/preview/tv/design/patterns.jd
+++ b/docs/html/design/tv/patterns.jd
@@ -1,7 +1,7 @@
-page.title=Patterns for TV
-page.tags="design"
+page.title=UI Patterns for TV
@jd:body
+
<p>As a developer of apps for TV, you should follow certain patterns to enable users to
quickly understand and operate your app. This section describes recommended design patterns
for TV apps.</p>
@@ -13,7 +13,7 @@
user interface has clear paths for two-axis navigation by aligning objects in lists and
grids.</p>
-<img src="{@docRoot}preview/tv/design/images/focus.png" alt="TV navigation and focus diagram" />
+<img src="{@docRoot}design/tv/images/focus.png" alt="TV navigation and focus diagram" />
<p>A key aspect of making your application work well with a D-Pad controller is to make sure
that there is always an object that is obviously in focus. Your app must clearly indicate
@@ -47,7 +47,7 @@
<p>Recommendation cards include a small icon that is imposed over a colored background.
An example and specifications for this icon are shown below:</p>
-<img src="{@docRoot}preview/tv/design/images/icon.png" alt="Recommendation icon examples" />
+<img src="{@docRoot}design/tv/images/icon.png" alt="Recommendation icon examples" />
<p>Here are the requirements for recommendation icons:</p>
@@ -65,16 +65,20 @@
<h2>Background Images</h2>
<p>Background images are displayed in the background of your app to provide additional visual
- interest, information, or branding. The BrowseFragment and DetailsFragment classes in the Leanback
- support library provide specific support for background images and for updating them as items gain
- and lose focus. Here are the specific requirements for background images:</p>
+ interest, information, or branding. The user interface widgets provided in the <a href="{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support
+ library</a> provide specific support for background images and for updating them as items gain
+ and lose focus. The specific requirements for background images on TV devices is that they
+ should be full color and a size of 1920 x 1080 pixels.
+</p>
-<ul>
- <li>Full color, 1920 x 1080 pixels</li>
-</ul>
+<p class="note" id="solid-background">
+ <strong>Important:</strong> Background images must not be transparent. Your must not allow any
+ portion of another app to be seen through your app.
+</p>
<p class="note">
- <strong>Note:</strong> If the image does not meet this requirement, it is scaled to fit.
+ <strong>Note:</strong> If you background image does not meet the size requirements, it is scaled
+ to fit.
</p>
<h2>Audio Feedback</h2>
@@ -82,5 +86,6 @@
<p>Sounds on Android TV bring a cinematic quality to the interaction experience. You should
consider adding sounds for user actions or to provide feedback when a user is only partially
visually engaged with the screen (e.g., because they are distracted or multitasking).
- You should also consider using sounds as alternatives to visual messages, for example to indicate
- that a user has reached the end of a list or is trying to navigate to an undefined location.</p>
+ You should also consider using sounds as alternatives to visual messages. For example, use sounds
+ to indicate that a user has reached the end of a list or is trying to navigate to an undefined
+ location.</p>
diff --git a/docs/html/preview/tv/design/principles.jd b/docs/html/design/tv/principles.jd
similarity index 87%
rename from docs/html/preview/tv/design/principles.jd
rename to docs/html/design/tv/principles.jd
index 106fa96..c2f5fc9 100644
--- a/docs/html/preview/tv/design/principles.jd
+++ b/docs/html/design/tv/principles.jd
@@ -1,9 +1,12 @@
page.title=Creative Vision for TV
@jd:body
-<p>Users bring a specific set of expectations when watching TV, versus
- interacting with a phone or tablet. These guidelines have been developed by the Android User
- Experience Team to guide creation of the Android TV platform and the apps that run on it.</p>
+
+<p>Users bring a specific set of expectations when watching TV, versus interacting with a phone or
+ tablet. The Android User Experience Team has developed the following guidelines for creation of
+ the Android TV platform and the apps that run on it.
+</p>
+
<h2>Casual Consumption</h2>
diff --git a/docs/html/preview/tv/design/style.jd b/docs/html/design/tv/style.jd
similarity index 86%
rename from docs/html/preview/tv/design/style.jd
rename to docs/html/design/tv/style.jd
index 67a7096..6e2704b 100644
--- a/docs/html/preview/tv/design/style.jd
+++ b/docs/html/design/tv/style.jd
@@ -1,5 +1,4 @@
page.title=Style for TV
-page.tags="design"
@jd:body
@@ -19,9 +18,10 @@
</p>
<p>If you are creating an app for browsing and playing content, use the prebuilt fragments in the
- Leanback support library. These layouts have been built specifically for use on TV devices with
+ <a href="{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support
+ library</a>. These layouts have been built specifically for use on TV devices with
the guidance of the Android User Experience team. For more information on using these classes,
- see the <a href="{@docRoot}preview/tv/build-ui/index.html">User Interfaces</a> guide.
+ see the <a href="{@docRoot}training/tv/index.html">Building Apps for TV</a> training.
</p>
<p>Here are some additional recommendations for creating functional and attractive layouts for TV
@@ -33,8 +33,12 @@
<li>Design your artwork assets for best viewing at HD resolution (1920 x 1080 pixels).</li>
<li>Put on-screen navigational controls on the left or right side of the screen, and
save the vertical space for content.</li>
- <li>Use Fragments to create UIs that are divided into sections, and use view groups
- like GridView instead of ListView to make better use of the horizontal screen space.</li>
+ <li>Use <a href="{@docRoot}guide/components/fragments.html">fragments</a> to create UIs that are
+ divided into sections, and use view groups like <a href=
+ "{@docRoot}guide/topics/ui/layout/gridview.html">Grid View</a> instead of <a href=
+ "{@docRoot}guide/topics/ui/layout/listview.html">List View</a> to make better use of the
+ horizontal screen space.
+ </li>
<li>Avoid a cluttered interface by adding sufficient margins between layout controls.</li>
</ul>
@@ -45,7 +49,7 @@
outside of a safe zone that most TVs could reliably display. Even on some of today’s HDTV flat
screens, areas outside that zone may not be visible.</p>
-<img src="{@docRoot}preview/tv/design/images/overscan.png" alt="Overscan borders for TV" />
+<img src="{@docRoot}design/tv/images/overscan.png" alt="Overscan borders for TV" />
<p>Build a 10% margin into your TV screen designs to account for overscan area the TV may not
display correctly. On a 1920 x 1080 pixel screen, this margin should be a minimum of 27px from the
diff --git a/docs/html/preview/license.jd b/docs/html/preview/license.jd
new file mode 100644
index 0000000..5ff52ba
--- /dev/null
+++ b/docs/html/preview/license.jd
@@ -0,0 +1,143 @@
+page.title=License Agreement
+
+@jd:body
+
+<p>
+To get started with the Android SDK Preview, you must agree to the following terms and conditions.
+As described below, please note that this is a preview version of the Android SDK, subject to change, that you use at your own risk. The Android SDK Preview is not a stable release, and may contain errors and defects that can result in serious damage to your computer systems, devices and data.
+</p>
+
+<p>
+This is the Android SDK Preview License Agreement (the “License Agreement”).
+</p>
+<div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px">
+1. Introduction
+
+1.1 The Android SDK Preview (referred to in the License Agreement as the “Preview” and specifically including the Android system files, packaged APIs, and Preview library files, if and when they are made available) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the Preview.
+
+1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
+
+1.3 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+
+2. Accepting the License Agreement
+
+2.1 In order to use the Preview, you must first agree to the License Agreement. You may not use the Preview if you do not accept the License Agreement.
+
+2.2 By clicking to accept and/or using the Preview, you hereby agree to the terms of the License Agreement.
+
+2.3 You may not use the Preview and may not accept the License Agreement if you are a person barred from receiving the Preview under the laws of the United States or other countries including the country in which you are resident or from which you use the Preview.
+
+2.4 If you will use the Preview internally within your company or organization you agree to be bound by the License Agreement on behalf of your employer or other entity, and you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the Preview on behalf of your employer or other entity.
+
+3. Preview License from Google
+
+3.1 Subject to the terms of the License Agreement, Google grants you a royalty-free, non-assignable, non-exclusive, non-sublicensable, limited, revocable license to use the Preview, personally or internally within your company or organization, solely to develop applications to run on the Android platform.
+
+3.2 You agree that Google or third parties owns all legal right, title and interest in and to the Preview, including any Intellectual Property Rights that subsist in the Preview. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
+
+3.3 You may not use the Preview for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the Preview or any part of the Preview; or (b) load any part of the Preview onto a mobile handset or any other hardware device except a personal computer, combine any part of the Preview with other software, or distribute any software or device incorporating a part of the Preview.
+
+3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the Preview.
+
+3.5 Use, reproduction and distribution of components of the Preview licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement. You agree to remain a licensee in good standing in regard to such open source software licenses under all the rights granted and to refrain from any actions that may terminate, suspend, or breach such rights.
+
+3.6 You agree that the form and nature of the Preview that Google provides may change without prior notice to you and that future versions of the Preview may be incompatible with applications developed on previous versions of the Preview. You agree that Google may stop (permanently or temporarily) providing the Preview (or any features within the Preview) to you or to users generally at Google's sole discretion, without prior notice to you.
+
+3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
+
+3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the Preview.
+
+4. Use of the Preview by You
+
+4.1 Google agrees that nothing in the License Agreement gives Google any right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the Preview, including any intellectual property rights that subsist in those applications.
+
+4.2 You agree to use the Preview and write applications only for purposes that are permitted by (a) the License Agreement, and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
+
+4.3 You agree that if you use the Preview to develop applications, you will protect the privacy and legal rights of users. If users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If users provide you with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, each user has given you permission to do so.
+
+4.4 You agree that you will not engage in any activity with the Preview, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of Google or any third party.
+
+4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
+
+4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
+
+4.7 The Preview is in development, and your testing and feedback are an important part of the development process. By using the Preview, you acknowledge that implementation of some features are still under development and that you should not rely on the Preview having the full functionality of a stable release. You agree not to publicly distribute or ship any application using this Preview as this Preview will no longer be supported after the official Android SDK is released.
+
+5. Your Developer Credentials
+
+5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
+
+6. Privacy and Information
+
+6.1 In order to continually innovate and improve the Preview, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the Preview are being used and how they are being used. Before any of this information is collected, the Preview will notify you and seek your consent. If you withhold consent, the information will not be collected.
+
+6.2 The data collected is examined in the aggregate to improve the Preview and is maintained in accordance with Google's Privacy Policy located at http://www.google.com/policies/privacy/.
+
+7. Third Party Applications
+
+7.1 If you use the Preview to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
+
+7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
+
+7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party.
+
+8. Using Google APIs
+
+8.1 Google APIs
+
+8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
+
+8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
+
+9. Terminating the License Agreement
+
+9.1 the License Agreement will continue to apply until terminated by either you or Google as set out below.
+
+9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the Preview and any relevant developer credentials.
+
+9.3 Google may at any time, terminate the License Agreement, with or without cause, upon notice to you.
+
+9.4 The License Agreement will automatically terminate without notice or other action upon the earlier of:
+(A) when Google ceases to provide the Preview or certain parts of the Preview to users in the country in which you are resident or from which you use the service; and
+(B) Google issues a final release version of the Android SDK.
+
+9.5 When the License Agreement is terminated, the license granted to you in the License Agreement will terminate, you will immediately cease all use of the Preview, and the provisions of paragraphs 10, 11, 12 and 14 shall survive indefinitely.
+
+10. DISCLAIMERS
+
+10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE PREVIEW IS AT YOUR SOLE RISK AND THAT THE PREVIEW IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+
+10.2 YOUR USE OF THE PREVIEW AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE PREVIEW IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE. WITHOUT LIMITING THE FOREGOING, YOU UNDERSTAND THAT THE PREVIEW IS NOT A STABLE RELEASE AND MAY CONTAIN ERRORS, DEFECTS AND SECURITY VULNERABILITIES THAT CAN RESULT IN SIGNIFICANT DAMAGE, INCLUDING THE COMPLETE, IRRECOVERABLE LOSS OF USE OF YOUR COMPUTER SYSTEM OR OTHER DEVICE.
+
+10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+
+11. LIMITATION OF LIABILITY
+
+11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+
+12. Indemnification
+
+12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys’ fees) arising out of or accruing from (a) your use of the Preview, (b) any application you develop on the Preview that infringes any Intellectual Property Rights of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you of the License Agreement.
+
+13. Changes to the License Agreement
+
+13.1 Google may make changes to the License Agreement as it distributes new versions of the Preview. When these changes are made, Google will make a new version of the License Agreement available on the website where the Preview is made available.
+
+14. General Legal Terms
+
+14.1 the License Agreement constitutes the whole legal agreement between you and Google and governs your use of the Preview (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the Preview.
+
+14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
+
+14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.
+
+14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.
+
+14.5 EXPORT RESTRICTIONS. THE PREVIEW IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE PREVIEW. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+
+14.6 The License Agreement may not be assigned or transferred by you without the prior written approval of Google, and any attempted assignment without such approval will be void. You shall not delegate your responsibilities or obligations under the License Agreement without the prior written approval of Google.
+
+14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+
+
+</div>
\ No newline at end of file
diff --git a/docs/html/preview/preview_toc.cs b/docs/html/preview/preview_toc.cs
index 04f966a..3564b16 100644
--- a/docs/html/preview/preview_toc.cs
+++ b/docs/html/preview/preview_toc.cs
@@ -76,6 +76,8 @@
Hardware Features</a></li>
<li><a href="<?cs var:toroot ?>preview/tv/adt-1/index.html">
ADT-1</a></li>
+ <li><a href="<?cs var:toroot ?>preview/tv/publish/index.html">
+ Publishing TV Apps</a></li>
</ul>
</li>
@@ -96,6 +98,11 @@
<a href="<?cs var:toroot ?>preview/support.html">Support</a>
</div>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header empty">
+ <a href="<?cs var:toroot ?>preview/license.html">License Agreement</a>
+ </div>
+ </li>
<li class="nav-section" style="margin: 20px 0 0 -10px;">
<div class="nav-section-header empty">
<a href="<?cs var:toroot ?>index.html" class="back-link">Developer Home</a>
diff --git a/docs/html/preview/tv/design/index.jd b/docs/html/preview/tv/design/index.jd
deleted file mode 100644
index b924a5c..0000000
--- a/docs/html/preview/tv/design/index.jd
+++ /dev/null
@@ -1,65 +0,0 @@
-page.title=Design for TV
-header.justLinks=1
-footer.hide=1
-@jd:body
-
-
-<p>The Android TV platform user interface provides the launch pad for your app's big screen
- experience. It's important to understand how your app is presented in the main user interface and
- how your app can help users get to the content they want quickly.</p>
-
-
-<h2>Home Screen</h2>
-
-<p>The Home Screen is the start of the user experience, providing search, content
- recommendations, and access to apps and settings. This screen provides a rich and cinematic
- overview of apps and content.</p>
-
-<img src="{@docRoot}preview/tv/design/images/atv-home.jpg" alt="TV Home screen" />
-
-
-<h2>Search</h2>
-
-<p>By bringing the power of Google search to the big screen, Android TV makes new, dynamic
- connections between content. A favorite movie may lead to the discovery of a new music artist,
- planning a trip to Paris might surface new YouTube content and photos.</p>
-
-<img src="{@docRoot}preview/tv/design/images/search.jpg" alt="Recommendations Row" />
-
-<p>To learn more about searching within your app, see
- <a href="{@docRoot}preview/tv/ui/in-app-search.html">Searching in TV Apps</a>.
-
-<h2>Recommendations</h2>
-
-<p>The recommendations row on Android TV is a central feature of the Home Screen that allows
- users quick access to dynamic and relevant content for their media-consumption activities. The
- row is optimized for quick browsing of personalized content and activity resumption (on the
- device and across devices), while also providing a way for users to act on meaningful new
- content.</p>
-
-<img src="{@docRoot}preview/tv/design/images/recommendations.png" alt="Recommendations Row" />
-
-<p>
- Recommendations are based on the user’s recent and frequent usage behaviors, as well as
- expressed content preferences. They appear as cards that represent a system or app action,
- notification, activity, or piece of actionable media. Your app can provide suggestions for the
- recommendations row to help get your content noticed. To learn more, see
- <a href="{@docRoot}preview/tv/ui/recommendations.html">Recommendations</a>.
-</p>
-
-
-<h2>Apps and Games</h2>
-
-<p>Apps and Games rows both have special areas on the Home Screen. Within their respective
- areas, Apps and Games titles are ordered to reflect the user’s recent usage.</p>
-
-<img src="{@docRoot}preview/tv/design/images/apps-games-rows.jpg" alt="Apps and Games Rows" />
-
-
-<h2>Settings</h2>
-
-<p>Access to Settings is found at the bottom of the Home Screen. From here, the user can access
- Android and device-specific settings.
-</p>
-
-<img src="{@docRoot}preview/tv/design/images/settings.jpg" alt="Settings Row" />
diff --git a/docs/html/preview/tv/games/index.jd b/docs/html/preview/tv/games/index.jd
deleted file mode 100644
index 61a26d2c..0000000
--- a/docs/html/preview/tv/games/index.jd
+++ /dev/null
@@ -1,152 +0,0 @@
-ikpage.title=Games on TV
-page.tags="controller"
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#display">Display</li></a></li>
- <li><a href="#control">Input Devices</li></a></li>
- <li><a href="#manifest">Manifest</li></a></li>
- <li><a href="#gpgs">Google Play Game Services</li></a></li>
- <li><a href="#web">Web</a></li>
- </ol>
-</div>
-</div>
-
-<p>The television screen presents a number of considerations that may be new to mobile-game
-developers. These areas include its large size, its control scheme, and the fact that all
-players are viewing it simultaneously.</p>
-
-
-<h2 id=display>Display</h2>
-<p>The two main things to keep in mind when developing games for the TV screen are its nature as a
-shared display and the need to design your game for a landscape orientation.</p>
-<h3>Shared display</h3>
-<p>A living-room TV poses design challenges for multiplayer games, in that all players can see
-everything. This issue is especially relevant to games (such as card games or strategy games) that
-rely on each player’s possession of hidden information.</p>
-<p>Some mechanisms you can implement to address the problem of one player’s eavesdropping
-on another’s information are:</p>
-<ul>
-<li>A blinder on the screen to help conceal information. For example, in a
-turn-based game like a word or card game, one player at a time might view the display. When the
-player finishes a move, the game allows him or her to cover the screen with a blinder that
-blocks anyone from viewing secret information. When the next player begins a turn, the blinder
-opens to reveal his or her own information.</li>
-<li>A companion app, running on a phone or tablet, can enable a player to conceal
-information.</li>
-</ul>
-<h3>Landscape display</h3>
-<p>A TV is always sideways: You can’t turn it, and there is no
-portrait orientation. Always design your TV games to be displayed in landscape
-mode.</p>
-
-<h2 id="control">Input Devices</h2>
-<p>TVs don't have touch interfaces, so it's even more important to get your controls right and make
- sure that players find them intuitive and fun to use. The separation of controller from device also
-introduces some other issues to pay attention to, like keeping track of multiple players'
-controllers, and handling disconnects gracefully.</p>
-<h3>D-pad</h3>
-<p>Plan your control scheme around a directional pad (D-pad) control, since this control set is the
-default for Android TV devices. The player needs to be able to use a D-Pad in all aspects of the
-game–not just controlling core
-gameplay, but also navigating menus and ads. For this reason, you should also ensure that your
-Android TV game does not refer to a touch interface: for example, an Android TV game cannot tell a
-player to <strong>Tap to skip</strong>.</p>
-<p>How you shape the player's interaction with the controller can be key to achieving a great user
-experience:
- <ul>
- <p><li><strong>Communicate Controller Requirements up Front</strong> - Use your Play Store description to communicate to the player any expectations about
-controllers. If a game is better suited to a gamepad with a joystick than one with only a D-pad,
-make this fact clear. A player who uses an ill-suited controller for a game is likely to have a
-subpar experience–and penalize your game in the ratings.</p>
- <p><li><strong>Use Consistent Button Mapping</strong> - Intuitive and flexible button mapping is key to a good user experience. For example,
-you can adhere to accepted custom by using the A button to <code>Accept</code>, and the B button to
-<code>Cancel</code>. You can also offer flexibility in the form of remappability. For more
-information on button mapping, see <a
-href="http://developer.android.com/training/game-controllers/controller-input.html">Handling
-Controller Actions</a>.</p>
- <p><li><strong>Detect Controller Capabilities and Adjust Accordingly</strong> - Query the controller about its capabilities in order to optimize the match between
-controller and game. For example, you may intend for a player to steer an object by waving the
-controller in the air. If a player's controller lacks accelerometer and gyroscope hardware, however,
-waving will not work. When, however, your game queries the controller and discovers that motion detection
-is not supported, it can switch over to an alternative, available control scheme.
-For more information on querying controller capabilities, see <a
-href="http://developer.android.com/training/game-controllers/compatibility.html">Supporting
-Controllers Across Android Versions</a>.</p>
- </ul>
-<h3>Back-button behavior</h3>
-<p>The Back button should never act as a toggle. For example, do not use it to both open and close
-a menu. It should only navigate backward, breadcrumb-style, through the previous screens the player has
-been on. For example: Game play > Game pause screen > Game
-main screen > Android home screen.</p>
-<p>Since the Back button should only perform linear (backward) navigation, you may use the
-back button to leave an in-game menu (opened by a different button) and return to gameplay. For
-more information about design for navigation, see <a
-href="http://developer.android.com/design/patterns/navigation.html">Navigation with Back and
-Up</a>. To learn about implementation, refer to <a
-href="http://developer.android.com/training/implementing-navigation/temporal.html">Providing Proper
-Back Navigation</a>. </p>
-<h3>Handling multiple controllers</h3>
-<p>When multiple players are playing a game, each with his or her own controller, it is important
-to map each player-controller pair. For information on how to implement controller-number
-identification, see <a href="http://developer.android.com/reference/android/view/InputDevice.html
-#getControllerNumber(">Input Devices</a>) on the Android developer site.</p>
-<h3>Handling disconnects</h3>
-<p>When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog
-should appear prompting the disconnected player to reconnect his or her controller.</p>
-<p>The dialog should also offer troubleshooting tips (for example, a pop-up dialog telling the player to
-"Check your Bluetooth connection"). For more information on implementing input-device support, see <a
-href="http://developer.android.com/training/game-controllers/controller-input.html">Supporting Game
-Controllers"</a>. Specific information about Bluetooth connections is at <a
-href="http://developer.android.com/guide/topics/connectivity/bluetooth.html">Bluetooth</a>.</p>
-
-<h2 id="manifest">Manifest</h2>
-<p>Games are displayed in a separate row from regular apps in the launcher. Android TV uses the
-<code>android:isGame</code> flag to differentiate games from non-game apps. You can assign it a
-value of either <code>true</code> or <code>false</code>. For example:</p>
-<pre class="fragment"><application>
- ...
-< android:isGame=["true" | "false"] >
- ...
-</application></pre>
-
-<h2 id="gpgs">Google Play Game Services</h2>
-<p>If your game integrates Google Play Game Services, you should keep in mind a number of
-considerations pertaining to achievements, sign-on, saving games, and multiplayer play.</p>
-<h3>Achievements</h3>
-<p>Your game should include at least five (earnable) achievements. Only a user controlling gameplay
-from a supported input device should be able to earn achievements. For more information on
-Achievements and how to implement them, see <a
-href="https://developers.google.com/games/services/android/achievements">Achievements in
-Android</a>.</p>
-<h3>Sign-in</h3>
-<p>Your game should attempt to sign the user in on launch. If the player declines sign-in several
-times in a row, your game should stop asking. Learn more about sign-in at <a
-href="https://developers.google.com/games/services/training/signin">Implementing Sign-in on
-Android</a>.</p>
-<h3>Saving</h3>
-<p>We highly recommend using Play Services <a
-href="https://developers.google.com/games/services/common/concepts/cloudsave">Cloud Save</a> to
-store your game save. Your game should bind game saves to a specific Google account, so as to be
-uniquely identifiable even across devices: Whether the player is using a handset or a TV, the game
-should be able to pull the same game-save information from his or her account.</p>
-<p>You should also provide an option in your game's UI to allow the player to delete locally and
-cloud-stored data. You might put the option in the game's <code>Settings</code> screen. For
-specifics on implementing Cloud Save, see <a
-href="https://developers.google.com/games/services/android/cloudsave">Cloud Save in Android</a>.</p>
-<h3>Multiplayer experience</h3>
-<p>A game offering a multiplayer experience must allow at least two players to enter a room. For
-further information on multiplayer games in Android, see the <a
-href="https://developers.google.com/games/services/android/realtimeMultiplayer">Real-time
-Multiplayer</a> and <a href="">Turn-based Multiplayer</a> documentation on the Android developer
-site.</p>
-
-<h2 id="web">Web</h2>
-<p>We discourage including web browsing in games for Android TV. The television set is not well-suited for browsing, either in terms of display or control scheme.</p>
-<p class="note"><strong>Note:</strong> You can use the {@link android.webkit.WebView} class for logins to services like Google+ and
-Facebook. </p>
-
diff --git a/docs/html/preview/tv/publish/index.jd b/docs/html/preview/tv/publish/index.jd
new file mode 100644
index 0000000..f834493
--- /dev/null
+++ b/docs/html/preview/tv/publish/index.jd
@@ -0,0 +1,205 @@
+page.title=Publishing TV Apps
+page.tags="requirements","usability"
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#requirements">Publishing Requirements for TV Apps</a>
+ <ol>
+ <li><a href="#requirements-manifest">Manifest Requirements</a></li>
+ <li><a href="#requirements-usability">Usability Requirements</a></li>
+ </ol>
+ </li>
+ <li><a href="#faq">Frequently Asked Questions</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ Apps for TV devices can be published like other Android apps. You must prepare your app for
+ release and then you can publish it through <a href=
+ "{@docRoot}distribute/googleplay/index.html">Google Play</a>. In order for your app to be
+ accepted as a TV app in Google Play, it must meet some additional requirements, which are covered
+ in this document.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You will not be able to publish apps to TV devices through <a href=
+ "{@docRoot}distribute/googleplay/index.html">Google Play</a> until Android L SDK is released.
+</p>
+
+
+<h2 id="requirements">Publishing Requirements for TV Apps</h2>
+
+<p>
+ Your app must provide specific manifest declarations and meet some minimum usability requirements
+ before it can qualify as TV app on Google Play. Make sure your app meets these requirements to
+ get your app ready for TV devices.
+</p>
+
+<p class="caution">
+ <strong>Caution:</strong> Your app must meet all of the requirements described in this section in
+ order to qualify as a TV app on Google Play. If your app does not meet the usability requirements
+ described below, the Google Play team will contact you through the email address specified in main
+ <a href="https://play.google.com/apps/publish/">Google Play Developer Console</a> account
+ associated with the app.
+</p>
+
+<h3 id="requirements-manifest">Manifest Requirements</h3>
+
+<p>
+ Developers who want their apps to be considered for publishing on TV devices <em>must</em>
+ include a manifest entry that declares an activity which handles the {@code
+ android.intent.category.LEANBACK_LAUNCHER} intent filter. For more information about including
+ the required manifest entries, see <a href=
+ "{@docRoot}preview/tv/start/index.html#tv-activity">Get Started with TV Apps</a>.
+</p>
+
+<p class="caution">
+ <strong>Caution:</strong> If you do not include the <a href=
+ "{@docRoot}preview/tv/start/index.html#tv-activity">required manifest entries</a> for TV devices,
+ your app is not considered as a TV app. The app will not be reviewed for the TV app usability
+ requirements and will not be able to qualify as a TV app on Google Play.
+</p>
+
+
+<h3 id="requirements-usability">Usability Requirements</h3>
+
+<p>
+ Users bring a different set of expectations when watching TV. Apps for Android TV devices have a
+ different interaction, look and feel from Android apps on the phone or tablet. How users interact
+ with TVs (with a remote control device) and how they view them (sitting about 10 feet away),
+ significantly changes the requirements for what makes a good user experience in an app.
+</p>
+
+<p>
+ The first step toward creating a great experience for users on TV is to review and follow the
+ <a href="{@docRoot}preview/tv/design/index.html">Design for TV</a> guidelines. These guidelines
+ provide general directions for designing a TV app as well as some specific implementation
+ instructions.
+</p>
+
+<p>
+ Apps for TV devices must meet some specific requirements for usability. Only apps that meet the
+ following usability criteria will qualify as an TV app on Google Play:
+</p>
+
+<ul>
+ <li>App functionality must be navigable using 5-way D-pad controls, unless the app requires a
+ game controller.
+ (<a href="{@docRoot}preview/tv/ui/navigation.html#d-pad-navigation">details</a>)
+ <ul>
+ <li>If the app requires a game controller, all functionality must be navigable using
+ standard Android game controller keys.
+ (<a href="{@docRoot}training/game-controllers/controller-input.html#button">details</a>)
+ </li>
+ </ul>
+ </li>
+
+ <li>Layouts used on TV devices must be designed for landscape orientation.
+ (<a href="{@docRoot}preview/tv/ui/layouts.html#structure">details</a>)</li>
+
+ <li>Core text used in TV layouts must be at least 16sp in size and all text must be at least
+ 12sp.</li>
+
+ <li>Text and functionality should be placed inside an overscan margin of at least 27dp from the
+ top and bottom edges and 48dp from the left and right edges of the TV screen.
+ (<a href="{@docRoot}preview/tv/ui/layouts.html#overscan">details</a>)</li>
+
+ <li>Apps that uses full-screen, non-video ads, must ensure that the ads are immediately
+ dismissible by the user with D-pad controls.</li>
+
+ <li>Apps must not depend on having a web browser app on TV devices. Apps can use <a href=
+ "http://developer.android.com/reference/android/webkit/WebView.html">WebView components</a> to
+ show web content where needed.</li>
+
+ <li>Apps that uses clickable, non-full screen, non-video ads must ensure that the ads do not link
+ to a web URL. These ads must also not link to an app or game that is not available on TV devices
+ and, therefore, not available in the Google Play store for TV.</li>
+
+ <li>Apps must display correctly on the Android TV launcher by doing the following:
+ <ul>
+ <li>Include in the app manifest an intent filter of type {@code ACTION_MAIN} with an intent
+ category {@code CATEGORY_LEANBACK_LAUNCHER}.
+ (<a href="{@docRoot}preview/tv/start/index.html#tv-activity">details</a>)
+ </li>
+
+ <li>Provide a 320x180px banner image resource and declare it in the manifest.</li>
+
+ <li>If the app is a game, it must set the {@code isGame} property to {@code true} in the
+ manifest. (<a href="{@docRoot}preview/tv/games/index.html#manifest">details</a>)
+ </li>
+ </ul>
+ </li>
+
+ <li>App must not partially obscure other apps. Apps must fill the entire screen and have a
+ non-transparent background.
+ </li>
+
+ <li>Music and audio apps that continue to play sound after a user has left the app must provide
+ a <strong>Now Playing</strong> card on the home screen recommendation row so users can easily
+ control playback. Developers should use the {@code android.media.session.MediaSession} API
+ to enable this card and link playback to a specific activity.
+ </li>
+
+ <li>Media apps that play video or music content must toggle between play and pause of media
+ playback when a <a href="{@docRoot}reference/android/view/KeyEvent.html#KEYCODE_MEDIA_PLAY_PAUSE">
+ play or pause key event</a> is sent during playback.
+ </li>
+
+ <li>Games that use a gamepad in order to play must define gamepad use in the app manifest.
+ (<a href="{@docRoot}preview/tv/games/index.html#gamepad">details</a>)
+ </li>
+
+ <li>Games that provide in-game instructions for game controllers must show a generic controller
+ layout that does not include any branding. You can download generic controller artwork from
+ here: <a href="http://storage.googleapis.com/androiddevelopers/design/android_tv_gamepad_template-2014-10.zip">
+ android_tv_gamepad_template_2014-10.zip</a>.
+ </li>
+</ul>
+
+
+<h2 id="faq">Frequently Asked Questions</h2>
+
+<p>
+ <strong>After I submit my app, how will find out if my app does not meet all the requirements for
+ TV devices?</strong>
+</p>
+<p>
+ If your app does not meet the usability requirements described on this page, the Play Store team
+ will contact you through the email address specified in main <a href=
+ "https://play.google.com/apps/publish/">Google Play Developer Console</a> account associated with
+ the app.
+</p>
+<p class="caution">
+ <strong>Caution:</strong> Make sure your app includes the <a href=
+ "{@docRoot}preview/tv/start/index.html#tv-activity">required manifest entries</a> for TV devices,
+ otherwise your app will not be considered a TV app and will not be reviewed for TV usability
+ requirements.
+</p>
+
+
+<p>
+ <strong>My app targets more than just TV devices. If my app does not meet the TV device
+ requirements, will my new or updated app still appear on Google Play for phones and
+ tablets?</strong>
+</p>
+<p>
+ Yes. The requirements described above only restrict distribution to the Google Play Store on TV
+ devices. Distribution to other device types, such as phones, tablets and other devices, is not
+ affected.
+</p>
+
+
+<p>
+ <strong>If my app meets the publishing requirements, when will it be available in the Google
+ Play Store on TV devices?</strong>
+</p>
+
+<p>
+ Apps that meet the requirements for TV will appear in the Google Play Store on TV devices
+ <em>after</em> the official release of Android L.
+</p>
\ No newline at end of file
diff --git a/docs/html/preview/tv/start/hardware-features.jd b/docs/html/preview/tv/start/hardware-features.jd
deleted file mode 100644
index ddec496..0000000
--- a/docs/html/preview/tv/start/hardware-features.jd
+++ /dev/null
@@ -1,183 +0,0 @@
-page.title=Hardware Features on TV
-page.tags="unsupported"
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#unsupported-features">Unsupported Hardware Features</a></li>
- <li><a href="#workaround-features">Handling Unsupported Features</a></li>
- <li><a href="#check-features">Checking Available Features</a>
- <ol>
- <li><a href="#no-touchscreen">Touch screen</a></li>
- <li><a href="#no-camera">Camera</a></li>
- <li><a href="#no-gps">GPS</a></li>
- </ol>
-
- </li>
- </ol>
-</div>
-</div>
-
-<p>TVs do not have some of the hardware features found on other Android devices.
-Touch screens, cameras, and GPS receivers are some of the most commonly used hardware features
-which are typically not available on a TV. When you build an app for TV, you must carefully
-consider if your app can handle not having these features and, if necessary, work around them.</p>
-
-<p>This guide discusses the hardware features not available on TV devices and shows you how to
-work around those limitations in your app. For more information on filtering and declaring
-features in the manifest, see the
-<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">uses-feature</a> guide.</p>
-
-
-<h2 id="unsupported-features">Unsupported Hardware Features</h2>
-
-<p>TVs have a different purpose from other devices, and so they do not have hardware
-features that other Android-powered devices often have. For this reason, the Android system
-does not support the following features for a TV device:
-
-<table>
-<tr>
-<th>Hardware</th>
-<th>Android feature descriptor</th>
-</tr>
-<tr>
-<td>Camera</td>
-<td>android.hardware.camera</td>
-</tr>
-<tr>
-<td>GPS</td>
-<td>android.hardware.location.gps</td>
-</tr>
-<tr>
-<td>Microphone</td>
-<td>android.hardware.microphone</td>
-</tr>
-<tr>
-<td>Near Field Communications (NFC)</td>
-<td>android.hardware.nfc</td>
-</tr>
-<tr>
-<td>Telephony</td>
-<td>android.hardware.telephony</td>
-</tr>
-<tr>
-<td>Touchscreen</td>
-<td>android.hardware.touchscreen</td>
-</tr>
-</table>
-</p>
-
-
-<h2 id="check-features">Checking Available Features</h2>
-
-<p>To check if a feature is available at runtime, call {@link
- android.content.pm.PackageManager#hasSystemFeature(String)}. This method takes a single string
- argument that specifies the feature you want to check. For example, to check for a touch screen,
- use {@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument
- {@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.</p>
-
-<p>The following code example demonstrates how to detect the availability of a hardware features
- at runtime:</p>
-
-<pre>
-// Check if the telephony hardware feature is available.
-if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
- Log.d("Mobile Test", "Running on phone");
-// Check if android.hardware.touchscreen feature is available.
-} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
- Log.d("Tablet Test", "Running on devices that don't support telephony but "+
- "do have a touch screen.");
-} else {
- Log.d("TV Test", "Running on a TV!");
-}
-</pre>
-
-<p class="note">
- <strong>Note:</strong> You can also use the {@link android.app.UiModeManager#getCurrentModeType
- UiModeManager.getCurrentModeType()} method to detect the current platform type. For TV devices,
- this method returns a value of {@link android.content.res.Configuration#UI_MODE_TYPE_TELEVISION
- Configuration.UI_MODE_TYPE_TELEVISION}.
-</p>
-
-
-<h2 id="workaround-features">Handling Unsupported Features</h2>
-
-<p>Depending on the design and functionality of your app, you may be able to work around certain
- hardware features being unavailable. This section discusses how to work around specific hardware
- features.</p>
-
-
-<h3 id="no-touchscreen">Touch screen</h3>
-
-<p>Android doesn't support touch screen interaction for TV devices, since most TVs don't have touch
- screens, and using a touch screen is not consistent with a viewing environment where the user is
- seated 10 feet away from the display.</p>
-
-<p>On TV devices, you should work around this limitation by supporting navigation using a directional
- pad (D-pad) on TV remote control. For more information on properly supporting navigation using
- TV-friendly controls, see <a href="{@docRoot}preview/tv/ui/navigation.html">Navigation for
- TV</a>.</p>
-
-<p>You can explicitly declare if your application requires (or does not require) a touch screen
- by including the following entry in your manifest:</p>
-
-<pre>
-<uses-feature android:name="android.hardware.touchscreen"
- android:required="false"/>
-</pre>
-
-
-<h3 id="no-camera">Camera</h3>
-
-<p>Although a TV typically does not have a camera, you can still provide a photography-related
- application on a TV. For example, if you have an app that takes, views and edits photos, you can
- disable its picture-taking functionality for TVs and still allow users to view and even edit
- photos. If you decide that you want to enable your camera-related application to work on a
- TV device without a camera, you can add an attribute to your app manifest declaring that
- a camera is not required by your app:</p>
-
-<pre>
-<uses-feature android:name="android.hardware.camera" android:required="false" />
-</pre>
-
-<p>If you enable your application to run without a camera, you should add code to your application
-that detects if the camera feature is available and makes adjustments to the operation of your app.
-The following code example demonstrates how to detect the presence of a camera:</p>
-
-<pre>
-// Check if the camera hardware feature is available.
-if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
- Log.d("Camera test", "Camera available!");
-} else {
- Log.d("Camera test", "No camera available. View and edit features only.");
-}
-</pre>
-
-
-<h3 id="no-gps">GPS</h3>
-
-<p>TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
- receivers. If your application uses location information, you can still allow users to search
- for a location, or use a static location provider such as a zip code configured during the
- TV device setup.</p>
-
-<pre>
-LocationManager locationManager = (LocationManager) this.getSystemService(
- Context.LOCATION_SERVICE);
-Location location = locationManager.getLastKnownLocation("static");
-Geocoder geocoder = new Geocoder(this);
-Address address = null;
-
-try {
- address = geocoder.getFromLocation(location.getLatitude(),
- location.getLongitude(), 1).get(0);
- Log.d("Zip code", address.getPostalCode());
-
-} catch (IOException e) {
- Log.e(TAG, "Geocoder error", e);
-}
-</pre>
-
diff --git a/docs/html/preview/tv/start/index.jd b/docs/html/preview/tv/start/index.jd
deleted file mode 100644
index 5af28a6..0000000
--- a/docs/html/preview/tv/start/index.jd
+++ /dev/null
@@ -1,231 +0,0 @@
-page.title=Get Started with TV Apps
-page.tags="leanback","recyclerview","launcher"
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#prerequisites">Prerequisites</a></li>
- <li><a href="#dev-project">Setup a TV Project</a>
- <ul>
- <li><a href="#tv-activity">Create a TV Activity</a></li>
- <li><a href="#tv-libraries">Add TV Support Libraries</a></li>
- </ul>
- </li>
- <li><a href="#build-it">Build TV Apps</a></li>
- <li><a href="#run">Run TV Apps</a></li>
-
- </ol>
-</div>
-</div>
-
-<p>This guide describes how to prepare your development environment and projects for building
- TV apps, including updating your existing app to run on TV devices.</p>
-
-
-<h2 id="prerequisites">Prerequisites</h2>
-
-<p>Before you begin setting up to build apps for TV, you must:</p>
-
-<ul>
- <li><strong><a href="{@docRoot}preview/setup-sdk.html">
- Set up the Preview SDK</a></strong>
- <br>
- The preview SDK provides the developer tools needed to build and test apps for TV.
- </li>
- <li><strong><a href="{@docRoot}preview/setup-sdk.html#project">
- Create a Preview SDK Project</a></strong>
- <br>
- In order to access new APIs for TV devices, you must create a project that targets the preview
- release level or modify an existing project to target the preview release.
- </li>
-</ul>
-
-
-<h2 id="dev-project">Set up a TV Project</h2>
-
-<p>TV apps use the same structure as those for phones and tablets. This means you can modify
- your existing apps to also run on TV devices or create new apps based on what you already know
- about building apps for Android. This section discusses how to modify an existing app, or create a
- new one, to run on TV devices.</p>
-
-<p>These are the main steps to creating an app that runs on TV devices. Only the first
- is required:</p>
-
-<ul>
- <li><strong>Activity for TV</strong> - (Required) In your application manifest, you must
- declare an activity that is intended to run on TV devices.</li>
- <li><strong>TV Support Libraries</strong> - (Optional) There are several Support Libraries
- available for TV devices that provide widgets for building user interfaces.</li>
-</ul>
-
-
-<h3 id="tv-activity">Create a TV Activity</h3>
-
-<p>An application intended to run on TV devices must declare a launcher activity for TV
- in its manifest using a {@code android.intent.category.LEANBACK_LAUNCHER} intent filter.
- This filter identifies your app as being built for TV, enabling it to be displayed in the
- Google Play store app running on TV devices. Declaring this intent also identifies which activity
- in your app should be launched when a user selects its icon on the TV home screen.</p>
-
-<p class="caution">
- <strong>Caution:</strong> If you do not include the {@code LEANBACK_LAUNCHER} intent filter in
- your app, it is not visible to users running the Google Play store on TV devices. Also, if your
- app does not have this filter when you load it onto a TV device using developer tools, the app
- does not appear in the TV user interface.
-</p>
-
-<p>The following code snippet shows how to include this intent filter in your manifest:</p>
-
-<pre>
-<application>
- ...
- <activity
- android:name="com.example.android.MainActivity"
- android:label="@string/app_name" >
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity
- android:name="com.example.android.<strong>TvActivity</strong>"
- android:label="@string/app_name"
- android:theme="@style/Theme.Leanback">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="<strong>android.intent.category.LEANBACK_LAUNCHER</strong>" />
- </intent-filter>
-
- </activity>
-</application>
-</pre>
-
-<p>The second activity manifest entry in the example above specifies that activity as
- the main one when your app launches on an TV device.</p>
-
-<p>If you have an existing app that you are modifying for TV use, your app should not use the same
- activity layout for TV that it does for phones and tablets. The user interface of your TV app (or
- TV portion of your existing app) should provide a simpler interface that can be easily navigated
- using a remote control from a couch. For guidelines on designing an app for TV, see the
- <a href="{@docRoot}design/tv/index.html">TV Design</a> guide. For more instructions on
- developing a user interface appropriate to TV, see the
- <a href="{@docRoot}preview/tv/ui/index.html">TV User Interface</a> guide.
-</p>
-
-
-<h3 id="tv-libraries">Add TV Support Libraries</h3>
-
-<p>The Preview SDK includes support libraries that are intended for use with TV apps. These
- libraries provide APIs and user interface widgets for use on TV devices. The libraries are
- located in the {@code <sdk>/extras/android/support/} directory where you installed the
- Preview SDK. Here is a list of the libraries and their general purpose:</p>
-
-<ul>
- <li><strong>v17 leanback library</strong> - Provides user interface widgets for TV, including
- {@code BrowseFragment}, {@code DetailsFragment}, and {@code SearchFragment}.
- <ul>
- <li>SDK location: {@code <sdk>/extras/android/support/v17/leanback}</li>
- <li>Gradle dependency: {@code com.android.support:leanback-v17:20.0.+}</li>
- <li>Contains resources: Yes</li>
- </ul>
- </li>
- <li><strong>v7 recyclerview library</strong> - Provides classes for managing display of long
- lists in a memory efficient manner. Several classes in the v17 leanback library depend on the
- classes in this library.
- <ul>
- <li>SDK location: {@code <sdk>/extras/android/support/v7/recyclerview}</li>
- <li>Gradle dependency: {@code com.android.support:recyclerview-v7:20.0.+}</li>
- <li>Contains resources: No</li>
- </ul>
- </li>
-</ul>
-
-<p class="note">
- <strong>Note:</strong> You are not required to use these support libraries for your TV app.
- However, we strongly recommend using them, particularly for apps that provide a media catalog
- browsing interface.
-</p>
-
-<p>If you decide to use the v17 leanback library for your app, you should note that it is
- dependent on the
- <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. This means
- that apps that use the leanback support library should include all of these support
- libraries:</p>
-
-<ul>
- <li>v17 leanback support library</li>
- <li>v7 recyclerview support library</li>
- <li>v4 support library</li>
-</ul>
-
-<p>The v17 leanback library contain resources, which requires
- you to take specific steps to include it in app projects. For instructions on
- importing a support library with resources, see
- <a href="http://developer.android.com/tools/support-library/setup.html#libs-with-res">
- Support Library Setup</a>.
-</p>
-
-
-<h2 id="build-it">Build TV Apps</h2>
-
-<p>After you have completed the steps described above, it's time to start building apps for
- the big screen! Check out these additional topics to help you build your app for TV:
-
-<ul>
- <li><a href="{@docRoot}preview/tv/ui/index.html">User Interface</a> - The user interface of
- TV devices is different from those of other Android devices. See this topic to find out how
- to build TV user interfaces and to learn about the widgets provided to simplify that task.
- </li>
- <li><a href="{@docRoot}preview/tv/games/index.html">Games for TV</a> - TV devices are great
- platforms for games. See this topic for information on building great game experiences for
- TV.</li>
- <li><a href="{@docRoot}preview/tv/start/hardware-features.html">Hardware features</a> - TV
- devices do not contain hardware features normally found on other Android devices. See this
- topic for information on unsupported hardware features and what to do about them.
- </li>
-</ul>
-
-
-<h2 id="run">Run TV Apps</h2>
-
-<p>Running your app is an important part of the development process. The AVD Manager in the
- Android SDK provides the device definitions that allows you to create virtual TV devices for
- running and testing your applications.</p>
-
-<p>To create an virtual TV device:</p>
-
-<ol>
- <li>Start the AVD Manager. For more information, see the
- <a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> help.</li>
- <li>In the AVD Manager dialog, click the <strong>Device Definitions</strong> tab.</li>
- <li>Select one of the Android TV device definitions, such as
- <strong>Large Android TV</strong>, and click <strong>Create AVD</strong>.</li>
- <li>Select the emulator options and click <strong>OK</strong> to create the AVD.
- <p class="note">
- <strong>Note:</strong> For best performance of the TV emulator device, enable the <strong>Use
- Host GPU</strong> option and CPU platform image that supports hardware acceleration. For
- more information on hardware acceleration of the emulator, see
- <a href="{@docRoot}tools/devices/emulator.html#acceleration">Using the Emulator</a>.
- </p>
- </li>
-</ol>
-
-<p>To test your application on the virtual TV device:</p>
-
-<ol>
- <li>Compile your TV application in your development environment.</li>
- <li>Run the application from your development environment and choose the TV virtual device as
- the target.</li>
-</ol>
-
-<p>For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
-Using the Emulator</a>. For more information about deploying apps to emulators from
-Eclipse with ADT, see <a href="{@docRoot}http://developer.android.com/tools/building/building-eclipse.html">
-Building and Running from Eclipse with ADT</a>.</p>
-
diff --git a/docs/html/preview/tv/ui/browse.jd b/docs/html/preview/tv/ui/browse.jd
deleted file mode 100644
index d6b97c1..0000000
--- a/docs/html/preview/tv/ui/browse.jd
+++ /dev/null
@@ -1,198 +0,0 @@
-page.title=BrowseFragment
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#layout">Media Browse Layout</a></li>
- <li><a href="#lists">Displaying Media Lists</a></li>
- <li><a href="#background">Updating the Background</a></li>
- </ol>
-
-</div>
-</div>
-
-<p>The <a href="{@docRoot}preview/tv/start/index.html#tv-libraries">Leanback support library</a>
- provides several APIs for displaying and browsing media catalogs
- on the TV devices. This guide discusses how to use the classes provided by this library to
- implement a user interface for browsing music or videos from your app's media catalog.</p>
-
-
-<h2 id="layout">Media Browse Layout</h2>
-
-<p>The {@code BrowseFragment} class in the Leanback support library allows you to create a primary
- layout for browsing categories and rows of media items with a minimum of code. The following
- example shows how to create a layout that contains a {@code BrowseFragment}:</p>
-
-<pre>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- >
-
- <fragment
- <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
- android:id="@+id/browse_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
-</LinearLayout>
-</pre>
-
-<p>In order to work with this layout in an activity, retrieve the {@code BrowseFragment} element
- from the layout. Use the methods in {@code BrowseFragment} to set display parameters such as the
- icon, title and whether category headers are enabled. The following code sample demonstrates how
- to set the layout parameters for a {@code BrowseFragment} in a layout:</p>
-
-<pre>
-public class BrowseMediaActivity extends Activity {
-
- public static final String TAG ="BrowseActivity";
-
- protected BrowseFragment mBrowseFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.browse_fragment);
-
- final FragmentManager fragmentManager = getFragmentManager();
- <strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
- R.id.browse_fragment);</strong>
-
- // Set display parameters for the BrowseFragment
- mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
- mBrowseFragment.setTitle(getString(R.string.app_name));
- mBrowseFragment.setBadgeDrawable(getResources().getDrawable(R.drawable.ic_launcher));
- mBrowseFragment.setBrowseParams(params);
-
- }
-}
-</pre>
-
-
-<h2 id="lists">Displaying Media Lists</h2>
-
-<p>The {@code BrowseFragment} allows you to define and display browsable media content categories and
- media items from a media catalog using adapters and presenters. Adapters enable you to connect to
- local or online data sources that contain your media catalog information. Presenter classes hold
- data about media items and provide layout information for displaying an item on screen.</p>
-
-<p>The following example code shows an implementation of a presenter for displaying string
- data:</p>
-
-<pre>
-public class StringPresenter extends Presenter {
- private static final String TAG = "StringPresenter";
-
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- TextView textView = new TextView(parent.getContext());
- textView.setFocusable(true);
- textView.setFocusableInTouchMode(true);
- textView.setBackground(
- parent.getContext().getResources().getDrawable(R.drawable.text_bg));
- return new ViewHolder(textView);
- }
-
- public void onBindViewHolder(ViewHolder viewHolder, Object item) {
- ((TextView) viewHolder.view).setText(item.toString());
- }
-
- public void onUnbindViewHolder(ViewHolder viewHolder) {
- // no op
- }
-}
-</pre>
-
-<p>Once you have constructed a presenter class for your media items, you can build and attach an
- adapter to the {@code BrowseFragment} to display those items on screen for browsing by the user. The
- following example code demonstrates how to construct an adapter to display categories and items
- in those categories using the StringPresenter class shown in the previous code example:</p>
-
-<pre>
-private ArrayObjectAdapter mRowsAdapter;
-private static final int NUM_ROWS = 4;
-
-@Override
-protected void onCreate(Bundle savedInstanceState) {
- ...
-
- buildRowsAdapter();
-}
-
-private void buildRowsAdapter() {
- mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
-
- for (int i = 0; i < NUM_ROWS; ++i) {
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
- new StringPresenter());
- listRowAdapter.add("Media Item 1");
- listRowAdapter.add("Media Item 2");
- listRowAdapter.add("Media Item 3");
- HeaderItem header = new HeaderItem(i, "Category " + i, null);
- mRowsAdapter.add(new ListRow(header, listRowAdapter));
- }
-
- mBrowseFragment.setAdapter(mRowsAdapter);
-}
-</pre>
-
-<p>This example shows a static implementation of the adapters. A typical media browsing
- application uses data from an online database or web service. For an example of a browsing
- application that uses data retrieved from the web, see the
- <a href="http://github.com/googlesamples/androidtv-leanback">Android TV</a> sample app.</p>
-
-
-<h2 id="background">Updating the Background</h2>
-
-<p>In order to add visual interest to a media-browsing app on TV, you can update the background
- image as users browse through content. This technique can make interaction with your app feel more
- cinematic and enjoyable for users.</p>
-
-<p>The Leanback support library provides a {@code BackgroundManager} class for changing the
- background of your TV app activity. The following example shows how to create a simple method
- for updating the background within your TV app activity:</p>
-
-<pre>
-protected void updateBackground(Drawable drawable) {
- BackgroundManager.getInstance(this).setDrawable(drawable);
-}
-</pre>
-
-<p>Many of the existing media-browse apps automatically update the background as the user
- navigates through media listings. In order to do this, you can set up a selection listener to
- automatically update the background based on the user's current selection. The following example
- shows you how to set up an {@code OnItemSelectedListener}
- class to catch selection events and update the background:</p>
-
-<pre>
-protected void clearBackground() {
- BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
-}
-
-protected OnItemSelectedListener getDefaultItemSelectedListener() {
- return new OnItemSelectedListener() {
- @Override
- public void onItemSelected(Object item, Row row) {
- if (item instanceof Movie ) {
- URI uri = ((Movie)item).getBackdropURI();
- updateBackground(uri);
- } else {
- clearBackground();
- }
- }
- };
-}
-</pre>
-
-<p class="note">
- <strong>Note:</strong> The implementation above is a simple example shown for purposes of
- illustration. When creating this function in your own app, you should consider running the
- background update action in a separate thread for better performance. In addition, if you are
- planning on updating the background in response to users scrolling through items, consider adding
- a time to delay a background image update until the user settles on an item. This technique avoids
- excessive background image updates.
-</p>
diff --git a/docs/html/preview/tv/ui/details.jd b/docs/html/preview/tv/ui/details.jd
deleted file mode 100644
index 8b8fa8b5..0000000
--- a/docs/html/preview/tv/ui/details.jd
+++ /dev/null
@@ -1,214 +0,0 @@
-page.title=DetailFragment
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#details-presenter">Build a Details Presenter</a></li>
- <li><a href="#details-fragment">Extend the Details Fragment</a>
- <li><a href="#activity">Creating a Details Activity</a></li>
- <li><a href="#item-listener">Listener for Clicked Items</a></li>
- </li>
- </ol>
-</div>
-</div>
-
-<p>The media browsing interface classes provided by the
- <a href="{@docRoot}preview/tv/start/index.html#tv-libraries">Leanback support library</a>
- include classes for displaying additional information about a media item, such as a description
- or reviews, and for taking action on that item, such as purchasing it or playing its content. This
- section discusses how to create a presenter class for media item details and extend the
- {@code DetailsFragment} class to implement a details view for a media item when it
- is selected by a user.
-</p>
-
-<p class="note">
- <strong>Note:</strong> The implementation example shown here uses an additional activity to
- contain the {@code DetailsFragment}. However, it is possible to avoid creating a second activity
- by replacing the current {@code BrowseFragment} with a {@code DetailsFragment} within the <em>same</em>
- activity using fragment transactions. For more information on using fragment transactions, see the
- <a href="{@docRoot}training/basics/fragments/fragment-ui.html#Replace">Building a Dynamic
- UI with Fragments</a> training.
-</p>
-
-
-<h2 id="details-presenter">Build a Details Presenter</h2>
-
-<p>In the media browsing framework provided for by the leanback support library, you use
- presenter objects to control the display of data on screen, including media item details. The
- framework provides the {@code AbstractDetailsDescriptionPresenter} class for this purpose, which
- is a nearly complete implementation of the presenter for media item details. All you have to do is
- implement the {@code onBindDescription()} method to bind the view fields to your data objects, as shown in
- the following code sample:</p>
-
-<pre>
-public class DetailsDescriptionPresenter
- extends AbstractDetailsDescriptionPresenter {
-
- @Override
- protected void onBindDescription(ViewHolder viewHolder, Object itemData) {
- MyMediaItemDetails details = (MyMediaItemDetails) itemData;
- // In a production app, the itemData object contains the information
- // needed to display details for the media item:
- // viewHolder.getTitle().setText(details.getShortTitle());
-
- // Here we provide static data for testing purposes:
- viewHolder.getTitle().setText(itemData.toString());
- viewHolder.getSubtitle().setText("2014 Drama TV-14");
- viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur "
- + "adipisicing elit, sed do eiusmod tempor incididunt ut labore "
- + " et dolore magna aliqua. Ut enim ad minim veniam, quis "
- + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
- + "commodo consequat.");
- }
-}
-</pre>
-
-
-<h2 id="details-fragment">Extend the Details Fragment</h2>
-
-<p>When you use the {@code DetailsFragment} class for displaying your media item details, you
- extend that class to provide additional content such as a preview image and actions for the media
- item. You can also provide additional content, such as a list of related media items.</p>
-
-<p>The following example code demonstrates how to use the presenter class you created in the
- previous section, add a preview image and actions for the media item being viewed. This example
- also shows the addition of a related media items row, which appears below the details listing.</p>
-
-<pre>
-public class MediaItemDetailsFragment extends DetailsFragment {
- private static final String TAG = "MediaItemDetailsFragment";
- private ArrayObjectAdapter mRowsAdapter;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "onCreate");
- super.onCreate(savedInstanceState);
-
- buildDetails();
- }
-
- private void buildDetails() {
- ClassPresenterSelector selector = new ClassPresenterSelector();
- // Attach your media item details presenter to the row presenter:
- DetailsOverviewRowPresenter rowPresenter =
- new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
-
- selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
- selector.addClassPresenter(ListRow.class,
- new ListRowPresenter());
- mRowsAdapter = new ArrayObjectAdapter(selector);
-
- Resources res = getActivity().getResources();
- DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
- "Media Item Details");
-
- // Add images and action buttons to the details view
- detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
- detailsOverview.addAction(new Action(1, "Buy $9.99"));
- detailsOverview.addAction(new Action(2, "Rent $2.99"));
- mRowsAdapter.add(detailsOverview);
-
- // Add a Related items row
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
- new StringPresenter());
- listRowAdapter.add("Media Item 1");
- listRowAdapter.add("Media Item 2");
- listRowAdapter.add("Media Item 3");
- HeaderItem header = new HeaderItem(0, "Related Items", null);
- mRowsAdapter.add(new ListRow(header, listRowAdapter));
-
- setAdapter(mRowsAdapter);
- }
-}
-</pre>
-
-
-<h3 id="activity">Creating a Details Activity</h3>
-
-<p>Fragments such as the {@code DetailsFragment} must be contained within an activity in order
- to be used for display. Creating an activity for your details view, separate from the browse
- activity, enables you to invoke your details view using an Intent. This section explains how to
- build an activity to contain your implementation of the detail view for your media items.</p>
-
-<p>Start creating the details activity by building a layout that references your implementation
- of the {@code DetailsFragment}:</p>
-
-<pre>
-<!-- file: res/layout/details.xml -->
-
-<fragment xmlns:android="http://schemas.android.com/apk/res/android"
- <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
- android:id="@+id/details_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
-/>
-</pre>
-
-<p>Next, create an activity class that uses the layout shown in the previous code example:</p>
-
-<pre>
-public class DetailsActivity extends Activity
-{
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- <strong>setContentView(R.layout.details);</strong>
- }
-}
-</pre>
-
-<p>Finally, add this new activity to the manifest. Remember to apply the Leanback theme to
- ensure that the user interface is consistent with the media browse activity:</p>
-
-<pre>
-<application>
- ...
-
- <activity android:name=".DetailsActivity"
- android:exported="true"
- <strong>android:theme="@style/Theme.Leanback"/></strong>
-
-</application>
-</pre>
-
-
-<h3 id="item-listener">Listener for Clicked Items</h3>
-
-<p>After you have implemented the {@code DetailsFragment}, you must modify your main media
- browsing view to move to your details view when a user clicks on a media item. In order to enable
- this behavior, add an {@code OnItemClickedListener} object to the BrowseFragment that fires an
- intent to start the item details activity.</p>
-
-<p>The following example shows how to implement a listener to start the details view when a user
- clicks a media item in the main media browsing activity:</p>
-
-<pre>
-public class BrowseMediaActivity extends Activity {
- ...
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- ...
-
- // create the media item rows
- buildRowsAdapter();
-
- // add a listener for selected items
- mBrowseFragment.setOnItemClickedListener(
- new OnItemClickedListener() {
- @Override
- public void onItemClicked(Object item, Row row) {
- System.out.println("Media Item clicked: " + item.toString());
- Intent intent = new Intent(BrowseMediaActivity.this,
- DetailsActivity.class);
- // pass the item information
- intent.getExtras().putLong("id", item.getId());
- startActivity(intent);
- }
- });
- }
-}
-</pre>
diff --git a/docs/html/preview/tv/ui/in-app-search.jd b/docs/html/preview/tv/ui/in-app-search.jd
deleted file mode 100644
index 3dbfcd2..0000000
--- a/docs/html/preview/tv/ui/in-app-search.jd
+++ /dev/null
@@ -1,111 +0,0 @@
-page.title=Adding Search to TV Apps
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#add-search-ui">Add Search User Interface</a></li>
- </ol>
-
-</div>
-</div>
-
-
-<p>Users frequently have specific content in mind when using a media app. A search interface can
- help your users get to the content they want faster than browsing. The Leanback library provides a
- set of classes to enable a standard search interface within your app that is consistent with other
- search functions on TV and provides features such as voice input.</p>
-
-<h2 id="add-search-ui">Add Search User Interface</h2>
-<p>When you use the BrowseFragment class for your media browsing interface, you can enable the
- search icon by setting an OnClickListener to the BrowseFragment object. The following sample code
- demonstrates this technique.</p>
-
-<pre>
-@Override
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.browse_activity);
-
- mBrowseFragment = (BrowseFragment)
- getFragmentManager().findFragmentById(R.id.browse_fragment);
-
- ...
-
- mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
- startActivity(intent);
- }
- });
-
- mBrowseFragment.setAdapter(buildAdapter());
-}
-</pre>
-
-<p class="note">
- <strong>Note:</strong> You can set the color of the search icon using the
- {@code setSearchAffordanceColor()} method of {@code BrowseFragment}.
-</p>
-
-<p>When a user selects the search icon, the system invokes a search activity via the defined
- Intent. Your search activity should use a linear layout containing a SearchFragment. This fragment
- must also implement the SearchFragment.SearchResultProvider interface in order to display the
- results of a search. The following code sample shows how to extend the SearchFragment class to
- provide a search interface and results:</p>
-
-<pre>
-public class MySearchFragment extends SearchFragment
- implements SearchFragment.SearchResultProvider {
-
- private static final int SEARCH_DELAY_MS = 300;
- private ArrayObjectAdapter mRowsAdapter;
- private Handler mHandler = new Handler();
- private SearchRunnable mDelayedLoad;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
- setSearchResultProvider(this);
- setOnItemClickedListener(getDefaultItemClickedListener());
- mDelayedLoad = new SearchRunnable();
- }
-
- @Override
- public ObjectAdapter getResultsAdapter() {
- return mRowsAdapter;
- }
-
- @Override
- public boolean onQueryTextChange(String newQuery) {
- mRowsAdapter.clear();
- if (!TextUtils.isEmpty(newQuery)) {
- mDelayedLoad.setSearchQuery(newQuery);
- mHandler.removeCallbacks(mDelayedLoad);
- mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextSubmit(String query) {
- mRowsAdapter.clear();
- if (!TextUtils.isEmpty(query)) {
- mDelayedLoad.setSearchQuery(query);
- mHandler.removeCallbacks(mDelayedLoad);
- mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
- }
- return true;
- }
-}
-</pre>
-
-<p>This example code shown above is meant to be used with a separate {@code SearchRunnable}
- class that runs the search query on a separate thread. This technique keeps potentially
- slow-running queries from blocking the main user interface thread.</p>
-
diff --git a/docs/html/preview/tv/ui/layouts.jd b/docs/html/preview/tv/ui/layouts.jd
deleted file mode 100644
index b9ca7b9..0000000
--- a/docs/html/preview/tv/ui/layouts.jd
+++ /dev/null
@@ -1,298 +0,0 @@
-page.title=Layouts for TV
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#themes">Themes</a>
- <ol>
- <li><a href="#leanback-theme">Leanback Theme</a></li>
- <li><a href="#notitle-theme">NoTitleBar Theme</a></li>
- </ol>
- </li>
- <li><a href="#structure">Layout Structure</a>
- <ol>
- <li><a href="#overscan">Overscan</a></li>
- </ol>
- </li>
- <li><a href="#visibility">Text and Controls Visibility</a></li>
- <li><a href="#density-resources">Screen Density and Image Resources</a></li>
- <li><a href="#anti-patterns">Layout Anti-Patterns</a></li>
- <li><a href="#large-bitmaps">Handling Large Bitmaps</a></li>
- </ol>
-
-</div>
-</div>
-
-<p>
- A TV screen is typically viewed from about 10 feet away, and while it is much larger than most
- other Android device displays, this type of screen does not provide the same level of precise
- detail and color as a smaller device. These factors require that you create app layouts with
- TV devices in mind in order to create a useful and enjoyable user experience.</p>
-
-<p>This guide provides direction and implementation details for building effective layouts inN
- TV apps.</p>
-
-
-<h2 id="themes">Themes</h2>
-
-<p>Android <a href="{@docRoot}guide/topics/ui/themes.html">Themes</a> can provide a basis for
- layouts in your TV apps. You should use a theme to modify the display of your app activities
- that are meant to run on a TV device. This section explains which themes you should use.</p>
-
-
-<h3 id="leanback-theme">Leanback Theme</h3>
-
-<p>The Leanback library provides a standard theme for TV activities, called {@code
- Theme.Leanback}, which establishes a consistent visual style for TV apps. Use of this theme is
- recommended for most apps. This theme is recommended for any TV app that uses the Leanback
- library classes. The following code sample shows how to apply this theme to a given
- activity within an app:</p>
-
-<pre>
-<activity
- android:name="com.example.android.TvActivity"
- android:label="@string/app_name"
- <strong>android:theme="@style/Theme.Leanback"</strong>>
-</pre>
-
-
-<h3 id="notitle-theme">NoTitleBar Theme</h3>
-
-<p>The title bar is a standard user interface element for Android apps on phones and tablets,
- but it is not appropriate for TV apps. If you are not using the Leanback library classes,
- you should apply this theme to your TV activities. The following code example from a TV app
- manifest demonstrates how to apply this theme to remove the display of a title bar:
-</p>
-
-<pre>
-<application>
- ...
-
- <activity
- android:name="com.example.android.TvActivity"
- android:label="@string/app_name"
- <strong>android:theme="@android:style/Theme.NoTitleBar"</strong>>
- ...
-
- </activity>
-</application>
-</pre>
-
-
-<h2 id="structure">Layout Structure</h2>
-
-<p>Layouts for TV devices should follow some basic guidelines to ensure they are usable and
- effective on large screens. Follow these tips to build landscape layouts optimized for TV screens:
-</p>
-
-<ul>
- <li>Build layouts with a landscape orientation. TV screens always display in landscape.</li>
- <li>Put on-screen navigation controls on the left or right side of the screen and save the
- vertical space for content.</li>
- <li>Create UIs that are divided into sections, using <a
- href="{@docRoot}guide/components/fragments.html"
- >Fragments</a>, and use view groups like {@link android.widget.GridView} instead of {@link
- android.widget.ListView} to make better use of the horizontal screen space.
- </li>
- <li>Use view groups such as {@link android.widget.RelativeLayout} or {@link
- android.widget.LinearLayout} to arrange views. This approach allows the system to adjust the
- position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.</li>
- <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
-</ul>
-
-
-<h3 id="overscan">Overscan</h3>
-
-<p>Layouts for TV have some unique requirements due to the evolution of TV standards and the
- desire to always present a full screen picture to viewers. For this reason, TV devices may
- clip the outside edge of an app layout in order to ensure that the entire display is filled.
- This behavior is generally referred to as Overscan.</p>
-
-<p>In order to account for the impact of overscan and make sure that all the user interface
- elements you place in a layout are actually shown on screen, you should incorporate a 10% margin
- on all sides of your layout. This translates into a 27dp margin on the left and right edges and
- a 48dp margin on the top and bottom of your base layouts for activities. The following
- example layout demonstrates how to set these margins in the root layout for a TV app:
-</p>
-
-<pre>
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/base_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="27dp"
- android:layout_marginLeft="48dp"
- android:layout_marginRight="48dp"
- android:layout_marginBottom="27dp" >
-</LinearLayout>
-</pre>
-
-<p class="caution">
- <strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the
- Leanback Support Library {@code BrowseFragment} or related widgets, as those layouts already
- incorporate overscan-safe margins.
-</p>
-
-
-<h2 id="visibility">Text and Controls Visibility</h2>
-
-<p>
-The text and controls in a TV app layout should be easily visible and navigable from a distance.
-Follow these tips to make them easier to see from a distance :
-</p>
-
-<ul>
- <li>Break text into small chunks that users can quickly scan.</li>
- <li>Use light text on a dark background. This style is easier to read on a TV.</li>
- <li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes.
- Use simple sans-serif fonts and anti-aliasing to increase readability.</li>
- <li>Use Android's standard font sizes:
-<pre>
-<TextView
- android:id="@+id/atext"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
-</pre>
- </li>
- <li>Ensure that all your view widgets are large enough to be clearly visible to someone
- sitting 10 feet away from the screen (this distance is greater for very large screens). The
- best way to do this is to use layout-relative sizing rather than absolute sizing, and
- density-independent pixel units instead of absolute pixel units. For example, to set the
- width of a widget, use wrap_content instead of a pixel measurement, and to set the margin
- for a widget, use dip instead of px values.</li>
-</ul>
-
-
-<h2 id="density-resources">Screen Density and Image Resources</h2>
-
-<p>The common high-definition TV display resolutions are 720p, 1080i, and 1080p.
- Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android
- system to downscale your layout elements to 720p if necessary. In general, downscaling
- (removing pixels) does not degrade your layout presentation quality. However, upscaling can
- cause display artifacts that degrade the quality of your layout and have a negative impact on
- the user experience of your app.</p>
-
-<p>
- To get the best scaling results for images, provide them as
- <a href="{@docRoot}tools/help/draw9patch.html">9-patch image</a> elements if possible. If you
- provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or
- grainy. This is not a good experience for the user. Instead, use high-quality images.
-</p>
-
-<p>
- For more information on optimizing layouts and resources for large screens see
- <a href="{@docRoot}training/multiscreen/index.html">Designing for multiple screens</a>.
-</p>
-
-
-<h2 id="anti-patterns">Layout Anti-Patterns</h2>
-
-<p>There are a few approaches to building layouts for TV that you should avoid because they do not
-work well and lead to bad user experiences. Here are some user interface approaches you
-should specifically <em>not</em> use when developing a layout for TV.
-</p>
-
-<ul>
- <li><strong>Re-using phone or tablet layouts</strong> - Do not reuse layouts from a phone or
- tablet app without modification. Layouts built for other Android device form factors are not
- well suited for TV devices and should be simplified for operation on a TV.</li>
- <li><strong>ActionBar</strong> - While this user interface convention is recommended for use
- on phones and tablets, it is not appropriate for a TV interface. In particular, using an
- action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due
- to the difficulty in navigating such a menu with a remote control.</li>
- <li><strong>ViewPager</strong> - Sliding between screens can work great on a phone or tablet,
- but don't try this on a TV!</li>
-
-</ul>
-
-<p>For more information on designing layouts that are appropriate to TV, see the
- <a href="{@docRoot}design/tv/index.html">TV Design</a> guide.</p>
-
-
-<h2 id="large-bitmaps">Handling Large Bitmaps</h2>
-
-<p>TV devices, like any other Android device, have a limited amount of memory. If you build your
- app layout with very high-resolution images or use many high-resolution images in the operation
- of your app, it can quickly run into memory limits and cause out of memory errors.
- To avoid these types of problems, follow these tips:</p>
-
-<ul>
- <li>Load images only when they're displayed on the screen. For example, when displaying multiple images in
- a {@link android.widget.GridView} or
- {@link android.widget.Gallery}, only load an image when
- {@link android.widget.Adapter#getView(int, View, ViewGroup) getView()}
- is called on the View's {@link android.widget.Adapter}.
- </li>
- <li>Call {@link android.graphics.Bitmap#recycle()} on
- {@link android.graphics.Bitmap} views that are no longer needed.
- </li>
- <li>Use {@link java.lang.ref.WeakReference} for storing references
- to {@link android.graphics.Bitmap} objects in an in-memory
- {@link java.util.Collection}.</li>
- <li>If you fetch images from the network, use {@link android.os.AsyncTask}
- to fetch and store them on the device for faster access.
- Never do network transactions on the application's UI thread.
- </li>
- <li>Scale down large images to a more appropriate size as you download them;
- otherwise, downloading the image itself may cause an out of memory exception.
- The following sample code demonstrates how to scale down images while downloading:
-<pre>
- // Get the source image's dimensions
- BitmapFactory.Options options = new BitmapFactory.Options();
- // This does not download the actual image, just downloads headers.
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
- // The actual width of the image.
- int srcWidth = options.outWidth;
- // The actual height of the image.
- int srcHeight = options.outHeight;
-
- // Only scale if the source is bigger than the width of the destination view.
- if(desiredWidth > srcWidth)
- desiredWidth = srcWidth;
-
- // Calculate the correct inSampleSize/scale value. This approach helps reduce
- // memory use. This value should be a power of 2.
- int inSampleSize = 1;
- while(srcWidth / 2 > desiredWidth){
- srcWidth /= 2;
- srcHeight /= 2;
- inSampleSize *= 2;
- }
-
- float desiredScale = (float) desiredWidth / srcWidth;
-
- // Decode with inSampleSize
- options.inJustDecodeBounds = false;
- options.inDither = false;
- options.inSampleSize = inSampleSize;
- options.inScaled = false;
- // Ensures the image stays as a 32-bit ARGB_8888 image.
- // This preserves image quality.
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-
- Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
-
- // Resize
- Matrix matrix = new Matrix();
- matrix.postScale(desiredScale, desiredScale);
- Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
- sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
- sampledSrcBitmap = null;
-
- // Save
- FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
- scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
- scaledBitmap = null;
-</pre>
- </li>
-</ul>
-
diff --git a/docs/html/preview/tv/ui/navigation.jd b/docs/html/preview/tv/ui/navigation.jd
deleted file mode 100644
index 684b743..0000000
--- a/docs/html/preview/tv/ui/navigation.jd
+++ /dev/null
@@ -1,136 +0,0 @@
-page.title=Navigation for TV
-
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#d-pad-navigation">D-pad Navigation</a></li>
- <li><a href="#focus-selection">Focus and Selection</a></li>
- </ol>
-
-</div>
-</div>
-
-<p>TV devices provide a limited set of navigation controls for apps. Creating an effective
- navigation scheme for your TV app depends on understanding these limited controls and the limits
- of users' perception while operating your app. As you build your Android app for TVs,
- you should pay special attention to how the user actually navigates around your app
- when using remote control buttons instead of a touch screen.</p>
-
-<p>This guide shows you how to build an effective navigation scheme for your TV app.</p>
-
-
-<h2 id="d-pad-navigation">D-pad Navigation</h2>
-
-<p>On a TV device, users navigate with controls on a remote control device, using either a
- directional pad (D-pad) or arrow keys. This type of control limits movement to up, down, left,
- and right. To build a great TV-optimized app, you must provide a navigation scheme where
- the user can quickly learn how to navigate your app using these limited controls.</p>
-
-<p>Follow these guidelines to build a navigation system that works well with a D-pad on a TV device:
-</p>
-
-<ul>
- <li>Ensure that the D-pad can navigate to all the visible controls on the screen.</li>
- <li>For scrolling lists with focus, D-pad up/down keys scroll the list, and the Enter key selects
- an item in the list. Ensure that users can select an element in the list and that the list still
- scrolls when an element is selected.</li>
- <li>Ensure that movement between controls is straightforward and predictable.</li>
-</ul>
-
-<p>The Android framework handles directional navigation between layout elements automatically, so
- you typically do not need to do anything extra for your app. However, you should thoroughly test
- navigation with a D-pad control to discover any navigation problems. If you discover that your
- screen layout makes navigation difficult, or if you want users to move through the layout in a
- specific way, you can set up explicit directional navigation for your controls. The following
- code sample shows how to define the next control to receive focus for a
- {@link android.widget.TextView} layout object:</p>
-
-<pre>
-<TextView android:id="@+id/Category1"
- android:nextFocusDown="@+id/Category2"\>
-</pre>
-
-<p>The following table lists all of the available navigation attributes for Android user interface
-widgets:</p>
-
-<table>
- <tr>
- <th>Attribute</th>
- <th>Function</th>
- </tr>
- <tr>
- <td>{@link android.R.attr#nextFocusDown}</td>
- <td>Defines the next view to receive focus when the user navigates down.</td>
- </tr>
- <tr>
- <td>{@link android.R.attr#nextFocusLeft}</td>
- <td>Defines the next view to receive focus when the user navigates left.</td>
- </tr>
- <tr>
- <td>{@link android.R.attr#nextFocusRight}</td>
- <td>Defines the next view to receive focus when the user navigates right.</td>
- </tr>
- <tr>
- <td>{@link android.R.attr#nextFocusUp}</td>
- <td>Defines the next view to receive focus when the user navigates up.</td>
- </tr>
-</table>
-
-<p>To use one of these explicit navigation attributes, set the value to the ID ({@code android:id}
- value) of another widget in the layout. You should set up the navigation order as a loop, so that
- the last control directs focus back to the first one.</p>
-
-<p class="note">
- <strong>Note:</strong> You should only use these attributes to modify the navigation order if the
- default order that the system applies does not work well.
-</p>
-
-
-<h2 id="focus-selection">Focus and Selection</h2>
-
-<p>The success of a navigation scheme on TV devices is strongly dependent on how easy it is for a
- user to determine what user interface element is in focus on screen. If you do not provide clear
- indications of what is in focus on screen (and therefore what item they can take action on),
- users can quickly become frustrated and exit your app. By the same token, it is important
- to always have an item in focus that a user can take action on immediately after your app starts,
- and any time your app is not playing content.</p>
-
-<p>Your app layout and implementation should use color, size, animation, or a combination of
- these attributes to help users easily determine what actions they can take next. Use a uniform
- scheme for indicating focus across your application.</p>
-
-<p>Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">
-Drawable State List Resources</a> to implement highlights for selected and focused controls. The
-following code example demonstrates how to indicate selection of a button object:
-</p>
-
-<pre>
-<!-- res/drawable/button.xml -->
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true"
- android:drawable="@drawable/button_pressed" /> <!-- pressed -->
- <item android:state_focused="true"
- android:drawable="@drawable/button_focused" /> <!-- focused -->
- <item android:state_hovered="true"
- android:drawable="@drawable/button_focused" /> <!-- hovered -->
- <item android:drawable="@drawable/button_normal" /> <!-- default -->
-</selector>
-</pre>
-
-<p>
-This layout XML applies the above state list drawable to a {@link android.widget.Button}:
-</p>
-<pre>
-<Button
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/button" />
-</pre>
-
-<p>Make sure to provide sufficient padding within the focusable and selectable controls so that
- the highlights around them are clearly visible.</p>
-
diff --git a/docs/html/samples/images/ActivitySceneTransitionBasic.png b/docs/html/samples/images/ActivitySceneTransitionBasic.png
new file mode 100644
index 0000000..ea58641
--- /dev/null
+++ b/docs/html/samples/images/ActivitySceneTransitionBasic.png
Binary files differ
diff --git a/docs/html/samples/images/ActivitySceneTransitionBasic@2x.png b/docs/html/samples/images/ActivitySceneTransitionBasic@2x.png
new file mode 100644
index 0000000..cd28ade
--- /dev/null
+++ b/docs/html/samples/images/ActivitySceneTransitionBasic@2x.png
Binary files differ
diff --git a/docs/html/samples/images/BasicManagedProfile.png b/docs/html/samples/images/BasicManagedProfile.png
new file mode 100644
index 0000000..7354842
--- /dev/null
+++ b/docs/html/samples/images/BasicManagedProfile.png
Binary files differ
diff --git a/docs/html/samples/images/BasicManagedProfile@2x.png b/docs/html/samples/images/BasicManagedProfile@2x.png
new file mode 100644
index 0000000..c232809
--- /dev/null
+++ b/docs/html/samples/images/BasicManagedProfile@2x.png
Binary files differ
diff --git a/docs/html/samples/images/JobSchedulerSample.png b/docs/html/samples/images/JobSchedulerSample.png
new file mode 100644
index 0000000..ee57bdb
--- /dev/null
+++ b/docs/html/samples/images/JobSchedulerSample.png
Binary files differ
diff --git a/docs/html/samples/images/JobSchedulerSample@2x.png b/docs/html/samples/images/JobSchedulerSample@2x.png
new file mode 100644
index 0000000..3d543db
--- /dev/null
+++ b/docs/html/samples/images/JobSchedulerSample@2x.png
Binary files differ
diff --git a/docs/html/samples/index.jd b/docs/html/samples/index.jd
index ab15e32..a44a22b 100644
--- a/docs/html/samples/index.jd
+++ b/docs/html/samples/index.jd
@@ -1,5 +1,5 @@
page.title=Samples
-page.tags=samples,examples,code
+page.tags="examples","code"
@jd:body
diff --git a/docs/html/samples/new/index.jd b/docs/html/samples/new/index.jd
new file mode 100644
index 0000000..ca44775
--- /dev/null
+++ b/docs/html/samples/new/index.jd
@@ -0,0 +1,237 @@
+page.title=What's New
+
+@jd:body
+
+<p>The following code samples were recently published for the L Developer Preview. You can
+download them in the Android SDK Manager under the <b>SDK Samples</b> component
+for the L Developer Preview.</p>
+
+<p class="note">
+ <strong>Note:</strong> At this time, the downloadable projects are designed
+ for use with Gradle and Android Studio.
+</p>
+
+
+<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
+<div class="figure" style="width:220px">
+ <img src="{@docRoot}samples/images/BasicManagedProfile.png"
+ srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
+ alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure 1.</strong> The BasicManagedProfile sample app.
+ </p>
+</div>
+
+<p>This sample demonstrates how to create a managed profile. You can also:</p>
+<ul>
+ <li>Enable or disable other apps, and set restrictions on them.</li>
+ <li>Configure intents to be forwarded between the primary account and the
+ managed profile.</li>
+ <li>Wipe all the data associated with the managed profile.</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> There can be only one managed profile on
+ a device at a time.</p>
+
+<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
+
+<h3 id="Camera2Basic">Camera2Basic</h3>
+
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>This sample demonstrates the basic use of the Camera2 API. The sample code
+demonstrates how you can display camera preview and take pictures.</p>
+
+<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
+
+
+<h3 id="Camera2Video">Camera2Video</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>This sample demonstrates how to record video using the Camera2 API.</p>
+
+<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
+
+<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
+<div class="figure" style="width:220px">
+ <img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
+ srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
+ alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure 2.</strong> The ActivitySceneTransitionBasic sample app.
+ </p>
+ </div>
+
+<p> This sample demonstrates how to the use {@link android.app.Activity} scene
+transitions when transitioning from one activity to another. Uses a combination
+of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
+from a grid of images to an activity with a large image and detail text. </p>
+
+<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
+
+<h3 id="ElevationBasic">ElevationBasic</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample demonstrates two alternative ways to move a view in the z-axis:</p>
+
+<ul>
+ <li>With a fixed elevation, using XML.</li>
+ <li>Raising the elevation when the user taps on it, using
+ <code>setTranslationZ()</code>.</li>
+</ul>
+
+<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
+
+<h3 id="ElevationDrag">ElevationDrag</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>This sample demonstrates a drag and drop action on different shapes.
+Elevation and z-translation are used to render the shadows. The views are
+clipped using different outlines.</p>
+
+<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
+
+
+<h3 id="ClippingBasic">ClippingBasic</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample demonstrates clipping on a {@link android.view.View}.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-ClippingBasic">Get it on GitHub</a></p>
+
+<div class="figure" style="width:220px">
+ <img src="{@docRoot}samples/images/JobSchedulerSample.png"
+ srcset="{@docRoot}samples/images/JobSchedulerSample@2x.png 2x"
+ alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure 3.</strong> The JobSchedulerSample sample app.
+ </p>
+</div>
+
+<h3 id="GameControllerSample">GameControllerSample</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample implements a multi-player game, demonstrating game controller input
+handling.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
+
+
+<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample displays events received from a game controller shown on the screen.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
+
+<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample demonstrates use of the Android TV Leanback Support Library.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
+
+<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
+
+<p>
+This sample app allows the user to schedule jobs through the UI, and shows
+visual cues when the jobs are executed.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
+
+<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample illustrates a common usage of the Android support library's
+{@link android.support.v4.widget.DrawerLayout} widget.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
+<!--
+<h3 id="">SampleName</h3>
+
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+
+<p>
+**description**
+</p>
+-->
diff --git a/docs/html/samples/samples_toc.cs b/docs/html/samples/samples_toc.cs
index 2007f22..976a7ca 100644
--- a/docs/html/samples/samples_toc.cs
+++ b/docs/html/samples/samples_toc.cs
@@ -10,5 +10,10 @@
<span class="en">About the Samples</span></a>
</div>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>samples/new/index.html">
+ <span class="en">What's New</span></a>
+ </div>
+ </li>
<?cs var:samples_toc_tree ?>
</ul>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 9ed70ed..d91e7e8 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -308,7 +308,7 @@
If you're a new Android developer, you should consider starting with Android Studio, because the
ADT plugin for Eclipse is no longer in active development.</p>
<p style="margin: 0;">
- <a href="/sdk/installing/studio.html">Learn more about Android Studio</a></p>
+ <a href="/sdk/installing/studio.html" style="position:relative;z-index:99">Learn more about Android Studio</a></p>
</div>
diff --git a/docs/html/training/articles/perf-tips.jd b/docs/html/training/articles/perf-tips.jd
index 1660b7f..e9df51b 100644
--- a/docs/html/training/articles/perf-tips.jd
+++ b/docs/html/training/articles/perf-tips.jd
@@ -388,7 +388,7 @@
the JIT makes the two effectively indistinguishable.</p>
<p>On devices without a JIT, caching field accesses is about 20% faster than
-repeatedly accesssing the field. With a JIT, field access costs about the same
+repeatedly accessing the field. With a JIT, field access costs about the same
as local access, so this isn't a worthwhile optimization unless you feel it
makes your code easier to read. (This is true of final, static, and static
final fields too.)
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 5443c56..12685ba 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -839,6 +839,91 @@
<!-- End Building for wearables -->
+ <!-- Start: Building for TV -->
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/index.html">
+ <span class="small">Building Apps for</span><br/>
+ TV
+ </a>
+ </div>
+ <ul>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+
+ <a href="<?cs var:toroot ?>training/tv/start/index.html"
+ description="How to start building TV apps or extend your existing app to run on TV
+ devices.">
+ Building TV Apps</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/start.html">
+ Getting Started with TV Apps</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/hardware.html">
+ Handling TV Hardware</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/layouts.html">
+ Building TV Layouts</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/navigation.html">
+ Creating TV Navigation</a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/playback/index.html"
+ description="How to build apps that provide media catalogs and play content.">
+ Building TV Playback Apps</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/browse.html">
+ Creating a Catalog Browser</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/details.html">
+ Building a Details View</a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/discovery/index.html"
+ description="How to help users discovery content from your app.">
+ Helping Users Find Content on TV</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/recommendations.html">
+ Recommending TV Content</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/in-app-search.html">
+ Searching within TV Apps</a>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/games/index.html"
+ description="How to build games for TV.">
+ Building TV Games</a>
+ </li>
+
+ </ul>
+ </li>
+ <!-- End: Building for TV -->
+
+
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/best-ux.html">
@@ -1046,29 +1131,6 @@
</li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>training/tv/index.html"
- description=
- "How to optimize your app's user interface and user input for
- the "ten foot experience" of a TV screen."
- >Designing for TV</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
- Optimizing Layouts for TV
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
- Optimizing Navigation for TV
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
- Handling Features Not Supported on TV
- </a>
- </li>
- </ul>
- </li>
-
- <li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/custom-views/index.html"
description=
diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd
new file mode 100644
index 0000000..28c7a35
--- /dev/null
+++ b/docs/html/training/tv/discovery/in-app-search.jd
@@ -0,0 +1,145 @@
+page.title=Searching within TV Apps
+page.tags="leanback"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#add-search-action">Add a Search Action</a></li>
+ <li><a href="#add-search-ui">Add Search Input and Results</a></li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>
+ Users frequently have specific content in mind when using a media app on TV. If your app contains
+ a large catalog of content, browsing for a specific title may not be the most efficient way for
+ users to find what they are looking for. A search interface can help your users get to the
+ content they want faster than browsing.
+</p>
+
+<p>
+ The <a href="{@docRoot}tools/support-library/features.html#v17-leanback">Leanback support
+ library</a> provides a set of classes to enable a standard search interface within your app that
+ is consistent with other search functions on TV and provides features such as voice input.
+</p>
+
+<p>
+ This lesson discusses how to provide a search interface in your app using Leanback support
+ library classes.
+</p>
+
+
+<h2 id="add-search-action">Add a Search Action</h2>
+
+<p>
+ When you use the {@link android.support.v17.leanback.app.BrowseFragment} class for a media
+ browsing interface, you can enable a search interface as a standard part of the user
+ interface. The search interface is an icon that appears in the layout when you set {@link
+ android.view.View.OnClickListener} on the {@link android.support.v17.leanback.app.BrowseFragment}
+ object. The following sample code demonstrates this technique.
+</p>
+
+<pre>
+@Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_activity);
+
+ mBrowseFragment = (BrowseFragment)
+ getFragmentManager().findFragmentById(R.id.browse_fragment);
+
+ ...
+
+ mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ mBrowseFragment.setAdapter(buildAdapter());
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> You can set the color of the search icon using the
+ {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}.
+</p>
+
+
+<h2 id="add-search-ui">Add a Search Input and Results</h2>
+
+<p>
+ When a user selects the search icon, the system invokes a search activity via the defined intent.
+ Your search activity should use a linear layout containing a {@link
+ android.support.v17.leanback.app.SearchFragment}. This fragment must also implement the {@link
+ android.support.v17.leanback.app.SearchFragment.SearchResultProvider} interface in order to
+ display the results of a search.
+</p>
+
+<p>
+ The following code sample shows how to extend the {@link
+ android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results:
+</p>
+
+<pre>
+public class MySearchFragment extends SearchFragment
+ implements SearchFragment.SearchResultProvider {
+
+ private static final int SEARCH_DELAY_MS = 300;
+ private ArrayObjectAdapter mRowsAdapter;
+ private Handler mHandler = new Handler();
+ private SearchRunnable mDelayedLoad;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ setSearchResultProvider(this);
+ setOnItemClickedListener(getDefaultItemClickedListener());
+ mDelayedLoad = new SearchRunnable();
+ }
+
+ @Override
+ public ObjectAdapter getResultsAdapter() {
+ return mRowsAdapter;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newQuery) {
+ mRowsAdapter.clear();
+ if (!TextUtils.isEmpty(newQuery)) {
+ mDelayedLoad.setSearchQuery(newQuery);
+ mHandler.removeCallbacks(mDelayedLoad);
+ mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ mRowsAdapter.clear();
+ if (!TextUtils.isEmpty(query)) {
+ mDelayedLoad.setSearchQuery(query);
+ mHandler.removeCallbacks(mDelayedLoad);
+ mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ }
+ return true;
+ }
+}
+</pre>
+
+<p>
+ The example code shown above is meant to be used with a separate {@code SearchRunnable} class
+ that runs the search query on a separate thread. This technique keeps potentially slow-running
+ queries from blocking the main user interface thread.
+</p>
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
new file mode 100644
index 0000000..fbc8c9f
--- /dev/null
+++ b/docs/html/training/tv/discovery/index.jd
@@ -0,0 +1,48 @@
+page.title=Helping Users Find Content on TV
+
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ </ul>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}design/tv/index.html">
+ Design for TV</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ TV devices offer many entertainment options for users. They have thousands of content options
+ from apps and related content services. At the same time, most users prefer to use TVs with the
+ least amount of input possible. With the amount of choice available to users, it is important for
+ app developers to provide quick and easy paths for users to discover and enjoy your content.
+</p>
+
+<p>
+ The Android framework helps you provide a number of paths for users to discover your content,
+ including recommendations on the home screen and searching within your app's content catalog.
+</p>
+
+<p>
+ This class shows you how to help users discover your app's content through recommendations and
+ in-app searching.
+</p>
+
+
+<h2>Topics</h2>
+
+<dl>
+ <dt><b><a href="recommendations.html">Recommending TV Content</a></b></dt>
+ <dd>Learn how to recommend content for users so that it appears in the recommendations row
+ on the home screen of a TV device.</dd>
+
+ <dt><b><a href="in-app-search.html">Searching within TV Apps</a></b></dt>
+ <dd>Learn how to use a built-for-TV user interface for searching within your app.</dd>
+</dl>
diff --git a/docs/html/preview/tv/ui/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
similarity index 65%
rename from docs/html/preview/tv/ui/recommendations.jd
rename to docs/html/training/tv/discovery/recommendations.jd
index a2ff55c..048b649 100644
--- a/docs/html/preview/tv/ui/recommendations.jd
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -1,39 +1,57 @@
-page.title=Making Recommendations
+page.title=Recommending TV Content
+page.tags="recommendation","recommend"
+
+trainingnavtop=true
@jd:body
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
<ol>
<li><a href="#service">Create a Recommendations Service</a></li>
<li><a href="#build">Build Recommendations</a></li>
<li><a href="#run-service">Run Recommendations Service</a></li>
</ol>
-
</div>
</div>
+<p>
+ When interacting with TVs, users generally prefer to give minimal input before watching
+ content. An ideal scenario for many TV users is: sit down, turn on, and watch. The fewest steps
+ to get users to content they enjoy is generally the path they prefer.
+</p>
-<p>Content recommendations appear as the first row of the TV launch screen after the first use
- of the device. This row is intended to help users quickly find content they enjoy. Contributing
- recommendations from your apps content catalog can help bring users back to your app.</p>
-
+<p>
+ The Android framework assists with minimum-input interaction by providing a recommendations row
+ on the home screen. Content recommendations appear as the first row of the TV launch screen after
+ the first use of the device. Contributing recommendations from your app's content catalog can help
+ bring users back to your app.
+</p>
<img src="{@docRoot}preview/tv/images/home-recommendations.png" alt="" id="figure1" />
<p class="img-caption">
<strong>Figure 1.</strong> An example of the recommendations row.
</p>
+<p>
+ This lesson teaches you how to create recommendations and provide them to the Android framework
+ so your app content can be easily discovered and enjoyed by users.
+</p>
+
<h2 id="service">Create a Recommendations Service</h2>
-<p>Content recommendations are created with background processing. In order for your application
- to contribute to recommendations, you create a service that periodically adds listings from your
- app's catalog to the system list of recommendations.</p>
+<p>
+ Content recommendations are created with background processing. In order for your application to
+ contribute to recommendations, create a service that periodically adds listings from your
+ app's catalog to the system list of recommendations.
+</p>
-<p>The following code example illustrates how to extend the {@link android.app.IntentService} to
- create a recommendation service for your application.</p>
+<p>
+ The following code example illustrates how to extend {@link android.app.IntentService} to
+ create a recommendation service for your application:
+</p>
<pre>
public class RecommendationsService extends IntentService {
@@ -66,9 +84,10 @@
}
</pre>
-<p>In order for this class to be recognized and run as a service, you must register this service
- using your app manifest. The following code snippet illustrates how to add this class as a
- service:</p>
+<p>
+ In order for this service to be recognized by the system and run, register it using your
+ app manifest. The following code snippet illustrates how to declare this class as a service:
+</p>
<pre>
<manifest ... >
@@ -81,14 +100,20 @@
</manifest>
</pre>
+
<h2 id="build">Build Recommendations</h2>
-<p>Once it starts running, your service must create recommendations and pass them to the Android
- framework. The framework receives the recommendations as {@link android.app.Notification} objects
- that use a specific style and are marked with a specific category.</p>
+<p>
+ Once your recommendation server starts running, it must create recommendations and pass them to
+ the Android framework. The framework receives the recommendations as {@link
+ android.app.Notification} objects that use a specific template and are marked with a specific
+ category.
+</p>
-<p>The following code example demonstrates how to get an instance of the {@link
- android.app.NotificationManager}, build a recommendation, and post it to the manager:</p>
+<p>
+ The following code example demonstrates how to get an instance of the {@link
+ android.app.NotificationManager}, build a recommendation, and post it to the manager:
+</p>
<pre>
public class RecommendationsService extends IntentService {
@@ -113,8 +138,11 @@
new NotificationCompat.Builder(context)
.setContentTitle(movie.getTitle())
.setContentText(movie.getDescription())
+ .setContentInfo(APP_NAME)
+ .setGroup("ActionMovies")
+ .setSortKey("0.8")
.setPriority(movie.getPriority())
- .setOngoing(true)
+ .setColor(#FFFF2020)
.setCategory("recommendation")
.setLargeIcon(movie.getImage())
.setSmallIcon(movie.getSmallIcon())
@@ -148,11 +176,13 @@
<h3 id="run-service">Run Recommendations Service</h3>
-<p>Your app's recommendation service must run periodically in order to create current
- recommendations. In order to run your service, you should create a class that runs a timer and
- invokes it at regular intervals. The following code example extends the {@link
+<p>
+ Your app's recommendation service must run periodically in order to create current
+ recommendations. To run your service, create a class that runs a timer and invokes
+ it at regular intervals. The following code example extends the {@link
android.content.BroadcastReceiver} class to start periodic execution of a recommendation service
- every 12 hours:</p>
+ every 12 hours:
+</p>
<pre>
public class BootupReceiver extends BroadcastReceiver {
@@ -183,10 +213,12 @@
}
</pre>
-<p>In order for the {@link android.content.BroadcastReceiver} class to execute after a TV
- device starts up, you must register this class in your app manifest and attach an intent filter
- in order for the device boot process to complete. This sample code demonstrates how to add this
- configuration to the manifest:</p>
+<p>
+ This implementation of the {@link android.content.BroadcastReceiver} class must run after start
+ up of the TV device where it is installed. To accomplish this, register this class in your app
+ manifest with an intent filter that listens for the completion of the device boot process. The
+ following sample code demonstrates how to add this configuration to the manifest:
+</p>
<pre>
<manifest ... >
@@ -203,6 +235,6 @@
<p class="important">
<strong>Important:</strong> Receiving a boot completed notification requires that your app
- request the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission.
+ requests the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission.
For more information, see {@link android.content.Intent#ACTION_BOOT_COMPLETED}.
</p>
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
new file mode 100644
index 0000000..29b055b
--- /dev/null
+++ b/docs/html/training/tv/games/index.jd
@@ -0,0 +1,282 @@
+page.title=Building TV Games
+page.tags="controller"
+page.article=true
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#display">Display</a></li>
+ <li><a href="#control">Input Devices</a></li>
+ <li><a href="#manifest">Manifest</a></li>
+ <li><a href="#gpgs">Google Play Game Services</a></li>
+ <li><a href="#web">Web</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ The television screen presents a number of considerations that may be new to mobile game
+ developers. These areas include its large size, its control scheme, and the fact that all players
+ are viewing it simultaneously.
+</p>
+
+
+<h2 id="display">Display</h2>
+<p>
+ The two main things to keep in mind when developing games for the TV screen are its nature as a
+ shared display and the need to design your game for a landscape orientation.
+</p>
+
+
+<h3 id="shared-display">Shared display</h3>
+
+<p>
+ A living-room TV poses design challenges for multiplayer games, in that all players can see
+ everything. This issue is especially relevant to games (such as card games or strategy games)
+ that rely on each player’s possession of hidden information.
+</p>
+
+<p>
+ Some mechanisms you can implement to address the problem of one player’s eavesdropping on
+ another’s information are:
+</p>
+
+<ul>
+ <li>A blinder on the screen to help conceal information. For example, in a turn-based game like a
+ word or card game, one player at a time might view the display. When the player finishes a move,
+ the game allows him or her to cover the screen with a blinder that blocks anyone from viewing
+ secret information. When the next player begins a turn, the blinder opens to reveal his or her
+ own information.
+ </li>
+ <li>A companion app, running on a phone or tablet, can enable a player to conceal information by
+ serving as a second screen.
+ </li>
+</ul>
+
+
+<h3 id="landscape-display">Landscape display</h3>
+
+<p>
+ A TV is always sideways: You can’t turn it, and there is no portrait orientation. Always design
+ your TV games to be displayed in landscape mode.
+</p>
+
+
+<h2 id="control">Input Devices</h2>
+
+<p>
+ TVs don't have touch interfaces, so it's even more important to get your controls right and make
+ sure that players find them intuitive and fun to use. The separation of controller from device
+ also introduces some other issues to pay attention to, like keeping track of multiple players'
+ controllers, and handling disconnects gracefully.
+</p>
+
+<h3 id="d-pad">D-pad</h3>
+
+<p>
+ Plan your control scheme around a directional pad (D-pad) control, since this control set is the
+ default for Android TV devices. The player needs to be able to use a D-Pad in all aspects of the
+ game–not just controlling core gameplay, but also navigating menus and ads. For this reason, you
+ should also ensure that your Android TV game does not refer to a touch interface: For example, an
+ Android TV game should not tell a player to <strong>Tap here to skip</strong>.
+</p>
+
+<p>
+ How you shape the player's interaction with the controller can be key to achieving a great user
+ experience:
+</p>
+
+<ul>
+ <li>
+ <strong>Communicate Controller Requirements up Front</strong> - Use your Play Store description
+ to communicate to the player any expectations about controllers. If a game is better suited to
+ a gamepad with a joystick than one with only a D-pad, make this fact clear. A player who uses
+ an ill-suited controller for a game is likely to have a subpar experience–and penalize your
+ game in the ratings.
+ </li>
+ <li>
+ <strong>Use Consistent Button Mapping</strong> - Intuitive and flexible button mapping is key
+ to a good user experience. For example, you can adhere to accepted custom by using the A button
+ to <code>Accept</code>, and the B button to <code>Cancel</code>. You can also offer flexibility
+ in the form of remappability. For more information on button mapping, see <a href=
+ "http://developer.android.com/training/game-controllers/controller-input.html">Handling
+ Controller Actions</a>.
+ </li>
+ <li>
+ <strong>Detect Controller Capabilities and Adjust Accordingly</strong> - Query the controller
+ about its capabilities in order to optimize the match between controller and game. For example,
+ you may intend for a player to steer an object by waving the controller in the air. If a
+ player's controller lacks accelerometer and gyroscope hardware, however, waving will not work.
+ When, however, your game queries the controller and discovers that motion detection is not
+ supported, it can switch over to an alternative, available control scheme. For more information
+ on querying controller capabilities, see <a href=
+ "http://developer.android.com/training/game-controllers/compatibility.html">Supporting
+ Controllers Across Android Versions</a>.
+ </li>
+</ul>
+
+
+<h3 id="back-button">Back-button behavior</h3>
+
+<p>
+ The Back button should never act as a toggle. For example, do not use it to both open and close a
+ menu. It should only navigate backward, breadcrumb-style, through the previous screens the player
+ has been on, for example: Game play > Game pause screen > Game main screen > Android
+ home screen.
+</p>
+
+<p>
+ Since the Back button should only perform linear (backward) navigation, you may use the back
+ button to leave an in-game menu (opened by a different button) and return to gameplay. For more
+ information about design for navigation, see <a href=
+ "http://developer.android.com/design/patterns/navigation.html">Navigation with Back and Up</a>.
+ To learn about implementation, refer to <a href=
+ "http://developer.android.com/training/implementing-navigation/temporal.html">Providing Proper
+ Back Navigation</a>.
+</p>
+
+
+<h3 id="multiple-controllers">Handling multiple controllers</h3>
+
+<p>
+ When multiple players are playing a game, each with his or her own controller, it is important to
+ map each player-controller pair. For information on how to implement controller-number
+ identification, see <a href=
+ "http://developer.android.com/reference/android/view/InputDevice.html#getControllerNumber">Input
+ Devices</a>.
+</p>
+
+
+<h3 id="handle-disconnect">Handling disconnects</h3>
+
+<p>
+ When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog
+ should appear prompting the disconnected player to reconnect his or her controller.
+</p>
+
+<p>
+ The dialog should also offer troubleshooting tips (for example, a pop-up dialog telling the
+ player to "Check your Bluetooth connection"). For more information on implementing input-device
+ support, see <a href=
+ "http://developer.android.com/training/game-controllers/controller-input.html">Handling Controller
+ Actions</a>. Specific information about Bluetooth connections is at <a href=
+ "http://developer.android.com/guide/topics/connectivity/bluetooth.html">Bluetooth</a>.
+</p>
+
+
+<h2 id="manifest">Manifest</h2>
+
+<p>
+ The Android TV launcher home screen displays games in a separate row from regular apps. The TV
+ framework uses the <code>android:isGame</code> manifest attribute to differentiate games from
+ non-game apps. Set this value to <code>true</code> in your game's app manifest, as shown in the
+ following code example:
+</p>
+
+<pre class="fragment">
+<application>
+ ...
+ < meta-data android:name="isGame" android:value="true" >
+ ...
+</application>
+</pre>
+
+
+<h3 id="gamepad">Game Controllers</h3>
+
+<p>
+ Games controllers may not be available or active for users of a TV device. In order to properly
+ inform users that your game requires (or just supports) a game controller, you must include
+ entries in the app manifest. If your game requires a game controller, you must include the
+ following entry in your app manifest:
+</p>
+
+<pre>
+ <uses-feature android:name="android.hardware.gamepad"/>
+</pre>
+
+<p>
+ If your game uses, but does not require, a game controller, include the following feature
+ entry in your app manifest:
+</p>
+
+<pre>
+ <uses-feature android:name="android.hardware.gamepad" android:required="false"/>
+</pre>
+
+<p>For more information about manifest entries, see
+ <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">App Manifest</a>.
+</p>
+
+
+<h2 id="gpgs">Google Play Game Services</h2>
+
+<p>
+ If your game integrates Google Play Game Services, you should keep in mind a number of
+ considerations pertaining to achievements, sign-in, saving games, and multiplayer play.
+</p>
+
+
+<h3 id="achievements">Achievements</h3>
+
+<p>
+ Your game should include at least five (earnable) achievements. Only a user controlling gameplay
+ from a supported input device should be able to earn achievements. For more information on
+ achievements and how to implement them, see <a href=
+ "https://developers.google.com/games/services/android/achievements">Achievements in Android</a>.
+</p>
+
+
+<h3 id="sign-in">Sign-in</h3>
+
+<p>
+ Your game should attempt to sign the user in on launch. If the player declines sign-in several
+ times in a row, your game should stop asking. Learn more about sign-in at <a href=
+ "https://developers.google.com/games/services/training/signin">Implementing Sign-in on
+ Android</a>.
+</p>
+
+
+<h3 id="saving">Saving</h3>
+
+<p>
+ We highly recommend using Play Services <a href=
+ "https://developers.google.com/games/services/common/concepts/savedgames">Saved Games</a> to store
+ your game save. Your game should bind game saves to a specific Google account, so as to be
+ uniquely identifiable even across devices: Whether the player is using a handset or a TV, the
+ game should be able to pull the game-save information from the same user account.
+</p>
+
+<p>
+ You should also provide an option in your game's UI to allow the player to delete locally and
+ cloud-stored data. You might put the option in the game's <code>Settings</code> screen. For
+ specifics on implementing saved games using Play Services, see <a href=
+ "https://developers.google.com/games/services/android/savedgames">Saved Games in Android</a>.
+</p>
+
+
+<h3 id="multiplayer-ux">Multiplayer experience</h3>
+
+<p>
+ A game offering a multiplayer experience must allow at least two players to enter a room. For
+ further information on multiplayer games in Android, see the <a href=
+ "https://developers.google.com/games/services/android/realtimeMultiplayer">Real-time
+ Multiplayer</a> and <a href="">Turn-based Multiplayer</a> documentation on the Android developer
+ site.
+</p>
+
+
+<h2 id="web">Web</h2>
+
+<p>
+ We discourage enabling web browsing in games for Android TV. The television set is not
+ well-suited for browsing, either in terms of display or control scheme.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You can use the {@link android.webkit.WebView} class for logins to
+ services like Google+ and Facebook.
+</p>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 54f7016..56667a9 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,59 +1,8 @@
-page.title=Designing for TV
-page.tags="input","screens"
-
-trainingnavtop=true
-startpage=true
+page.title=Building Apps for TV
+page.trainingcourse=true
@jd:body
-<div id="tb-wrapper">
-<div id="tb">
-<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
-<h2>Dependencies and prerequisites</h2>
-<ul>
- <li>Android 2.0 (API Level 5) or higher</li>
-</ul>
-</div>
-</div>
-
-<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=zsRnRLh-O34">
-<div>
- <h3>Video</h3>
- <p>DevBytes: Design for Large Displays - Part 1</p>
-</div>
-</a>
-
-<p>
- Smart TVs powered by Android bring your favorite Android apps to the best screen in your house.
- Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how
- you can optimize your Android app for TVs, including how to build a layout that
- works great when the user is ten feet away and navigating with a remote control.
-</p>
-
-<h2>Lessons</h2>
-
-<dl>
- <dt><b><a href="optimizing-layouts-tv.html">Optimizing Layouts for TV</a></b></dt>
- <dd>Shows you how to optimize app layouts for TV screens, which have some unique characteristics such as:
- <ul>
- <li>permanent "landscape" mode</li>
- <li>high-resolution displays</li>
- <li>"10 foot UI" environment.</li>
- </ul>
- </dd>
-
- <dt><b><a href="optimizing-navigation-tv.html">Optimizing Navigation for TV</a></b></dt>
- <dd>Shows you how to design navigation for TVs, including:
- <ul>
- <li>handling D-pad navigation</li>
- <li>providing navigational feedback</li>
- <li>providing easily-accessible controls on the screen.</li>
- </ul>
- </dd>
-
- <dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
- <dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to
- provide alternatives for missing features or check for missing features and disable code at run time.</dd>
-</dl>
+<p>These classes teach you how to build apps for TV devices.</p>
\ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-layouts-tv.jd b/docs/html/training/tv/optimizing-layouts-tv.jd
deleted file mode 100644
index a6db052..0000000
--- a/docs/html/training/tv/optimizing-layouts-tv.jd
+++ /dev/null
@@ -1,246 +0,0 @@
-page.title=Optimizing Layouts for TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-next.title=Optimizing Navigation for TV
-next.link=optimizing-navigation-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
- <li><a href="#MakeTextControlsEasyToSee">Make Text and Controls Easy to See</a></li>
- <li><a href="#DesignForLargeScreens">Design for High-Density Large Screens</a></li>
- <li><a href="#HandleLargeBitmaps">Design to Handle Large Bitmaps</a></li>
-</ol>
-
-<h2>You should also read</h2>
-<ul>
- <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
-</ul>
-
-</div>
-</div>
-
-<p>
-When your application is running on a television set, you should assume that the user is sitting about
-ten feet away from the screen. This user environment is referred to as the
-<a href="http://en.wikipedia.org/wiki/10-foot_user_interface">10-foot UI</a>. To provide your
-users with a usable and enjoyable experience, you should style and lay out your UI accordingly..
-</p>
-<p>
-This lesson shows you how to optimize layouts for TV by:
-</p>
-<ul>
- <li>Providing appropriate layout resources for landscape mode.</li>
- <li>Ensuring that text and controls are large enough to be visible from a distance.</li>
- <li>Providing high resolution bitmaps and icons for HD TV screens.</li>
-</ul>
-
-<h2 id="DesignLandscapeLayouts">Design Landscape Layouts</h2>
-
-<p>
-TV screens are always in landscape orientation. Follow these tips to build landscape layouts optimized for TV screens:
-</p>
-<ul>
- <li>Put on-screen navigational controls on the left or right side of the screen and save the
- vertical space for content.</li>
- <li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/components/fragments.html">Fragments</a>
- and use view groups like {@link android.widget.GridView} instead
- of {@link android.widget.ListView} to make better use of the
- horizontal screen space.</li>
- <li>Use view groups such as {@link android.widget.RelativeLayout}
- or {@link android.widget.LinearLayout} to arrange views.
- This allows the Android system to adjust the position of the views to the size, alignment,
- aspect ratio, and pixel density of the TV screen.</li>
- <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
-</ul>
-
-<p>
-For example, the following layout is optimized for TV:
-</p>
-
-<img src="{@docRoot}images/training/panoramio-grid.png" />
-
-<p>
-In this layout, the controls are on the lefthand side. The UI is displayed within a
-{@link android.widget.GridView}, which is well-suited to landscape orientation.
-In this layout both GridView and Fragment have the width and height set
-dynamically, so they can adjust to the screen resolution. Controls are added to the left side Fragment programatically at runtime.
-The layout file for this UI is {@code res/layout-land-large/photogrid_tv.xml}.
-(This layout file is placed in {@code layout-land-large} because TVs have large screens with landscape orientation. For details refer to
-<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.)</p>
-
-res/layout-land-large/photogrid_tv.xml
-<pre>
-<RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- <fragment
- android:id="@+id/leftsidecontrols"
- android:layout_width="0dip"
- android:layout_marginLeft="5dip"
- android:layout_height="match_parent" />
-
- <GridView
- android:id="@+id/gridview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
-</RelativeLayout>
-</pre>
-
-<p>
-To set up action bar items on the left side of the screen, you can also include the <a
-href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarLibrary">
-Left navigation bar library</a> in your application to set up action items on the left side
-of the screen, instead of creating a custom Fragment to add controls:
-</p>
-
-<pre>
-LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this);
-</pre>
-
-<p>
-When you have an activity in which the content scrolls vertically, always use a left navigation bar;
-otherwise, your users have to scroll to the top of the content to switch between the content view and
-the ActionBar. Look at the
-<a href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarDemo">
-Left navigation bar sample app</a> to see how to simple it is to include the left navigation bar in your app.
-</p>
-
-<h2 id="MakeTextControlsEasyToSee">Make Text and Controls Easy to See</h2>
-<p>
-The text and controls in a TV application's UI should be easily visible and navigable from a distance.
-Follow these tips to make them easier to see from a distance :
-</p>
-
-<ul>
- <li>Break text into small chunks that users can quickly scan.</li>
- <li>Use light text on a dark background. This style is easier to read on a TV.</li>
- <li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. Use simple sans-serif
- fonts and use anti-aliasing to increase readability.</li>
- <li>Use Android's standard font sizes:
- <pre>
- <TextView
- android:id="@+id/atext"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
- </pre></li>
- <li>Ensure that all your view widgets are large enough to be clearly visible to someone sitting 10 feet away
- from the screen (this distance is greater for very large screens). The best way to do this is to use
- layout-relative sizing rather than absolute sizing, and density-independent pixel units instead of absolute
- pixel units. For example, to set the width of a widget, use wrap_content instead of a pixel measurement,
- and to set the margin for a widget, use dip instead of px values.
- </li>
-</ul>
-<p>
-
-</p>
-
-<h2 id="DesignForLargeScreens">Design for High-Density Large Screens</h2>
-
-<p>
-The common HDTV display resolutions are 720p, 1080i, and 1080p. Design your UI for 1080p, and then
-allow the Android system to downscale your UI to 720p if necessary. In general, downscaling (removing pixels)
-does not degrade the UI (Notice that the converse is not true; you should avoid upscaling because it degrades
-UI quality).
-</p>
-
-<p>
-To get the best scaling results for images, provide them as <a href="{@docRoot}tools/help/draw9patch.html">
-9-patch image</a> elements if possible.
-If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy. This
-is not a good experience for the user. Instead, use high-quality images.
-</p>
-
-<p>
-For more information on optimizing apps for large screens see <a href="{@docRoot}training/multiscreen/index.html">
-Designing for multiple screens</a>.
-</p>
-
-<h2 id="HandleLargeBitmaps">Design to Handle Large Bitmaps</h2>
-
-<p>
-The Android system has a limited amount of memory, so downloading and storing high-resolution images can often
-cause out-of-memory errors in your app. To avoid this, follow these tips:
-</p>
-
-<ul>
- <li>Load images only when they're displayed on the screen. For example, when displaying multiple images in
- a {@link android.widget.GridView} or
- {@link android.widget.Gallery}, only load an image when
- {@link android.widget.Adapter#getView(int, View, ViewGroup) getView()}
- is called on the View's {@link android.widget.Adapter}.
- </li>
- <li>Call {@link android.graphics.Bitmap#recycle()} on
- {@link android.graphics.Bitmap} views that are no longer needed.
- </li>
- <li>Use {@link java.lang.ref.WeakReference} for storing references
- to {@link android.graphics.Bitmap} objects in an in-memory
- {@link java.util.Collection}.</li>
- <li>If you fetch images from the network, use {@link android.os.AsyncTask}
- to fetch them and store them on the SD card for faster access.
- Never do network transactions on the application's UI thread.
- </li>
- <li>Scale down really large images to a more appropriate size as you download them; otherwise, downloading the image
- itself may cause an "Out of Memory" exception. Here is sample code that scales down images while downloading:
-
- <pre>
- // Get the source image's dimensions
- BitmapFactory.Options options = new BitmapFactory.Options();
- // This does not download the actual image, just downloads headers.
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
- // The actual width of the image.
- int srcWidth = options.outWidth;
- // The actual height of the image.
- int srcHeight = options.outHeight;
-
- // Only scale if the source is bigger than the width of the destination view.
- if(desiredWidth > srcWidth)
- desiredWidth = srcWidth;
-
- // Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.
- int inSampleSize = 1;
- while(srcWidth / 2 > desiredWidth){
- srcWidth /= 2;
- srcHeight /= 2;
- inSampleSize *= 2;
- }
-
- float desiredScale = (float) desiredWidth / srcWidth;
-
- // Decode with inSampleSize
- options.inJustDecodeBounds = false;
- options.inDither = false;
- options.inSampleSize = inSampleSize;
- options.inScaled = false;
- // Ensures the image stays as a 32-bit ARGB_8888 image.
- // This preserves image quality.
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-
- Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
-
- // Resize
- Matrix matrix = new Matrix();
- matrix.postScale(desiredScale, desiredScale);
- Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
- sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
- sampledSrcBitmap = null;
-
- // Save
- FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
- scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
- scaledBitmap = null;
- </pre>
- </li> </ul>
\ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-navigation-tv.jd b/docs/html/training/tv/optimizing-navigation-tv.jd
deleted file mode 100644
index bb78258..0000000
--- a/docs/html/training/tv/optimizing-navigation-tv.jd
+++ /dev/null
@@ -1,206 +0,0 @@
-page.title=Optimizing Navigation for TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-previous.title=Optimizing Layouts for TV
-previous.link=optimizing-layouts-tv.html
-next.title=Handling Features Not Supported on TV
-next.link=unsupported-features-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#HandleDpadNavigation">Handle D-pad Navigation</a></li>
- <li><a href="#HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</a></li>
- <li><a href="#DesignForEasyNavigation">Design for Easy Navigation</a></li>
-</ol>
-
-<h2>You should also read</h2>
-<ul>
- <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
-</ul>
-
-</div>
-</div>
-
-<p>
-An important aspect of the user experience when operating a TV is the direct human interface: a remote control.
-As you optimize your Android application for TVs, you should pay special attention to how the user actually navigates
-around your application when using a remote control instead of a touchscreen.
-</p>
-<p>
-This lesson shows you how to optimize navigation for TV by:
-</p>
-
-<ul>
- <li>Ensuring all layout controls are D-pad navigable.</li>
- <li>Providing highly obvious feedback for UI navigation.</li>
- <li>Placing layout controls for easy access.</li>
-</ul>
-
-<h2 id="HandleDpadNavigation">Handle D-pad Navigation</h2>
-
-<p>
-On a TV, users navigate with controls on a TV remote, using either a D-pad or arrow keys.
-This limits movement to up, down, left, and right.
-To build a great TV-optimized app, you must provide a navigation scheme in which the user can
-quickly learn how to navigate your app using the remote.
-</p>
-
-<p>
-When you design navigation for D-pad, follow these guidelines:
-</p>
-
-<ul>
- <li>Ensure that the D-pad can navigate to all the visible controls on the screen.</li>
- <li>For scrolling lists with focus, D-pad up/down keys scroll the list and Enter key selects an item in the list. Ensure that users can
- select an element in the list and that the list still scrolls when an element is selected.</li>
- <li>Ensure that movement between controls is straightforward and predictable.</li>
-</ul>
-
-<p>
-Android usually handles navigation order between layout elements automatically, so you don't need to do anything extra. If the screen layout
-makes navigation difficult, or if you want users to move through the layout in a specific way, you can set up explicit navigation for your
-controls.
-For example, for an {@code android.widget.EditText}, to define the next control to receive focus, use:
-<pre>
-<EditText android:id="@+id/LastNameField" android:nextFocusDown="@+id/FirstNameField"\>
-</pre>
-The following table lists all of the available navigation attributes:
-</p>
-
-<table>
-<tr>
-<th>Attribute</th>
-<th>Function</th>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusDown}</td>
-<td>Defines the next view to receive focus when the user navigates down.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusLeft}</td>
-<td>Defines the next view to receive focus when the user navigates left.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusRight}</td>
-<td>Defines the next view to receive focus when the user navigates right.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusUp}</td>
-<td>Defines the next view to receive focus when the user navigates up.</td>
-</tr>
-</table>
-
-<p>
-To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set
-up the navigation order as a loop, so that the last control directs focus back to the first one.
-</p>
-
-<p>
-Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well.
-</p>
-
-<h2 id="HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</h2>
-
-<p>
-Use appropriate color highlights for all navigable and selectable elements in the UI. This makes it easy for users to know whether the control
-is currently focused or selected when they navigate with a D-pad. Also, use uniform highlight scheme across your application.
-</p>
-
-<p>
-Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">Drawable State List Resources</a> to implement highlights
-for selected and focused controls. For example:
-</p>
-
-res/drawable/button.xml:
-<pre>
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true"
- android:drawable="@drawable/button_pressed" /> <!-- pressed -->
- <item android:state_focused="true"
- android:drawable="@drawable/button_focused" /> <!-- focused -->
- <item android:state_hovered="true"
- android:drawable="@drawable/button_focused" /> <!-- hovered -->
- <item android:drawable="@drawable/button_normal" /> <!-- default -->
-</selector>
-</pre>
-
-<p>
-This layout XML applies the above state list drawable to a {@link android.widget.Button}:
-</p>
-<pre>
-<Button
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/button" />
-</pre>
-
-<p>
-Provide sufficient padding within the focusable and selectable controls so that the highlights around them are clearly visible.
-</p>
-
-<h2 id="DesignForEasyNavigation">Design for Easy Navigation</h2>
-
-<p>
-Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation should be easy and intuitive to
-understand. For any non-intuitive actions, provide users with written help, using a dialog triggered by a help button or action bar icon.
-</p>
-
-<p>
-Predict the next screen that the user will want to navigate to and provide one click navigation to it. If the current screen UI is very sparse,
-consider making it a multi pane screen. Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with continent names
-on the left and list of cool places in each continent on the right.
-</p>
-
-<img src="{@docRoot}images/training/cool-places.png" alt="" />
-
-<p>
-The above UI consists of three Fragments - <code>left_side_action_controls</code>, <code>continents</code> and
-<code>places</code> - as shown in its layout
-xml file below. Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen space for
-TVs.
-</p>
-res/layout/cool_places.xml
-<pre>
-<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- >
- <fragment
- android:id="@+id/left_side_action_controls"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.2"/>
- <fragment
- android:id="@+id/continents"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.2"/>
-
- <fragment
- android:id="@+id/places"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.6"/>
-
-</LinearLayout>
-</pre>
-
-<p>
-Also, notice in the UI layout above action controls are on the left hand side of a vertically scrolling list to make
-them easily accessible using D-pad.
-In general, for layouts with horizontally scrolling components, place action controls on left or right hand side and
-vice versa for vertically scrolling components.
-</p>
-
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
new file mode 100644
index 0000000..9b25166
--- /dev/null
+++ b/docs/html/training/tv/playback/browse.jd
@@ -0,0 +1,230 @@
+page.title=Creating a Catalog Browser
+page.tags="browsefragment","presenter","backgroundmanager"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#layout">Create a Media Browse Layout</a></li>
+ <li><a href="#lists">Display Media Lists</a></li>
+ <li><a href="#background">Update the Background</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>
+ Media apps that run on TV need to allow users to browse its content offerings, make a
+ selection, and start playing content. The content browsing experience for apps of this type
+ should be simple and intuitive, as well as visually pleasing and engaging.
+</p>
+
+<p>
+ This lesson discusses how to use the classes provided by the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a> to
+ implement a user interface for browsing music or videos from your app's media catalog.
+</p>
+
+
+<h2 id="layout">Create a Media Browse Layout</h2>
+
+<p>
+ The {@link android.support.v17.leanback.app.BrowseFragment} class in the leanback library
+ allows you to create a primary layout for browsing categories and rows of media items with a
+ minimum of code. The following example shows how to create a layout that contains a {@link
+ android.support.v17.leanback.app.BrowseFragment}:
+</p>
+
+<pre>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <fragment
+ <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
+ android:id="@+id/browse_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+</LinearLayout>
+</pre>
+
+<p>
+ In order to work with this layout in an activity, retrieve the {@link
+ android.support.v17.leanback.app.BrowseFragment} element from the layout. Use the methods in this
+ class to set display parameters such as the icon, title, and whether category headers are enabled.
+ The following code sample demonstrates how to set the layout parameters for a {@link
+ android.support.v17.leanback.app.BrowseFragment} in a layout:
+</p>
+
+<pre>
+public class BrowseMediaActivity extends Activity {
+
+ public static final String TAG ="BrowseActivity";
+
+ protected BrowseFragment mBrowseFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_fragment);
+
+ final FragmentManager fragmentManager = getFragmentManager();
+ <strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
+ R.id.browse_fragment);</strong>
+
+ // Set display parameters for the BrowseFragment
+ mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
+ mBrowseFragment.setTitle(getString(R.string.app_name));
+ mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
+ R.drawable.ic_launcher));
+ mBrowseFragment.setBrowseParams(params);
+
+ }
+}
+</pre>
+
+
+<h2 id="lists">Displaying Media Lists</h2>
+
+<p>
+ The {@link android.support.v17.leanback.app.BrowseFragment} allows you to define and display
+ browsable media content categories and media items from a media catalog using adapters and
+ presenters. Adapters enable you to connect to local or online data sources that contain your
+ media catalog information. Presenters hold data about media items and provide layout information
+ for displaying an item on screen.
+</p>
+
+<p>
+ The following example code shows an implementation of a {@link
+ android.support.v17.leanback.widget.Presenter} for displaying string data:
+</p>
+
+<pre>
+public class StringPresenter extends Presenter {
+ private static final String TAG = "StringPresenter";
+
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ TextView textView = new TextView(parent.getContext());
+ textView.setFocusable(true);
+ textView.setFocusableInTouchMode(true);
+ textView.setBackground(
+ parent.getContext().getResources().getDrawable(R.drawable.text_bg));
+ return new ViewHolder(textView);
+ }
+
+ public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+ ((TextView) viewHolder.view).setText(item.toString());
+ }
+
+ public void onUnbindViewHolder(ViewHolder viewHolder) {
+ // no op
+ }
+}
+</pre>
+
+<p>
+ Once you have constructed a presenter class for your media items, you can build and attach an
+ adapter to the {@link android.support.v17.leanback.app.BrowseFragment} to display those items on
+ screen for browsing by the user. The following example code demonstrates how to construct an
+ adapter to display categories and items in those categories using the {@code StringPresenter}
+ class shown in the previous code example:
+</p>
+
+<pre>
+private ArrayObjectAdapter mRowsAdapter;
+private static final int NUM_ROWS = 4;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ ...
+
+ buildRowsAdapter();
+}
+
+private void buildRowsAdapter() {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ for (int i = 0; i < NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
+ new StringPresenter());
+ listRowAdapter.add("Media Item 1");
+ listRowAdapter.add("Media Item 2");
+ listRowAdapter.add("Media Item 3");
+ HeaderItem header = new HeaderItem(i, "Category " + i, null);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+
+ mBrowseFragment.setAdapter(mRowsAdapter);
+}
+</pre>
+
+<p>
+ This example shows a static implementation of the adapters. A typical media browsing application
+ uses data from an online database or web service. For an example of a browsing application that
+ uses data retrieved from the web, see the
+ <a href="http://github.com/googlesamples/androidtv-leanback">Android TV</a> sample app.
+</p>
+
+<h2 id="background">Update the Background</h2>
+
+<p>
+ In order to add visual interest to a media-browsing app on TV, you can update the background
+ image as users browse through content. This technique can make interaction with your app feel
+ more cinematic and enjoyable for users.
+</p>
+
+<p>
+ The Leanback support library provides a {@link android.support.v17.leanback.app.BackgroundManager}
+ class for changing the background of your TV app activity. The following example shows how to
+ create a simple method for updating the background within your TV app activity:
+</p>
+
+<pre>
+protected void updateBackground(Drawable drawable) {
+ BackgroundManager.getInstance(this).setDrawable(drawable);
+}
+</pre>
+
+<p>
+ Many of the existing media-browse apps automatically update the background as the user navigates
+ through media listings. In order to do this, you can set up a selection listener to automatically
+ update the background based on the user's current selection. The following example shows you how
+ to set up an {@link android.support.v17.leanback.widget.OnItemViewSelectedListener} class to
+ catch selection events and update the background:
+</p>
+
+<pre>
+protected void clearBackground() {
+ BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
+}
+
+protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
+ return new OnItemViewSelectedListener() {
+ @Override
+ public void onItemSelected(Object item, Row row) {
+ if (item instanceof Movie ) {
+ URI uri = ((Movie)item).getBackdropURI();
+ updateBackground(uri);
+ } else {
+ clearBackground();
+ }
+ }
+ };
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> The implementation above is a simple example shown for purposes of
+ illustration. When creating this function in your own app, you should consider running the
+ background update action in a separate thread for better performance. In addition, if you are
+ planning on updating the background in response to users scrolling through items, consider adding
+ a time to delay a background image update until the user settles on an item. This technique avoids
+ excessive background image updates.
+</p>
diff --git a/docs/html/training/tv/playback/details.jd b/docs/html/training/tv/playback/details.jd
new file mode 100644
index 0000000..6391a49
--- /dev/null
+++ b/docs/html/training/tv/playback/details.jd
@@ -0,0 +1,247 @@
+page.title=Building a Details View
+page.tags="detailsfragment"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#details-presenter">Build a Details Presenter</a></li>
+ <li><a href="#details-fragment">Extend the Details Fragment</a>
+ <li><a href="#activity">Create a Details Activity</a></li>
+ <li><a href="#item-listener">Define a Listener for Clicked Items</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ The media browsing interface classes provided by the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a>
+ include classes for displaying additional information about a media item, such as a description
+ or reviews, and for taking action on that item, such as purchasing it or playing its content.
+</p>
+
+<p>
+ This lesson discusses how to create a presenter class for media item details, and how to extend
+ the {@link android.support.v17.leanback.app.DetailsFragment} class to implement a details view
+ for a media item when it is selected by a user.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> The implementation example shown here uses an additional activity to
+ contain the {@link android.support.v17.leanback.app.DetailsFragment}. However, it is possible to
+ avoid creating a second activity by replacing the current {@link
+ android.support.v17.leanback.app.BrowseFragment} with a {@link
+ android.support.v17.leanback.app.DetailsFragment} within the <em>same</em> activity using
+ fragment transactions. For more information on using fragment transactions, see the <a href=
+ "{@docRoot}training/basics/fragments/fragment-ui.html#Replace">Building a Dynamic UI with
+ Fragments</a> training.
+</p>
+
+
+<h2 id="details-presenter">Build a Details Presenter</h2>
+
+<p>
+ In the media browsing framework provided by the leanback library, you use presenter
+ objects to control the display of data on screen, including media item details. The framework
+ provides the {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}
+ class for this purpose, which is a nearly complete implementation of the presenter for media item
+ details. All you have to do is implement the {@link
+ android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter#onBindDescription
+ onBindDescription()} method to bind the view fields to your data objects, as shown in the
+ following code sample:
+</p>
+
+<pre>
+public class DetailsDescriptionPresenter
+ extends AbstractDetailsDescriptionPresenter {
+
+ @Override
+ protected void onBindDescription(ViewHolder viewHolder, Object itemData) {
+ MyMediaItemDetails details = (MyMediaItemDetails) itemData;
+ // In a production app, the itemData object contains the information
+ // needed to display details for the media item:
+ // viewHolder.getTitle().setText(details.getShortTitle());
+
+ // Here we provide static data for testing purposes:
+ viewHolder.getTitle().setText(itemData.toString());
+ viewHolder.getSubtitle().setText("2014 Drama TV-14");
+ viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur "
+ + "adipisicing elit, sed do eiusmod tempor incididunt ut labore "
+ + " et dolore magna aliqua. Ut enim ad minim veniam, quis "
+ + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
+ + "commodo consequat.");
+ }
+}
+</pre>
+
+
+<h2 id="details-fragment">Extend the Details Fragment</h2>
+
+<p>
+ When using the {@link android.support.v17.leanback.app.DetailsFragment} class for displaying
+ your media item details, extend that class to provide additional content such as a preview
+ image and actions for the media item. You can also provide additional content, such as a list of
+ related media items.
+</p>
+
+<p>
+ The following example code demonstrates how to use the presenter class shown in the
+ previous section, to add a preview image and actions for the media item being viewed. This example
+ also shows the addition of a related media items row, which appears below the details listing.
+</p>
+
+<pre>
+public class MediaItemDetailsFragment extends DetailsFragment {
+ private static final String TAG = "MediaItemDetailsFragment";
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ buildDetails();
+ }
+
+ private void buildDetails() {
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ // Attach your media item details presenter to the row presenter:
+ DetailsOverviewRowPresenter rowPresenter =
+ new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
+
+ selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
+ selector.addClassPresenter(ListRow.class,
+ new ListRowPresenter());
+ mRowsAdapter = new ArrayObjectAdapter(selector);
+
+ Resources res = getActivity().getResources();
+ DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
+ "Media Item Details");
+
+ // Add images and action buttons to the details view
+ detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
+ detailsOverview.addAction(new Action(1, "Buy $9.99"));
+ detailsOverview.addAction(new Action(2, "Rent $2.99"));
+ mRowsAdapter.add(detailsOverview);
+
+ // Add a Related items row
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
+ new StringPresenter());
+ listRowAdapter.add("Media Item 1");
+ listRowAdapter.add("Media Item 2");
+ listRowAdapter.add("Media Item 3");
+ HeaderItem header = new HeaderItem(0, "Related Items", null);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+
+ setAdapter(mRowsAdapter);
+ }
+}
+</pre>
+
+
+<h3 id="activity">Create a Details Activity</h3>
+
+<p>
+ Fragments such as the {@link android.support.v17.leanback.app.DetailsFragment} must be contained
+ within an activity in order to be used for display. Creating an activity for your details view,
+ separate from the browse activity, enables you to invoke your details view using an
+ {@link android.content.Intent}. This
+ section explains how to build an activity to contain your implementation of the detail view for
+ your media items.
+</p>
+
+<p>
+ Start creating the details activity by building a layout that references your implementation of
+ the {@link android.support.v17.leanback.app.DetailsFragment}:
+</p>
+
+<pre>
+<!-- file: res/layout/details.xml -->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
+ android:id="@+id/details_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+/>
+</pre>
+
+<p>
+ Next, create an activity class that uses the layout shown in the previous code example:
+</p>
+
+<pre>
+public class DetailsActivity extends Activity
+{
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ <strong>setContentView(R.layout.details);</strong>
+ }
+}
+</pre>
+
+<p>
+ Finally, add this new activity to the manifest. Remember to apply the Leanback theme to ensure
+ that the user interface is consistent with the media browse activity:
+</p>
+
+<pre>
+<application>
+ ...
+
+ <activity android:name=".DetailsActivity"
+ android:exported="true"
+ <strong>android:theme="@style/Theme.Leanback"/></strong>
+
+</application>
+</pre>
+
+
+<h3 id="item-listener">Define a Listener for Clicked Items</h3>
+
+<p>
+ After you have implemented the {@link android.support.v17.leanback.app.DetailsFragment},
+ modify your main media browsing view to move to your details view when a user clicks on a media
+ item. In order to enable this behavior, add an
+ {@link android.support.v17.leanback.widget.OnItemViewClickedListener} object to the
+ {@link android.support.v17.leanback.app.BrowseFragment} that fires an intent to start the item
+ details activity.
+</p>
+
+<p>
+ The following example shows how to implement a listener to start the details view when a user
+ clicks a media item in the main media browsing activity:
+</p>
+
+<pre>
+public class BrowseMediaActivity extends Activity {
+ ...
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ ...
+
+ // create the media item rows
+ buildRowsAdapter();
+
+ // add a listener for selected items
+ mBrowseFragment.OnItemViewClickedListener(
+ new OnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Object item, Row row) {
+ System.out.println("Media Item clicked: " + item.toString());
+ Intent intent = new Intent(BrowseMediaActivity.this,
+ DetailsActivity.class);
+ // pass the item information
+ intent.getExtras().putLong("id", item.getId());
+ startActivity(intent);
+ }
+ });
+ }
+}
+</pre>
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
new file mode 100644
index 0000000..d7167e7
--- /dev/null
+++ b/docs/html/training/tv/playback/index.jd
@@ -0,0 +1,49 @@
+page.title=Building TV Playback Apps
+page.tags="leanback"
+
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ </ul>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}design/tv/index.html">
+ Design for TV</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ Browsing and playing media files is frequently part of the user experience provided by a TV app.
+ Building such an experience from scratch, while making sure that it is fast, fluid, and attractive
+ can be quite challenging. Whether your app provides access to a small or large media catalog,
+ it is important to allow users to quickly browse options and get to the content they want.
+</p>
+
+<p>
+ The Android framework provides classes for building user interfaces for these types of apps with
+ the <a href="{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support
+ library</a>. This library provides a framework of classes for creating an efficient and familiar
+ interface for browsing and playing media files with minimal coding. The classes are designed
+ be extended and customized so you can create an experience that is unique to your app.
+</p>
+
+<p>This class shows you how to build a TV app for browsing and playing media content using the Leanback
+ support libraries for TV.</p>
+
+<h2>Topics</h2>
+
+<dl>
+ <dt><b><a href="browse.html">Creating a Catalog Browser</a></b></dt>
+ <dd>Learn how to use the Leanback support library to build a browsing interface for media
+ catalogs.</dd>
+
+ <dt><b><a href="details.html">Building a Details View</a></b></dt>
+ <dd>Learn how to use the Leanback support library to build a details page for media items.</dd>
+</dl>
diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd
new file mode 100644
index 0000000..33d396b
--- /dev/null
+++ b/docs/html/training/tv/start/hardware.jd
@@ -0,0 +1,361 @@
+page.title=Handling TV Hardware
+page.tags="unsupported"
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#runtime-check">Check for a TV Device</a>
+ <li><a href="#handle-features">Handle Unsupported Hardware Features</a></li>
+ <li><a href="#controllers">Manage Hardware Controllers</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+<p>
+ TV hardware is substantially different from other Android devices. TVs do not
+ include some of the hardware features found on other Android devices, such as touch screens,
+ cameras, and GPS receivers. TVs are also completely dependent on secondary hardware devices.
+ In order for users to interact with TV apps, they must use a remote control or game pad. When
+ you build an app for TV, you must carefully consider the hardware limitations and requirements of
+ operating on TV hardware.
+</p>
+
+<p>
+ This lesson discusses how to check if your app is running on a TV, how to handle unsupported
+ hardware features, and discusses the requirements for handling controllers for TV devices.
+</p>
+
+
+<h2 id="runtime-check">Check for a TV Device</h2>
+
+<p>
+ If you are building an app that operates both on TV devices and other devices, you may need to
+ check what kind of device your app is running on and adjust the operation of your app. For
+ instance, if you have an app that can be started through an {@link android.content.Intent}, your
+ application should check the device properties to determine if it should start a TV-oriented
+ activity or a phone activity.
+</p>
+
+<p>
+ The recommended way to determine if your app is running on a TV device is to use the {@link
+ android.app.UiModeManager#getCurrentModeType UiModeManager.getCurrentModeType()} method to check
+ if the device is running in television mode. The following example code shows you how to check if
+ your app is running on a TV device:
+</p>
+
+<pre>
+public static final String TAG = "DeviceTypeRuntimeCheck";
+
+UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
+if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
+ Log.d(TAG, "Running on a TV Device")
+} else {
+ Log.d(TAG, "Running on a non-TV Device")
+}
+</pre>
+
+
+<h2 id="handle-features">Handle Unsupported Hardware Features</h2>
+
+<p>
+ Depending on the design and functionality of your app, you may be able to work around certain
+ hardware features being unavailable. This section discusses what hardware features are typically
+ not available for TV, how to detect missing hardware features, and suggests alternatives to
+ using these features.
+</p>
+
+
+<h3 id="unsupported-features">Unsupported TV hardware features</h3>
+
+<p>
+ TVs have a different purpose from other devices, and so they do not have hardware features that
+ other Android-powered devices often have. For this reason, the Android system does not support
+ the following features for a TV device:
+</p>
+
+<table>
+ <tr>
+ <th>Hardware</th>
+ <th>Android feature descriptor</th>
+ </tr>
+ <tr>
+ <td>Touchscreen</td>
+ <td>android.hardware.touchscreen</td>
+ </tr>
+ <tr>
+ <td>Telephony</td>
+ <td>android.hardware.telephony</td>
+ </tr>
+ <tr>
+ <td>Camera</td>
+ <td>android.hardware.camera</td>
+ </tr>
+ <tr>
+ <td>Near Field Communications (NFC)</td>
+ <td>android.hardware.nfc</td>
+ </tr>
+ <tr>
+ <td>GPS</td>
+ <td>android.hardware.location.gps</td>
+ </tr>
+ <tr>
+ <td>Microphone</td>
+ <td>android.hardware.microphone</td>
+ </tr>
+</table>
+
+
+<h3 id="declare-hardware-requirements">Declaring hardware requirements for TV</h3>
+
+<p>
+ Android apps can declare hardware feature requirements in the app manifest to ensure that they do
+ not get installed on devices that do not provide those features. If you are extending an existing
+ app for use on TV, closely review your app's manifest for any hardware requirement
+ declarations that might prevent it from being installed on a TV device.
+</p>
+
+<p>
+ If your app uses hardware features (such as a touchscreen or camera) that are not available on
+ TV, but can operate without the use of those features, modify your app's manifest to
+ indicate that these features are not required by your app. The following manifest code snippet
+ demonstrates how to declare that your app does not require hardware features which are unavailable
+ on TV devices, even though your app may use these features on non-TV devices:
+</p>
+
+<pre>
+<uses-feature android:name="android.hardware.touchscreen"
+ android:required="false"/>
+<uses-feature android:name="android.hardware.telephony"
+ android:required="false"/>
+<uses-feature android:name="android.hardware.camera"
+ android:required="false"/>
+<uses-feature android:name="android.hardware.nfc"
+ android:required="false"/>
+<uses-feature android:name="android.hardware.gps"
+ android:required="false"/>
+<uses-feature android:name="android.hardware.microphone"
+ android:required="false"/>
+</pre>
+
+<p class="caution">
+ <strong>Caution:</strong> Declaring an unavailable hardware feature as required by setting its
+ value to {@code true} in your app manifest prevents your app from being installed on TV
+ devices or appearing in the Android TV home screen launcher.
+</p>
+
+<p class="caution">
+ <strong>Caution:</strong> Some <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a> manifest declarations <em>imply hardware use</em>, which can also
+ prevent your app from being installed and used on TV devices. For example, requesting the
+ {@link android.Manifest.permission#RECORD_AUDIO} permission in your app implies the
+ {@code android.hardware.microphone} hardware feature requirement. In which case, you must declare
+ the microphone feature as not required ({@code android:required="false"}) in your app manifest.
+ For a list of permission requests that imply a hardware feature requirement, see <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">
+ {@code uses-feature}</a> guide.
+</p>
+
+<p>
+ Once you decide to make hardware features optional for your app, you must check for the
+ availability of those features at runtime and then adjust your app's behavior. The next section
+ discusses how to check for hardware features and suggests some approaches for changing the
+ behavior of your app.
+</p>
+
+<p>
+ For more information on filtering and declaring features in the manifest, see the
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>
+ guide.
+</p>
+
+
+<h3 id="check-features">Checking for hardware features</h2>
+
+<p>
+ The Android framework can tell you if hardware features are not available on the device where
+ your app is running. Use the {@link android.content.pm.PackageManager#hasSystemFeature(String)}
+ method to check for specific features at runtime. This method takes a single string argument that
+ specifies the feature you want to check.
+</p>
+
+<p>The following code example demonstrates how to detect the availability of hardware features
+ at runtime:</p>
+
+<pre>
+// Check if the telephony hardware feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
+ Log.d("HardwareFeatureTest", "Device can make phone calls");
+}
+
+// Check if android.hardware.touchscreen feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
+ Log.d("HardwareFeatureTest", "Device has a touch screen.");
+}
+</pre>
+
+
+<h4 id="no-touchscreen">Touch screen</h4>
+
+<p>
+ Since most TVs do not have touch screens, Android does not support touch screen interaction for
+ TV devices. Furthermore, using a touch screen is not consistent with a viewing environment where
+ the user is seated 10 feet away from the display.
+</p>
+
+<p>
+ On TV devices, you should design your app to work with this interaction model by supporting
+ navigation using a directional pad (D-pad) on a TV remote control. For more information on
+ properly supporting navigation using TV-friendly controls, see
+ <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
+</p>
+
+
+<h4 id="no-camera">Camera</h4>
+
+<p>
+ Although a TV typically does not have a camera, you can still provide a photography-related
+ app on a TV. For example, if you have an app that takes, views, and edits photos, you can
+ disable its picture-taking functionality for TVs and still allow users to view and even edit
+ photos. If you decide to enable your camera-related app to work on a TV, add the
+ following feature declaration your app manifest:
+</p>
+
+<pre>
+<uses-feature android:name="android.hardware.camera" android:required="false" />
+</pre>
+
+<p>
+ If you enable your app to run without a camera, add code to your app
+ that detects if the camera feature is available and makes adjustments to the operation of your
+ app. The following code example demonstrates how to detect the presence of a camera:
+</p>
+
+<pre>
+// Check if the camera hardware feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
+ Log.d("Camera test", "Camera available!");
+} else {
+ Log.d("Camera test", "No camera available. View and edit features only.");
+}
+</pre>
+
+
+<h4 id="no-gps">GPS</h4>
+
+<p>
+ TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
+ receivers. If your app uses location information, you can still allow users to search for
+ a location, or use a static location provider such as a zip code configured during the TV device
+ setup.
+</p>
+
+<pre>
+// Request a static location from the location manager
+LocationManager locationManager = (LocationManager) this.getSystemService(
+ Context.LOCATION_SERVICE);
+Location location = locationManager.getLastKnownLocation("static");
+
+// Attempt to get postal or zip code from the static location object
+Geocoder geocoder = new Geocoder(this);
+Address address = null;
+try {
+ address = geocoder.getFromLocation(location.getLatitude(),
+ location.getLongitude(), 1).get(0);
+ Log.d("Zip code", address.getPostalCode());
+
+} catch (IOException e) {
+ Log.e(TAG, "Geocoder error", e);
+}
+</pre>
+
+
+<h2 id="controllers">Handling Controllers</h2>
+
+<p>
+ TV devices require a secondary hardware device for interacting with apps, in the form of a basic
+ remote controller or game controller. This means that your app must support D-pad input. It also
+ means that your app may need to handle controllers going offline and input from more than one
+ type of controller.
+</p>
+
+
+<h3 id="d-pad-minimum">D-pad minimum controls</h3>
+
+<p>
+ The default controller for a TV device is a D-pad. In general, your app should be operable from a
+ remote controller that only has up, down, left, right, select, Back, and Home buttons. If your app
+ is a game that typically requires a game controller with additional controls, your app should
+ attempt to allow gameplay with these D-pad controls. In this case, your app should also warn the
+ user that
+ a controller is required and allow them to exit your game gracefully using the D-pad controller.
+ For more information about handling navigation with D-pad controller for TV devices, see
+ <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
+</p>
+
+
+<h3 id="controller-disconnects">Handle controller disconnects</h3>
+
+<p>
+ Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically
+ going into sleep mode and disconnecting from the TV device. This means that an app might be
+ interrupted or restarted if it is not configured to handle these reconnect events. These events
+ can happen in any of the following circumstances:
+</p>
+
+<ul>
+ <li>While watching a video which is several minutes long, a D-Pad or game controller goes into
+ sleep mode, disconnects from the TV device and then reconnects later on.
+ </li>
+ <li>During gameplay, a new player joins the game using a game controller that is not currently
+ connected.
+ </li>
+ <li>During gameplay, a player leaves the game and disconnects a game controller.
+ </li>
+</ul>
+
+<p>
+ Any TV app activity that is subject to disconnect and reconnect events must be configured to
+ handle reconnection events in the app manifest. The following code sample demonstrates how to
+ enable an activity to handle configuration changes, including a keyboard or navigation device
+ connecting, disconnecting, or reconnecting:
+</p>
+
+<pre>
+<activity
+ android:name="com.example.android.TvActivity"
+ android:label="@string/app_name"
+ <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong>
+ android:theme="@style/Theme.Leanback">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
+ </intent-filter>
+ ...
+</activity>
+</pre>
+
+<p>
+ This configuration change allows the app to continue running through a reconnection event, rather
+ than being restarted by the Android framework, which is not a good user experience.
+</p>
+
+
+<h3 id="d-pad-variants">Handle D-pad input variations</h3>
+
+<p>
+ TV device users may have more than one type of controller that they use with their TV. For
+ example, a user might have both a basic D-pad controller and a game controller. The key codes
+ provided by a game controller when it is being used for D-pad functions may vary from the key
+ codes sent by a physical D-pad.
+</p>
+
+<p>
+ Your app should handle the variations of D-pad input from a game controller, so the user does not
+ have to physically switch controllers to operate your app. For more information on handling these
+ input variations, see <a href="{@docRoot}training/game-controllers/controller-input.html#dpad">
+ Handling Controller Actions</a>.
+</p>
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
new file mode 100644
index 0000000..ceefea1
--- /dev/null
+++ b/docs/html/training/tv/start/index.jd
@@ -0,0 +1,63 @@
+page.title=Building TV Apps
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ <li>Android Studio 0.8 or later and Gradle 0.12 or later</li>
+ </ul>
+</div>
+</div>
+
+<p>
+ Android offers a rich user experience that's optimized for apps running on large screen devices,
+ such as high-definition televisions. Apps on TV offer new opportunities to delight your users
+ from the comfort of their couch.
+</p>
+
+<p>
+ TV apps use the same structure as those for phones and tablets. This approach means you can
+ create new TV apps based on what you already know about building apps for Android, or extend your
+ existing apps to also run on TV devices. However, the user interaction model for TV is
+ substantially different from phone and tablet devices. In order to make your app successful on TV
+ devices, you must design new layouts that can be easily understood from 10 feet away, and provide
+ navigation that works with just a directional pad and a select button.
+</p>
+
+<p>
+ This class describes how to start building apps for TV, including setting up your development
+ environment, basic requirements for layouts and navigation, as well as guidance on how to handle
+ hardware features that are not typically available on TV devices.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You are encouraged to use <a href=
+ "{@docRoot}sdk/installing/studio.html">Android Studio</a> for building TV apps, because it
+ provides project setup, library inclusion, and packaging conveniences. This training assumes you
+ are using Android Studio.
+</p>
+
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><a href="{@docRoot}training/tv/start/start.html">
+ Getting Started with TV Apps</a></dt>
+ <dd>Learn how to create a new Android Studio project for TV apps or modify your existing
+ app project to run on TV devices.</dd>
+ <dt><a href="{@docRoot}training/tv/start/layouts.html">
+ Building TV Layouts</a></dt>
+ <dd>Learn the minimum requirements for TV layouts and how to implement them.</dd>
+ <dt><a href="{@docRoot}training/tv/start/navigation.html">
+ Creating TV Navigation</a></dt>
+ <dd>Learn the requirements for TV navigation and how to implement TV-compatible
+ navigation.</dd>
+ <dt><a href="{@docRoot}training/tv/start/hardware.html">
+ Handling TV Hardware</a></dt>
+ <dd>Learn how to check if your app is running on TV hardware, handle unsupported hardware
+ features, and manage controller devices.</dd>
+</dl>
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
new file mode 100644
index 0000000..d2abe1d
--- /dev/null
+++ b/docs/html/training/tv/start/layouts.jd
@@ -0,0 +1,257 @@
+page.title=Building Layouts for TV
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#themes">Use Layout Themes for TV</a></li>
+ <li><a href="#structure">Build Basic TV Layouts</a></li>
+ <li><a href="#visibility">Build Useable Text and Controls</a></li>
+ <li><a href="#density-resources">Manage Layout Resources for TV</a></li>
+ <li><a href="#anti-patterns">Avoid Layout Anti-Patterns</a></li>
+ <li><a href="#large-bitmaps">Handle Large Bitmaps</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}design/tv/index.html">Android TV Design</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ A TV screen is typically viewed from about 10 feet away, and while it is much larger than most
+ other Android device displays, this type of screen does not provide the same level of precise
+ detail and color as a smaller device. These factors require you to create app layouts with TV
+ devices in mind in order to create a useful and enjoyable user experience.
+</p>
+
+<p>
+ This lesson describes the minimum requirements and implementation details for building effective
+ layouts in TV apps.
+</p>
+
+<h2 id="themes">Use Layout Themes for TV</h2>
+
+<p>
+ Android <a href="{@docRoot}guide/topics/ui/themes.html">Themes</a> can provide a basis for
+ layouts in your TV apps. You should use a theme to modify the display of your app activities that
+ are meant to run on a TV device. This section explains which themes you should use.
+</p>
+
+<h3 id="leanback-theme">Leanback theme</h3>
+
+<p>
+ A support library for TV user interfaces called the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback library</a> provides a
+ standard theme for TV activities, called {@code Theme.Leanback}. This theme establishes a
+ consistent visual style for TV apps. Use of this theme is recommended for most TV apps. This
+ theme is strongly recommended for any TV app that uses v17 leanback classes. The following code
+ sample shows how to apply this theme to a given activity within an app:
+</p>
+
+<pre>
+<activity
+ android:name="com.example.android.TvActivity"
+ android:label="@string/app_name"
+ <strong>android:theme="@style/Theme.Leanback"</strong>>
+</pre>
+
+
+<h3 id="notitle-theme">NoTitleBar theme</h3>
+
+<p>
+ The title bar is a standard user interface element for Android apps on phones and tablets, but it
+ is not appropriate for TV apps. If you are not using v17 leanback classes, you should apply this
+ theme to your TV activities to suppress the display of a title bar. The following code example
+ from a TV app manifest demonstrates how to apply this theme to remove the display of a title bar:
+</p>
+
+<pre>
+<application>
+ ...
+
+ <activity
+ android:name="com.example.android.TvActivity"
+ android:label="@string/app_name"
+ <strong>android:theme="@android:style/Theme.NoTitleBar"</strong>>
+ ...
+
+ </activity>
+</application>
+</pre>
+
+
+<h2 id="structure">Build Basic TV Layouts</h2>
+
+<p>Layouts for TV devices should follow some basic guidelines to ensure they are usable and
+ effective on large screens. Follow these tips to build landscape layouts optimized for TV screens:
+</p>
+
+<ul>
+ <li>Build layouts with a landscape orientation. TV screens always display in landscape mode.</li>
+ <li>Put on-screen navigation controls on the left or right side of the screen and save the
+ vertical space for content.</li>
+ <li>Create UIs that are divided into sections, using <a href="{@docRoot}guide/components/fragments.html"
+ >Fragments</a>, and use view groups like {@link android.widget.GridView} instead of {@link
+ android.widget.ListView} to make better use of the horizontal screen space.
+ </li>
+ <li>Use view groups such as {@link android.widget.RelativeLayout} or {@link
+ android.widget.LinearLayout} to arrange views. This approach allows the system to adjust the
+ position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.</li>
+ <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
+</ul>
+
+
+<h3 id="overscan">Overscan</h3>
+
+<p>Layouts for TV have some unique requirements due to the evolution of TV standards and the
+ desire to always present a full screen picture to viewers. For this reason, TV devices may
+ clip the outside edge of an app layout in order to ensure that the entire display is filled.
+ This behavior is generally referred to as <em>overscan</em>.
+</p>
+
+<p>
+ Avoid screen elements being clipped due to overscan and by incorporating a 10% margin
+ on all sides of your layout. This translates into a 27dp margin on the left and right edges and
+ a 48dp margin on the top and bottom of your base layouts for activities. The following
+ example layout demonstrates how to set these margins in the root layout for a TV app:
+</p>
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/base_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:layout_marginTop="27dp"
+ android:layout_marginLeft="48dp"
+ android:layout_marginRight="48dp"
+ android:layout_marginBottom="27dp" >
+</LinearLayout>
+</pre>
+
+<p class="caution">
+ <strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the
+ v17 leanback classes, such as {@link android.support.v17.leanback.app.BrowseFragment} or related
+ widgets, as those layouts already incorporate overscan-safe margins.
+</p>
+
+<h2 id="visibility">Build Useable Text and Controls</h2>
+
+<p>
+ The text and controls in a TV app layout should be easily visible and navigable from a distance.
+ Follow these tips to make your user interface elements easier to see from a distance:
+</p>
+
+<ul>
+ <li>Break text into small chunks that users can quickly scan.</li>
+ <li>Use light text on a dark background. This style is easier to read on a TV.</li>
+ <li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes.
+ Use simple sans-serif fonts and anti-aliasing to increase readability.</li>
+ <li>Use Android's standard font sizes:
+<pre>
+<TextView
+ android:id="@+id/atext"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ <strong>android:textAppearance="?android:attr/textAppearanceMedium"/></strong>
+</pre>
+ </li>
+ <li>Ensure that all your view widgets are large enough to be clearly visible to someone
+ sitting 10 feet away from the screen (this distance is greater for very large screens). The
+ best way to do this is to use layout-relative sizing rather than absolute sizing, and
+ density-independent pixel (dip) units instead of absolute pixel units. For example, to set the
+ width of a widget, use {@code wrap_content} instead of a pixel measurement, and to set the
+ margin for a widget, use dip values instead of px values.</li>
+</ul>
+
+<p>
+ For more information about density-independent pixels and building layouts to handle larger
+ screen sizes, see <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+ Screens</a>.
+</p>
+
+<h2 id="density-resources">Manage Layout Resources for TV</h2>
+
+<p>The common high-definition TV display resolutions are 720p, 1080i, and 1080p.
+ Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android
+ system to downscale your layout elements to 720p if necessary. In general, downscaling
+ (removing pixels) does not degrade your layout presentation quality. However, upscaling can
+ cause display artifacts that degrade the quality of your layout and have a negative impact on
+ the user experience of your app.</p>
+
+<p>
+ To get the best scaling results for images, provide them as
+ <a href="{@docRoot}tools/help/draw9patch.html">9-patch image</a> elements if possible. If you
+ provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or
+ grainy, which is not a good experience for the user. Use high-quality images instead.
+</p>
+
+<p>
+ For more information on optimizing layouts and resources for large screens see
+ <a href="{@docRoot}training/multiscreen/index.html">Designing for multiple screens</a>.
+</p>
+
+
+<h2 id="anti-patterns">Avoid Layout Anti-Patterns</h2>
+
+<p>
+ There are a few approaches to building layouts that you should avoid because they do not work
+ well on TV devices and lead to bad user experiences. Here are some user interface approaches you
+ should specifically <em>not</em> use when developing a layout for TV.
+</p>
+
+<ul>
+ <li><strong>Re-using phone or tablet layouts</strong> - Do not reuse layouts from a phone or
+ tablet app without modification. Layouts built for other Android device form factors are not
+ well suited for TV devices and should be simplified for operation on a TV.</li>
+ <li><strong>ActionBar</strong> - While this user interface convention is recommended for use
+ on phones and tablets, it is not appropriate for a TV interface. In particular, using an
+ action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due
+ to the difficulty in navigating such a menu with a remote control.</li>
+ <li><strong>ViewPager</strong> - Sliding between screens can work great on a phone or tablet,
+ but don't try this on a TV!</li>
+</ul>
+
+<p>For more information on designing layouts that are appropriate to TV, see the
+ <a href="{@docRoot}design/tv/index.html">TV Design</a> guide.</p>
+
+
+<h2 id="large-bitmaps">Handle Large Bitmaps</h2>
+
+<p>TV devices, like any other Android device, have a limited amount of memory. If you build your
+ app layout with very high-resolution images or use many high-resolution images in the operation
+ of your app, it can quickly run into memory limits and cause out of memory errors.
+ To avoid these types of problems, follow these tips:</p>
+
+<ul>
+ <li>Load images only when they are displayed on the screen. For example, when displaying multiple
+ images in a {@link android.widget.GridView} or {@link android.widget.Gallery}, only load an image
+ when {@link android.widget.Adapter#getView getView()} is called on the
+ view's {@link android.widget.Adapter}.
+ </li>
+ <li>Call {@link android.graphics.Bitmap#recycle()} on {@link android.graphics.Bitmap} views that
+ are no longer needed.
+ </li>
+ <li>Use {@link java.lang.ref.WeakReference} for storing references to {@link
+ android.graphics.Bitmap} objects in an in-memory {@link java.util.Collection}.
+ </li>
+ <li>If you fetch images from the network, use {@link android.os.AsyncTask} to fetch and store
+ them on the device for faster access. Never do network transactions on the application's main
+ user interface thread.
+ </li>
+ <li>Scale down large images to a more appropriate size as you download them; otherwise,
+ downloading the image itself may cause an out of memory exception.
+ </li>
+</ul>
+
+<p>
+ For more information on getting the best performance when working with images, see
+ <a href="{@docRoot}training/displaying-bitmaps/index.html">Displaying Bitmaps Efficiently</a>.
+</p>
diff --git a/docs/html/training/tv/start/navigation.jd b/docs/html/training/tv/start/navigation.jd
new file mode 100644
index 0000000..1c9faca
--- /dev/null
+++ b/docs/html/training/tv/start/navigation.jd
@@ -0,0 +1,180 @@
+page.title=Creating TV Navigation
+page.tags="focus","selection","d-pad"
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#d-pad-navigation">Enable D-pad Navigation</a></li>
+ <li><a href="#focus-selection">Provide Clear Focus and Selection</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>
+ TV devices provide a limited set of navigation controls for apps. Creating an effective
+ navigation scheme for your TV app depends on understanding these limited controls and the limits
+ of users' perception while operating your app. As you build your Android app for TVs,
+ pay special attention to how the user actually navigates around your app when using remote
+ control buttons instead of a touch screen.
+</p>
+
+<p>
+ This lesson explains the minimum requirements for creating effective TV app navigation scheme and
+ how to apply those requirements to your app.
+</p>
+
+
+<h2 id="d-pad-navigation">Enable D-pad Navigation</h2>
+
+<p>
+ On a TV device, users navigate with controls on a remote control device, using either a
+ directional pad (D-pad) or arrow keys. This type of control limits movement to up, down, left,
+ and right. To build a great TV-optimized app, you must provide a navigation scheme where the user
+ can quickly learn how to navigate your app using these limited controls.
+</p>
+
+<p>
+ The Android framework handles directional navigation between layout elements automatically, so
+ you typically do not need to do anything extra for your app. However, you should thoroughly test
+ navigation with a D-pad controller to discover any navigation problems. Follow these guidelines to
+ test that your app's navigation system works well with a D-pad on a TV device:
+</p>
+
+<ul>
+ <li>Ensure that a user with a D-pad controller can navigate to all visible controls on the
+ screen.
+ </li>
+ <li>For scrolling lists with focus, make sure that the D-pad up and down keys scroll the list,
+ and the Enter key selects an item in the list. Verify that users can select an element in the
+ list and that the list still scrolls when an element is selected.
+ </li>
+ <li>Ensure that switching between controls between controls is straightforward and predictable.
+ </li>
+</ul>
+
+
+<h3 id="modify-d-pad-nav">Modifying directional navigation</h3>
+
+<p>
+ The Android framework automatically applies a directional navigation scheme based on the
+ relative position of focusable elements in your layouts. You should test the generated
+ navigation scheme in your app using a D-pad controller. After testing, if you decide you want
+ users to move through your layouts in a specific way, you can set up explicit directional
+ navigation for your controls.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You should only use these attributes to modify the navigation order if the
+ default order that the system applies does not work well.
+</p>
+
+<p>
+ The following code sample shows how to define the next control to receive focus for a {@link
+ android.widget.TextView} layout object:
+</p>
+
+<pre>
+<TextView android:id="@+id/Category1"
+ android:nextFocusDown="@+id/Category2"\>
+</pre>
+
+<p>
+ The following table lists all of the available navigation attributes for Android user interface
+ widgets:
+</p>
+
+<table>
+ <tr>
+ <th>Attribute</th>
+ <th>Function</th>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusDown}</td>
+ <td>Defines the next view to receive focus when the user navigates down.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusLeft}</td>
+ <td>Defines the next view to receive focus when the user navigates left.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusRight}</td>
+ <td>Defines the next view to receive focus when the user navigates right.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusUp}</td>
+ <td>Defines the next view to receive focus when the user navigates up.</td>
+ </tr>
+</table>
+
+<p>
+ To use one of these explicit navigation attributes, set the value to the ID ({@code android:id}
+ value) of another widget in the layout. You should set up the navigation order as a loop, so that
+ the last control directs focus back to the first one.
+</p>
+
+
+
+<h2 id="focus-selection">Provide Clear Focus and Selection</h2>
+
+<p>
+ The success of an app's navigation scheme on TV devices is depends on how easy it is for
+ a user to determine what user interface element is in focus on screen. If you do not provide
+ clear indications of focused items (and therefore what item a user can take action on), they can
+ quickly become frustrated and exit your app. For the same reason, it is important to always have
+ an item in focus that a user can take action on immediately after your app starts, or any time
+ it is idle.
+</p>
+
+<p>
+ Your app layout and implementation should use color, size, animation, or a combination of these
+ attributes to help users easily determine what actions they can take next. Use a uniform scheme
+ for indicating focus across your application.
+</p>
+
+<p>
+ Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">
+ Drawable State List Resources</a> to implement highlights for focused and selected controls. The
+ following code example demonstrates how to enable visual behavior for a button to indicate that a
+ user has navigated to the control and then selected it:
+</p>
+
+<pre>
+<!-- res/drawable/button.xml -->
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/button_pressed" /> <!-- pressed -->
+ <item android:state_focused="true"
+ android:drawable="@drawable/button_focused" /> <!-- focused -->
+ <item android:state_hovered="true"
+ android:drawable="@drawable/button_focused" /> <!-- hovered -->
+ <item android:drawable="@drawable/button_normal" /> <!-- default -->
+</selector>
+</pre>
+
+<p>
+ The following layout XML sample code applies the previous state list drawable to a
+ {@link android.widget.Button}:
+</p>
+
+<pre>
+<Button
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:background="@drawable/button" />
+</pre>
+
+<p>
+ Make sure to provide sufficient padding within the focusable and selectable controls so that the
+ highlights around them are clearly visible.
+</p>
+
+<p>
+ For more recommendations on designing effective selection and focus for your TV app, see
+ <a href="{@docRoot}design/tv/patterns.html">Patterns for TV</a>.
+</p>
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
new file mode 100644
index 0000000..bebeedd
--- /dev/null
+++ b/docs/html/training/tv/start/start.jd
@@ -0,0 +1,259 @@
+page.title=Get Started with TV Apps
+page.tags="leanback","recyclerview","launcher"
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#dev-project">Setup a TV Project</a></li>
+ <li><a href="#build-it">Build TV Apps</a></li>
+ <li><a href="#run">Run TV Apps</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}design/tv/index.html">
+ TV Design</a></li>
+ <li><a href="{@docRoot}training/tv/start/layouts.html">
+ Building TV Layouts</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ TV apps use the same structure as those for phones and tablets. This similarity means you can
+ modify your existing apps to also run on TV devices or create new apps based on what you already
+ know about building apps for Android.
+</p>
+
+<p class="note">
+ <strong>Important:</strong> There are specific requirements your app must meet to
+ qualify as an Android TV app on Google Play. For more information, see the requirements listed
+ in <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
+</p>
+
+<p>
+ This lesson describes how to prepare your development environment for building TV apps, and the
+ minimum required changes to enable an app to run on TV devices.
+</p>
+
+
+<h2 id="dev-project">Set up a TV Project</h2>
+
+<p>
+ This section discusses how to modify an existing app to run on TV devices, or create a new one.
+ These are the main components you must use to create an app that runs on TV devices:
+</p>
+
+<ul>
+ <li><strong>Activity for TV</strong> (Required) - In your application manifest,
+ declare an activity that is intended to run on TV devices.</li>
+ <li><strong>TV Support Libraries</strong> (Optional) - There are several
+ <a href="#tv-libraries">Support Libraries</a>
+ available for TV devices that provide widgets for building user interfaces.</li>
+</ul>
+
+
+<h3 id="prerequisites">Prerequisites</h3>
+
+<p>Before you begin building apps for TV, you must:</p>
+
+<ul>
+ <li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
+ Update your SDK tools to version 24.0.0 or higher</a></strong>
+ <br>
+ The updated SDK tools enable you to build and test apps for TV.
+ </li>
+ <li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
+ Update your SDK with Android 5.0 (API 21) or higher</a></strong>
+ <br>
+ The updated platform version provides new APIs for TV apps.
+ </li>
+ <li><strong><a href="{@docRoot}sdk/installing/create-project.html">
+ Create or update your app project</a></strong>
+ <br>
+ In order to access new APIs for TV devices, you must create a project or modify an existing
+ project that targets Android 5.0 (API level 21) or higher.
+ </li>
+</ul>
+
+
+<h3 id="tv-activity">Declare a TV Activity</h3>
+
+<p>An application intended to run on TV devices must declare a launcher activity for TV
+ in its manifest using a {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter.
+ This filter identifies your app as being enabled for TV, allowing it to be considered a TV app
+ in Google Play. Declaring this intent also identifies which activity
+ in your app to launch when a user selects its icon on the TV home screen.</p>
+
+<p class="caution">
+ <strong>Caution:</strong> If you do not include the {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter in
+ your app, it is not visible to users running the Google Play store on TV devices. Also, if your
+ app does not have this filter when you load it onto a TV device using developer tools, the app
+ does not appear in the TV user interface.
+</p>
+
+<p>The following code snippet shows how to include this intent filter in your manifest:</p>
+
+<pre>
+<application>
+ ...
+ <activity
+ android:name="com.example.android.MainActivity"
+ android:label="@string/app_name" >
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="com.example.android.<strong>TvActivity</strong>"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.Leanback">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="<strong>android.intent.category.LEANBACK_LAUNCHER</strong>" />
+ </intent-filter>
+
+ </activity>
+</application>
+</pre>
+
+<p>
+ The second activity manifest entry in this example specifies that activity as the one to
+ launch on a TV device.
+</p>
+
+<p>
+ If you are modifying an existing app for use on TV, your app should not use the same
+ activity layout for TV that it does for phones and tablets. The user interface of your TV app (or
+ TV portion of your existing app) should provide a simpler interface that can be easily navigated
+ using a remote control from a couch. For guidelines on designing an app for TV, see the <a href=
+ "{@docRoot}design/tv/index.html">TV Design</a> guide. For more information on the minimum
+ implementation requirements for interface layouts on TV, see <a href=
+ "{@docRoot}training/tv/start/layouts.html">Building TV Layouts</a>.
+</p>
+
+
+<h3 id="tv-libraries">Add TV support libraries</h3>
+
+<p>
+ The Android SDK includes support libraries that are intended for use with TV apps. These
+ libraries provide APIs and user interface widgets for use on TV devices. The libraries are
+ located in the {@code <sdk>/extras/android/support/} directory. Here is a list of the
+ libraries and their general purpose:
+</p>
+
+<ul>
+ <li><a href="{@docRoot}tools/support-library/features.html#v17-leanback">
+ <strong>v17 leanback library</strong></a> - Provides user interface widgets for TV apps,
+ particularly for apps that do media playback.
+ </li>
+ <li><a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">
+ <strong>v7 recyclerview library</strong></a> - Provides classes for managing display of long
+ lists in a memory efficient manner. Several classes in the v17 leanback library depend on the
+ classes in this library.
+ </li>
+ <li><a href="{@docRoot}tools/support-library/features.html#v7-cardview">
+ <strong>v7 cardview library</strong></a> - Provides user interface widgets for displaying
+ information cards, such as media item pictures and descriptions.
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Note:</strong> You are not required to use these support libraries for your TV app.
+ However, we strongly recommend using them, particularly for apps that provide a media catalog
+ browsing interface.
+</p>
+
+<p>
+ If you decide to use the v17 leanback library for your app, you should note that it is dependent
+ on the <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. This
+ means that apps that use the leanback support library should include all of these support
+ libraries:
+</p>
+
+<ul>
+ <li>v4 support library</li>
+ <li>v7 recyclerview support library</li>
+ <li>v17 leanback support library</li>
+</ul>
+
+<p>
+ The v17 leanback library contains resources, which require you to take specific steps to include
+ it in app projects. For instructions on importing a support library with resources, see
+ <a href="{@docRoot}tools/support-library/setup.html#libs-with-res">Support Library Setup</a>.
+</p>
+
+
+<h2 id="build-it">Build TV Apps</h2>
+
+<p>After you have completed the steps described above, it's time to start building apps for
+ the big screen! Check out these additional topics to help you build your app for TV:
+
+<ul>
+ <li>
+ <a href="{@docRoot}training/tv/playback/index.html">Building TV Playback Apps</a> - TVs are
+ built to entertain, so Android provides a set of user interface tools and widgets for building
+ TV apps that play videos and music, and let users browse for the content they want.
+ </li>
+ <li>
+ <a href="{@docRoot}training/tv/search/index.html">Surfacing Content on TV</a> - With all the
+ content choices at users' fingertips, helping them find content they enjoy is almost as important
+ as providing that content. This training discusses how to surface your content on TV devices.
+ </li>
+ <li>
+ <a href="{@docRoot}training/tv/games/index.html">Games for TV</a> - TV devices are a great
+ platform for games. See this topic for information on building great game experiences for TV.
+ </li>
+</ul>
+
+
+<h2 id="run">Run TV Apps</h2>
+
+<p>
+ Running your app is an important part of the development process. The AVD Manager in the Android
+ SDK provides the device definitions that allow you to create virtual TV devices for running and
+ testing your applications.
+</p>
+
+<p>To create an virtual TV device:</p>
+
+<ol>
+ <li>Start the AVD Manager. For more information, see the
+ <a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> help.</li>
+ <li>In the AVD Manager dialog, click the <strong>Device Definitions</strong> tab.</li>
+ <li>Select one of the Android TV device definitions and click <strong>Create AVD</strong>.</li>
+ <li>Select the emulator options and click <strong>OK</strong> to create the AVD.
+ <p class="note">
+ <strong>Note:</strong> For best performance of the TV emulator device, enable the <strong>Use
+ Host GPU</strong> option and, where supported, use virtual device acceleration. For
+ more information on hardware acceleration of the emulator, see
+ <a href="{@docRoot}tools/devices/emulator.html#acceleration">Using the Emulator</a>.
+ </p>
+ </li>
+</ol>
+
+<p>To test your application on the virtual TV device:</p>
+
+<ol>
+ <li>Compile your TV application in your development environment.</li>
+ <li>Run the application from your development environment and choose the TV virtual device as
+ the target.</li>
+</ol>
+
+<p>
+ For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
+ Using the Emulator</a>. For more information on deploying apps from Android Studio to virtual
+ devices, see <a href="{@docRoot}sdk/installing/studio-debug.html">Debugging with Android
+ Studio</a>. For more information about deploying apps to emulators from Eclipse with ADT, see
+ <a href="{@docRoot}tools/building/building-eclipse.html">Building and Running from Eclipse with
+ ADT</a>.
+</p>
diff --git a/docs/html/training/tv/unsupported-features-tv.jd b/docs/html/training/tv/unsupported-features-tv.jd
deleted file mode 100644
index a9f090b..0000000
--- a/docs/html/training/tv/unsupported-features-tv.jd
+++ /dev/null
@@ -1,157 +0,0 @@
-page.title=Handling Features Not Supported on TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-previous.title=Optimizing Navigation for TV
-previous.link=optimizing-navigation-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</a></li>
- <li><a href="#CheckAvailableFeatures">Check for Available Features at Runtime</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>
-TVs are much different from other Android-powered devices:
-</p>
-<ul>
- <li>They're not mobile.</li>
- <li>Out of habit, people use them for watching media with little or no interaction.</li>
- <li>People interact with them from a distance.</li>
-</ul>
-
-<p>
-Because TVs have a different purpose from other devices, they usually don't have hardware features
-that other Android-powered devices often have. For this reason, the Android system does not
-support the following features for a TV device:
-<table>
-<tr>
-<th>Hardware</th>
-<th>Android feature descriptor</th>
-</tr>
-<tr>
-<td>Camera</td>
-<td>android.hardware.camera</td>
-</tr>
-<tr>
-<td>GPS</td>
-<td>android.hardware.location.gps</td>
-</tr>
-<tr>
-<td>Microphone</td>
-<td>android.hardware.microphone</td>
-</tr>
-<tr>
-<td>Near Field Communications (NFC)</td>
-<td>android.hardware.nfc</td>
-</tr>
-<tr>
-<td>Telephony</td>
-<td>android.hardware.telephony</td>
-</tr>
-<tr>
-<td>Touchscreen</td>
-<td>android.hardware.touchscreen</td>
-</tr>
-</table>
-</p>
-
-<p>
-This lesson shows you how to work around features that are not available on TV by:
-<ul>
- <li>Providing work arounds for some non-supported features.</li>
- <li>Checking for available features at runtime and conditionally activating/deactivating certain code
- paths based on availability of those features.</li>
-</ul>
-</p>
-
-
-<h2 id="WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</h2>
-
-<p>
-Android doesn't support touchscreen interaction for TV devices, most TVs don't have touch screens,
-and interacting with a TV using a touchscreen is not consistent with the 10 foot environment. For
-these reasons, users interact with Android-powered TVs using a remote. In consideration of this,
-ensure that every control in your app can be accessed with the D-pad. Refer back to the previous two lessons
-<a href="{@docRoot}training/tv/optimizing-layouts-tv.html">Optimizing Layouts for TV</a> and
-<a href="{@docRoot}training/tv/optimizing-navigation-tv.html">Optimize Navigation for TV</a> for
-more details
-on this topic. The Android system assumes that a device has a touchscreen, so if you want your application
-to run on a TV, you must <strong>explicitly</strong> disable the touchscreen requirement in your manifest file:
-<pre>
-<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
-</pre>
-</p>
-
-<p>
-Although a TV doesn't have a camera, you can still provide a photography-related application on a TV.
-For example, if you have an app that takes, views and edits photos, you can disable its picture-taking
-functionality for TVs and still allow users to view and even edit photos. The next section talks about how to
-deactivate or activate specific functions in the application based on runtime device type detection.
-</p>
-
-<p>
-Because TVs are stationary, indoor devices, they don't have built-in GPS. If your application uses location
-information, allow users to search for a location or use a "static" location provider to get
-a location from the zip code configured during the TV setup.
-<pre>
-LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
-Location location = locationManager.getLastKnownLocation("static");
-Geocoder geocoder = new Geocoder(this);
-Address address = null;
-
-try {
- address = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1).get(0);
- Log.d("Zip code", address.getPostalCode());
-
-} catch (IOException e) {
- Log.e(TAG, "Geocoder error", e);
-}
-</pre>
-</p>
-
-<p>
-TVs usually don't support microphones, but if you have an application that uses voice control,
-you can create a mobile device app that takes voice input and then acts as a remote control for a TV.
-</p>
-
-<h2 id="CheckAvailableFeatures">Check for Available Features at Runtime</h2>
-
-<p>
-To check if a feature is available at runtime, call
-{@link android.content.pm.PackageManager#hasSystemFeature(String)}.
- This method takes a single argument : a string corresponding to the
-feature you want to check. For example, to check for touchscreen, use
-{@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument
-{@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.
-</p>
-
-<p>
-The following code snippet demonstrates how to detect device type at runtime based on supported features:
-
-<pre>
-// Check if android.hardware.telephony feature is available.
-if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
- Log.d("Mobile Test", "Running on phone");
-// Check if android.hardware.touchscreen feature is available.
-} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
- Log.d("Tablet Test", "Running on devices that don't support telphony but have a touchscreen.");
-} else {
- Log.d("TV Test", "Running on a TV!");
-}
-</pre>
-</p>
-
-<p>
-This is just one example of using runtime checks to deactivate app functionality that depends on features
-that aren't available on TVs.
-</p>
\ No newline at end of file
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 8cef137..b5d2885 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -4175,57 +4175,61 @@
continue;
}
- const ssize_t ti = group->findType16(type, typeLen);
- if (ti < 0) {
- TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
- continue;
- }
-
- const TypeList& typeList = group->types[ti];
- if (typeList.isEmpty()) {
- TABLE_NOISY(printf("Expected type structure not found in package %s for index %d\n",
- String8(group->name).string(), ti));
- continue;
- }
-
- const size_t typeCount = typeList.size();
- for (size_t i = 0; i < typeCount; i++) {
- const Type* t = typeList[i];
- const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen);
- if (ei < 0) {
+ const size_t packageCount = group->packages.size();
+ for (size_t pi = 0; pi < packageCount; pi++) {
+ ssize_t ti = group->packages[pi]->typeStrings.indexOfString(type, typeLen);
+ if (ti < 0) {
continue;
}
- const size_t configCount = t->configs.size();
- for (size_t j = 0; j < configCount; j++) {
- const TypeVariant tv(t->configs[j]);
- for (TypeVariant::iterator iter = tv.beginEntries();
- iter != tv.endEntries();
- iter++) {
- const ResTable_entry* entry = *iter;
- if (entry == NULL) {
- continue;
- }
+ ti += group->packages[pi]->typeIdOffset;
- if (dtohl(entry->key.index) == (size_t) ei) {
- uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index());
- if (outTypeSpecFlags) {
- Entry result;
- if (getEntry(group, ti, iter.index(), NULL, &result) != NO_ERROR) {
- ALOGW("Failed to find spec flags for %s:%s/%s (0x%08x)",
- String8(group->name).string(),
- String8(String16(type, typeLen)).string(),
- String8(String16(name, nameLen)).string(),
- resId);
- return 0;
- }
- *outTypeSpecFlags = result.specFlags;
+ const TypeList& typeList = group->types[ti];
+ if (typeList.isEmpty()) {
+ TABLE_NOISY(printf("Expected type structure not found in package %s for index %d\n",
+ String8(group->name).string(), ti));
+ continue;
+ }
- if (fakePublic) {
- *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
- }
+ const size_t typeCount = typeList.size();
+ for (size_t i = 0; i < typeCount; i++) {
+ const Type* t = typeList[i];
+ const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen);
+ if (ei < 0) {
+ continue;
+ }
+
+ const size_t configCount = t->configs.size();
+ for (size_t j = 0; j < configCount; j++) {
+ const TypeVariant tv(t->configs[j]);
+ for (TypeVariant::iterator iter = tv.beginEntries();
+ iter != tv.endEntries();
+ iter++) {
+ const ResTable_entry* entry = *iter;
+ if (entry == NULL) {
+ continue;
}
- return resId;
+
+ if (dtohl(entry->key.index) == (size_t) ei) {
+ uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index());
+ if (outTypeSpecFlags) {
+ Entry result;
+ if (getEntry(group, ti, iter.index(), NULL, &result) != NO_ERROR) {
+ ALOGW("Failed to find spec flags for %s:%s/%s (0x%08x)",
+ String8(group->name).string(),
+ String8(String16(type, typeLen)).string(),
+ String8(String16(name, nameLen)).string(),
+ resId);
+ return 0;
+ }
+ *outTypeSpecFlags = result.specFlags;
+
+ if (fakePublic) {
+ *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
+ }
+ }
+ return resId;
+ }
}
}
}
diff --git a/libs/androidfw/tests/Split_test.cpp b/libs/androidfw/tests/Split_test.cpp
index 82703f9..f63f566 100644
--- a/libs/androidfw/tests/Split_test.cpp
+++ b/libs/androidfw/tests/Split_test.cpp
@@ -179,7 +179,7 @@
EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);
}
-TEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) {
+TEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) {
ResTable table;
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
@@ -200,4 +200,17 @@
String16(name.name, name.nameLen));
}
+TEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) {
+ ResTable table;
+ ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
+ ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
+
+ const String16 name("test3");
+ const String16 type("string");
+ const String16 package("com.android.test.basic");
+ ASSERT_EQ(base::R::string::test3, table.identifierForName(name.string(), name.size(),
+ type.string(), type.size(),
+ package.string(), package.size()));
+}
+
} // namespace
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index 05acf90..d0f3334 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -16,6 +16,7 @@
package android.media;
+import android.net.NetworkUtils;
import android.os.IBinder;
import android.os.StrictMode;
import android.util.Log;
@@ -25,6 +26,7 @@
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
+import java.net.Proxy;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
@@ -137,6 +139,29 @@
}
}
+ private static final boolean isLocalHost(URL url) {
+ if (url == null) {
+ return false;
+ }
+
+ String host = url.getHost();
+
+ if (host == null) {
+ return false;
+ }
+
+ try {
+ if (host.equalsIgnoreCase("localhost")) {
+ return true;
+ }
+ if (NetworkUtils.numericToInetAddress(host).isLoopbackAddress()) {
+ return true;
+ }
+ } catch (IllegalArgumentException iex) {
+ }
+ return false;
+ }
+
private void seekTo(long offset) throws IOException {
teardownConnection();
@@ -145,8 +170,17 @@
int redirectCount = 0;
URL url = mURL;
+
+ // do not use any proxy for localhost (127.0.0.1)
+ boolean noProxy = isLocalHost(url);
+
while (true) {
- mConnection = (HttpURLConnection)url.openConnection();
+ if (noProxy) {
+ mConnection = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
+ } else {
+ mConnection = (HttpURLConnection)url.openConnection();
+ }
+
// handle redirects ourselves if we do not allow cross-domain redirect
mConnection.setInstanceFollowRedirects(mAllowCrossDomainRedirect);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 0ed82d9..fef1f4a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -421,9 +421,11 @@
if (showRootIcon) {
mToolbar.setNavigationIcon(
root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
mToolbar.setNavigationOnClickListener(null);
} else {
mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f6fc435..148bd5f 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -330,7 +330,7 @@
<string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar ahora"</string>
- <string name="empty_shade_text" msgid="708135716272867002">"Ninguna notificación"</string>
+ <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
<string name="device_owned_footer" msgid="3802752663326030053">"Es posible que este dispositivo esté supervisado"</string>
<string name="profile_owned_footer" msgid="8021888108553696069">"Es posible que se supervise el perfil"</string>
<string name="vpn_footer" msgid="2388611096129106812">"Puede que la red esté supervisada"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 100ef5e..31fb4637 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -69,7 +69,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"កំពុងរក្សាទុករូបថតអេក្រង់…"</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"កំពុងរក្សាទុករូបថតអេក្រង់..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"រូបថតអេក្រង់កំពុងត្រូវបានរក្សាទុក។"</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"ប៉ះ ដើម្បីមើលរូបថតអេក្រង់របស់អ្នក។"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"មិនអាចចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_failed_text" msgid="1260203058661337274">"មិនអាចថតអេក្រង់ដោយសារតែទំហំផ្ទុកមានដែនកំណត់ ឬវាមិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី ឬស្ថាប័នរបស់អ្នក។"</string>
@@ -152,7 +152,7 @@
<string name="accessibility_remove_notification" msgid="3603099514902182350">"សម្អាតការជូនដំណឹង។"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"បានបើក GPS ។"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ទទួល GPS ។"</string>
- <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"កម្មវិធីរោទ៍ញ័រ។"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"កម្មវិធីរោទ៍ស្ងាត់។"</string>
<!-- no translation found for accessibility_casting (6887382141726543668) -->
@@ -236,7 +236,7 @@
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"បញ្ឈរ"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ទេសភាព"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"វិធីសាស្ត្របញ្ចូល"</string>
- <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
+ <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"ទីតាំងបានបិទ"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"ឧបករណ៍មេឌៀ"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
@@ -280,11 +280,11 @@
<string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ចាក់សោទៅកម្មវិធី"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"មិនអាចចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
- <string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string>
+ <string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"កំពុងបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> រហូតដល់ពេញ"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"មិនកំពុងបញ្ចូលថ្ម"</string>
- <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
+ <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
<string name="description_direction_up" msgid="7169032478259485180">"រុញឡើងលើដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
<string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 746dd71..502ec44 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -314,7 +314,7 @@
<string name="guest_exit_guest" msgid="7187359342030096885">"ລຶບແຂກ"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"ລຶບແຂກບໍ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ລຶບ"</string>
+ <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ລຶບ"</string>
<string name="guest_wipe_session_title" msgid="6419439912885956132">"ຍິນດີຕ້ອນຮັບກັບມາ, ຜູ່ຢ້ຽມຢາມ!"</string>
<string name="guest_wipe_session_message" msgid="8476238178270112811">"ທ່ານຕ້ອງການສືບຕໍ່ເຊດຊັນຂອງທ່ານບໍ່?"</string>
<string name="guest_wipe_session_wipe" msgid="5065558566939858884">"ເລີ່ມຕົ້ນໃຫມ່"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 0d5ebe7..e4faa6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -403,6 +403,7 @@
}
private void fadeBackground() {
+ mBackgroundNormal.animate().cancel();
if (mDimmed) {
mBackgroundDimmed.setVisibility(View.VISIBLE);
} else {
@@ -446,6 +447,7 @@
mBackgroundDimmed.setVisibility(View.VISIBLE);
mBackgroundNormal.setVisibility(View.INVISIBLE);
} else {
+ cancelFadeAnimations();
mBackgroundDimmed.setVisibility(View.INVISIBLE);
mBackgroundNormal.setVisibility(View.VISIBLE);
mBackgroundNormal.setAlpha(1f);
@@ -453,6 +455,13 @@
}
}
+ private void cancelFadeAnimations() {
+ if (mBackgroundAnimator != null) {
+ mBackgroundAnimator.cancel();
+ }
+ mBackgroundNormal.animate().cancel();
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index c612e4c..d8c99f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -774,6 +774,14 @@
requestLayout();
}
+ public void instantCollapse() {
+ abortAnimations();
+ setExpandedFraction(0f);
+ if (mExpanding) {
+ notifyExpandingFinished();
+ }
+ }
+
private void abortAnimations() {
cancelPeek();
if (mHeightAnimator != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 3b05ef1..9e3f0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3746,7 +3746,7 @@
}
private void instantCollapseNotificationPanel() {
- mNotificationPanel.setExpandedFraction(0);
+ mNotificationPanel.instantCollapse();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 6006217..47e1ab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -85,7 +85,7 @@
}
else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
- updateBluetooth(intent);
+ updateBluetooth();
}
else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
updateVolumeZen();
@@ -128,16 +128,7 @@
mService.setIconVisibility(SLOT_CDMA_ERI, false);
// bluetooth status
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- int bluetoothIcon = R.drawable.stat_sys_data_bluetooth;
- if (adapter != null) {
- mBluetoothEnabled = (adapter.getState() == BluetoothAdapter.STATE_ON);
- if (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) {
- bluetoothIcon = R.drawable.stat_sys_data_bluetooth_connected;
- }
- }
- mService.setIcon(SLOT_BLUETOOTH, bluetoothIcon, 0, null);
- mService.setIconVisibility(SLOT_BLUETOOTH, mBluetoothEnabled);
+ updateBluetooth();
// Alarm clock
mService.setIcon(SLOT_ALARM_CLOCK, R.drawable.stat_sys_alarm, 0, null);
@@ -253,25 +244,19 @@
}
}
- private final void updateBluetooth(Intent intent) {
+ private final void updateBluetooth() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
int iconId = R.drawable.stat_sys_data_bluetooth;
- String contentDescription = null;
- String action = intent.getAction();
- if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
- } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
- BluetoothAdapter.STATE_DISCONNECTED);
- if (state == BluetoothAdapter.STATE_CONNECTED) {
+ String contentDescription =
+ mContext.getString(R.string.accessibility_bluetooth_disconnected);
+ if (adapter != null) {
+ mBluetoothEnabled = (adapter.getState() == BluetoothAdapter.STATE_ON);
+ if (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED) {
iconId = R.drawable.stat_sys_data_bluetooth_connected;
contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
- } else {
- contentDescription = mContext.getString(
- R.string.accessibility_bluetooth_disconnected);
}
} else {
- return;
+ mBluetoothEnabled = false;
}
mService.setIcon(SLOT_BLUETOOTH, iconId, 0, contentDescription);
diff --git a/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml b/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml
index 2a0188a..54f8ff3 100644
--- a/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml
+++ b/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml
@@ -31,5 +31,6 @@
android:drawableLeft="@drawable/ic_actionbar_accept"
android:drawablePadding="8dp"
android:gravity="center_vertical"
- android:text="@string/wallpaper_instructions" />
+ android:text="@string/wallpaper_instructions"
+ android:textColor="@android:color/white" />
</FrameLayout>
diff --git a/packages/WallpaperCropper/res/values-af/strings.xml b/packages/WallpaperCropper/res/values-af/strings.xml
new file mode 100644
index 0000000..f4a3bc5
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-af/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Stel muurpapier"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kon nie prent as muurpapier laai nie"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Snoei muurpapier"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-am/strings.xml b/packages/WallpaperCropper/res/values-am/strings.xml
new file mode 100644
index 0000000..0afbb03
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-am/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"የግድግዳ ወረቀት አዘጋጅ"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"ምስሉን እንደ ግድግዳ ወረቀት መጫን አልተቻለም"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"የግድግዳ ወረቀት ይከርክሙ"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ar/strings.xml b/packages/WallpaperCropper/res/values-ar/strings.xml
new file mode 100644
index 0000000..4b59890
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ar/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"تعيين الخلفية"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"تعذر تحميل الصورة كخلفية"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"اقتصاص الخلفية"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-bg/strings.xml b/packages/WallpaperCropper/res/values-bg/strings.xml
new file mode 100644
index 0000000..ea0da41
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-bg/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Задаване на тапета"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Изображението не можа да бъде заредено като тапет"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Подрязване на тапета"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ca/strings.xml b/packages/WallpaperCropper/res/values-ca/strings.xml
new file mode 100644
index 0000000..f974c70
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ca/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Estableix el fons de pantalla"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"No s\'ha pogut carregar la imatge com a fons de pantalla."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Retallar fons de pantalla"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-cs/strings.xml b/packages/WallpaperCropper/res/values-cs/strings.xml
new file mode 100644
index 0000000..6aef003
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-cs/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastavit jako tapetu"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Obrázek nelze načíst jako tapetu."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Oříznutí tapety"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-da/strings.xml b/packages/WallpaperCropper/res/values-da/strings.xml
new file mode 100644
index 0000000..99c2c1b
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-da/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Angiv baggrund"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Billedet kunne ikke indlæses som baggrund"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Beskær baggrunden"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-de/strings.xml b/packages/WallpaperCropper/res/values-de/strings.xml
new file mode 100644
index 0000000..4e19406
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-de/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Hintergrund auswählen"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Bild konnte nicht als Hintergrund geladen werden."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Hintergrund zuschneiden"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-el/strings.xml b/packages/WallpaperCropper/res/values-el/strings.xml
new file mode 100644
index 0000000..ae62e07
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-el/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Ορισμός ταπετσαρίας"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Δεν ήταν δυνατή η φόρτωση της εικόνας ως ταπετσαρία"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Περικοπή ταπετσαρίας"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-en-rGB/strings.xml b/packages/WallpaperCropper/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..45293cd
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-en-rGB/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Set wallpaper"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Couldn\'t load image as wallpaper"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Crop wallpaper"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-en-rIN/strings.xml b/packages/WallpaperCropper/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..45293cd
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-en-rIN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Set wallpaper"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Couldn\'t load image as wallpaper"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Crop wallpaper"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-es-rUS/strings.xml b/packages/WallpaperCropper/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..bb9f930
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-es-rUS/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Establecer como fondo de pantalla"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"No se pudo cargar la imagen como fondo de pantalla."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar fondo de pantalla"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-es/strings.xml b/packages/WallpaperCropper/res/values-es/strings.xml
new file mode 100644
index 0000000..96a30a5
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-es/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Establecer fondo"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"No se ha podido cargar la imagen como fondo de pantalla"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar fondo de pantalla"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-et-rEE/strings.xml b/packages/WallpaperCropper/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..811986f
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-et-rEE/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Määra taustapilt"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kujutist ei õnnestunud taustapildina laadida"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Taustapildi kärpimine"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-fa/strings.xml b/packages/WallpaperCropper/res/values-fa/strings.xml
new file mode 100644
index 0000000..04ff926
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-fa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"تنظیم کاغذدیواری"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"تصویر به عنوان کاغذدیواری بارگیری نشد"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"برش کاغذدیواری"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-fi/strings.xml b/packages/WallpaperCropper/res/values-fi/strings.xml
new file mode 100644
index 0000000..e9bcfea
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-fi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Aseta taustakuva"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kuvaa ei voitu ladata taustakuvaksi"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Rajaa taustakuva"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-fr-rCA/strings.xml b/packages/WallpaperCropper/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..03da5b1
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-fr-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Définir le fond d\'écran"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossible de charger l\'image comme fond d\'écran"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Rogner le fond d\'écran"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-fr/strings.xml b/packages/WallpaperCropper/res/values-fr/strings.xml
new file mode 100644
index 0000000..1128fc8
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-fr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Définir comme fond d\'écran"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossible de charger l\'image comme fond d\'écran."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Rogner le fond d\'écran"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-hi/strings.xml b/packages/WallpaperCropper/res/values-hi/strings.xml
new file mode 100644
index 0000000..0c72a0d
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-hi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"वॉलपेपर सेट करें"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"चित्र को वॉलपेपर के रूप में लोड नहीं किया जा सका"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"वॉलपेपर काटें"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-hr/strings.xml b/packages/WallpaperCropper/res/values-hr/strings.xml
new file mode 100644
index 0000000..010e829
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-hr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Postavi pozadinsku sliku"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nije moguće učitati sliku kao pozadinsku sliku"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Obrezivanje pozadinske slike"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-hu/strings.xml b/packages/WallpaperCropper/res/values-hu/strings.xml
new file mode 100644
index 0000000..962a3a5
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-hu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Háttérkép beállítása"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"A kép betöltése háttérképként nem sikerült"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Háttérkép körbevágása"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-hy-rAM/strings.xml b/packages/WallpaperCropper/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..2893976
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-hy-rAM/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Սահմանել պաստառը"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Չհաջողվեց նկարը սահմանել որպես պաստառ"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Եզրատել պաստառը"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-in/strings.xml b/packages/WallpaperCropper/res/values-in/strings.xml
new file mode 100644
index 0000000..aca5db6
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-in/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Setel wallpaper"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Tidak dapat memuat gambar sebagai wallpaper"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Pangkas wallpaper"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-it/strings.xml b/packages/WallpaperCropper/res/values-it/strings.xml
new file mode 100644
index 0000000..b3be0ca
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-it/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Imposta sfondo"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossibile caricare l\'immagine come sfondo"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Ritaglia sfondo"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-iw/strings.xml b/packages/WallpaperCropper/res/values-iw/strings.xml
new file mode 100644
index 0000000..24c3898
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-iw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"הגדר טפט"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"לא ניתן היה לטעון את התמונה כטפט"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"חתוך את הטפט"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ja/strings.xml b/packages/WallpaperCropper/res/values-ja/strings.xml
new file mode 100644
index 0000000..4a1d5b7
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"壁紙を設定"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"画像を壁紙として読み込めませんでした"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"壁紙のトリミング"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ka-rGE/strings.xml b/packages/WallpaperCropper/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..39d3359
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ka-rGE/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"ფონის დაყენება"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"სურათი ფონად ვერ ჩაიტვირთა."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"ფონის ჩამოჭრა"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-km-rKH/strings.xml b/packages/WallpaperCropper/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..d24aeee
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-km-rKH/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"កំណត់ផ្ទាំងរូបភាព"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"មិនអាចផ្ទុករូបភាពជាផ្ទាំងរូបភាព"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"ច្រឹបផ្ទាំងរូបភាព"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ko/strings.xml b/packages/WallpaperCropper/res/values-ko/strings.xml
new file mode 100644
index 0000000..198a358
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ko/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"배경화면 설정"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"이미지를 배경화면으로 로드할 수 없습니다."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"배경화면 잘라내기"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-lo-rLA/strings.xml b/packages/WallpaperCropper/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..80f9d1a
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-lo-rLA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"ຕັ້ງເປັນພາບພື້ນຫຼັງ"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"ບໍ່ສາມາດໂຫຼດຮູບເປັນພາບພື້ນຫຼັງໄດ້"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"ຕັດພາບພື້ນຫຼັງ"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-lt/strings.xml b/packages/WallpaperCropper/res/values-lt/strings.xml
new file mode 100644
index 0000000..6b316e0
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-lt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Nustatyti ekrano foną"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nepavyko įkelti vaizdo kaip ekrano fono"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Apkirpti ekrano foną"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-lv/strings.xml b/packages/WallpaperCropper/res/values-lv/strings.xml
new file mode 100644
index 0000000..f2eceee
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-lv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Iestatīt fona tapeti"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nevarēja ielādēt attēlu kā fona tapeti."</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Apgriezt fona tapeti"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-mn-rMN/strings.xml b/packages/WallpaperCropper/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..9af8fe7
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-mn-rMN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Ханын зургийг тохируулах"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Зургийг ханын зураг болгож ачаалж чадсангүй"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Ханын зургийг тайрах"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ms-rMY/strings.xml b/packages/WallpaperCropper/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..a060c8a
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ms-rMY/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Tetapkan kertas dinding"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Tidak dapat memuatkan imej sebagai kertas dinding"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Pangkas kertas dinding"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-nb/strings.xml b/packages/WallpaperCropper/res/values-nb/strings.xml
new file mode 100644
index 0000000..702e163
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-nb/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Angi bakgrunn"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kunne ikke laste inn bildet som bakgrunn"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Beskjær bakgrunnen"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-nl/strings.xml b/packages/WallpaperCropper/res/values-nl/strings.xml
new file mode 100644
index 0000000..b804cda
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-nl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Achtergrond instellen"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kan afbeelding niet laden als achtergrond"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Achtergrond bijsnijden"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-pl/strings.xml b/packages/WallpaperCropper/res/values-pl/strings.xml
new file mode 100644
index 0000000..8686695
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-pl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Ustaw tapetę"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nie udało się załadować obrazu jako tapety"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Przytnij tapetę"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-pt-rPT/strings.xml b/packages/WallpaperCropper/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..8cecccb
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Definir imagem fundo"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Não foi possível carregar a imagem como imagem de fundo"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar imagem de fundo"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-pt/strings.xml b/packages/WallpaperCropper/res/values-pt/strings.xml
new file mode 100644
index 0000000..5919035
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-pt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Definir plano de fundo"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Não foi possível carregar a imagem como plano de fundo"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Cortar plano de fundo"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ro/strings.xml b/packages/WallpaperCropper/res/values-ro/strings.xml
new file mode 100644
index 0000000..b9c48fc
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ro/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Setați imaginea de fundal"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nu s-a putut încărca imaginea ca fundal"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Decupați imaginea de fundal"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-ru/strings.xml b/packages/WallpaperCropper/res/values-ru/strings.xml
new file mode 100644
index 0000000..c9bcb2d
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-ru/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Установить как обои"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Не удалось загрузить изображение"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Кадрировать обои"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-sk/strings.xml b/packages/WallpaperCropper/res/values-sk/strings.xml
new file mode 100644
index 0000000..07b7e35
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastaviť tapetu"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Obrázok nie je možné načítať ako tapetu"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Orezanie tapety"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-sl/strings.xml b/packages/WallpaperCropper/res/values-sl/strings.xml
new file mode 100644
index 0000000..a318d8d
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastavi ozadje"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Slike ni bilo mogoče naložiti kot ozadje"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Obrezovanje ozadja"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-sr/strings.xml b/packages/WallpaperCropper/res/values-sr/strings.xml
new file mode 100644
index 0000000..a16b77f
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Подеси позадину"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Није могуће учитати слику као позадину"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Опсеци позадину"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-sv/strings.xml b/packages/WallpaperCropper/res/values-sv/strings.xml
new file mode 100644
index 0000000..5de6a5f
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Ange bakgrund"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Det gick inte att läsa in bilden som bakgrund"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Beskär bakgrund"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-sw/strings.xml b/packages/WallpaperCropper/res/values-sw/strings.xml
new file mode 100644
index 0000000..a144405
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Weka mandhari"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Haikuweza kupakia picha iwe mandhari"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Punguza mandhari"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-th/strings.xml b/packages/WallpaperCropper/res/values-th/strings.xml
new file mode 100644
index 0000000..d0c5d06
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-th/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"ตั้งวอลเปเปอร์"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"ไม่สามารถโหลดรูปภาพเป็นวอลเปเปอร์"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"ครอบตัดวอลเปเปอร์"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-tl/strings.xml b/packages/WallpaperCropper/res/values-tl/strings.xml
new file mode 100644
index 0000000..c230871
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Itakda ang wallpaper"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Hindi ma-load ang larawan bilang wallpaper"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"I-crop ang wallpaper"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-tr/strings.xml b/packages/WallpaperCropper/res/values-tr/strings.xml
new file mode 100644
index 0000000..1f3cabb
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-tr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Duvar kağıdını ayarla"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Resim duvar kağıdı olarak yüklenemedi"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Duvar kağıdını kırp"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-uk/strings.xml b/packages/WallpaperCropper/res/values-uk/strings.xml
new file mode 100644
index 0000000..3c650d9
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-uk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Установити фон"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Не вдалося завантажити зображення як фоновий малюнок"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Обрізати фоновий малюнок"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-vi/strings.xml b/packages/WallpaperCropper/res/values-vi/strings.xml
new file mode 100644
index 0000000..5e0cc62
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-vi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Đặt hình nền"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Không thể tải hình ảnh làm hình nền"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Cắt hình nền"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-zh-rCN/strings.xml b/packages/WallpaperCropper/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..9078ba9
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-zh-rCN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"设置壁纸"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"无法加载要设为壁纸的图片"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"剪裁壁纸"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-zh-rHK/strings.xml b/packages/WallpaperCropper/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..1c9e6a3
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-zh-rHK/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"設定桌布"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"無法載入圖片設為桌布"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"裁剪桌布"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-zh-rTW/strings.xml b/packages/WallpaperCropper/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..0b67423
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-zh-rTW/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"設定桌布"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"無法載入您要設為桌布的圖片"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"裁剪桌布"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values-zu/strings.xml b/packages/WallpaperCropper/res/values-zu/strings.xml
new file mode 100644
index 0000000..454d7e5
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-zu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wallpaper_instructions" msgid="3524143401182707094">"Setha isithombe sangemuva"</string>
+ <string name="wallpaper_load_fail" msgid="4800700444605404650">"Ayikwazanga ukulayisha isithombe njengesithombe sangemuva"</string>
+ <string name="crop_wallpaper" msgid="4882870800623585836">"Nqampuna isithombe sangemuva"</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values/styles.xml b/packages/WallpaperCropper/res/values/styles.xml
index b27a387..a34b25a 100644
--- a/packages/WallpaperCropper/res/values/styles.xml
+++ b/packages/WallpaperCropper/res/values/styles.xml
@@ -15,13 +15,13 @@
-->
<resources>
- <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault.Light">
+ <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
<item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowActionBarOverlay">true</item>
</style>
- <style name="WallpaperCropperActionBar" parent="android:style/Widget.DeviceDefault.Light.ActionBar">
+ <style name="WallpaperCropperActionBar" parent="android:style/Widget.DeviceDefault.ActionBar">
<item name="android:displayOptions">showCustom</item>
<item name="android:background">#88000000</item>
</style>
diff --git a/policy/src/com/android/internal/policy/impl/GlobalKeyManager.java b/policy/src/com/android/internal/policy/impl/GlobalKeyManager.java
index 8c8209f..fc65793 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalKeyManager.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalKeyManager.java
@@ -73,6 +73,7 @@
if (component != null) {
Intent intent = new Intent(Intent.ACTION_GLOBAL_BUTTON)
.setComponent(component)
+ .setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
.putExtra(Intent.EXTRA_KEY_EVENT, event);
context.sendBroadcastAsUser(intent, UserHandle.CURRENT, null);
return true;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index e9a114a..9c81f0a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,8 @@
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.*;
+import android.app.SearchManager;
+import android.os.UserHandle;
import com.android.internal.R;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
@@ -4004,13 +4006,21 @@
* @return true if search window opened
*/
private boolean launchDefaultSearch() {
+ boolean result;
final Callback cb = getCallback();
if (cb == null || isDestroyed()) {
- return false;
+ result = false;
} else {
sendCloseSystemWindows("search");
- return cb.onSearchRequested();
+ result = cb.onSearchRequested();
}
+ if (!result && (getContext().getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
+ // On TVs, if the app doesn't implement search, we want to launch assist.
+ return ((SearchManager)getContext().getSystemService(Context.SEARCH_SERVICE))
+ .launchAssistAction(0, null, UserHandle.myUserId());
+ }
+ return result;
}
@Override
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 9a5ffbd..3694d61 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2415,6 +2415,11 @@
mStatus = invokeAgentForBackup(PACKAGE_MANAGER_SENTINEL,
IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
addBackupTrace("PMBA invoke: " + mStatus);
+
+ // Because the PMBA is a local instance, it has already executed its
+ // backup callback and returned. Blow away the lingering (spurious)
+ // pending timeout message for it.
+ mBackupHandler.removeMessages(MSG_TIMEOUT);
}
if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
@@ -7048,6 +7053,11 @@
private void startRestore() {
sendStartRestore(mAcceptSet.size());
+ // If we're starting a full-system restore, set up to begin widget ID remapping
+ if (mIsSystemRestore) {
+ AppWidgetBackupBridge.restoreStarting(UserHandle.USER_OWNER);
+ }
+
try {
String transportDir = mTransport.transportDirName();
mStateDir = new File(mBaseStateDir, transportDir);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 7b64139..636228b 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -663,7 +663,8 @@
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
Intent i = new Intent(IBluetooth.class.getName());
if (!doBind(i, mConnection,
- Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
@@ -1050,7 +1051,8 @@
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
mConnection.setGetNameAddressOnly(false);
Intent i = new Intent(IBluetooth.class.getName());
- if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
+ if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
@@ -1153,7 +1155,8 @@
if (mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Intent i = new Intent(IBluetoothGatt.class.getName());
- doBind(i, mConnection, Context.BIND_AUTO_CREATE, UserHandle.CURRENT);
+ doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.CURRENT);
}
} else {
//If Bluetooth is off, send service down event to proxy objects, and unbind
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b0535b3..976e707 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -860,6 +860,11 @@
} catch (RemoteException e) {
Slog.e(TAG, "Error setting system locale from mount service", e);
}
+
+ // Temporary workaround for http://b/17945169.
+ Slog.d(TAG, "Setting system properties to " + systemLocale + " from mount service");
+ SystemProperties.set("persist.sys.language", locale.getLanguage());
+ SystemProperties.set("persist.sys.country", locale.getCountry());
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9e0483d..8357366 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -434,10 +434,19 @@
public class PendingAssistExtras extends Binder implements Runnable {
public final ActivityRecord activity;
+ public final Bundle extras;
+ public final Intent intent;
+ public final String hint;
+ public final int userHandle;
public boolean haveResult = false;
public Bundle result = null;
- public PendingAssistExtras(ActivityRecord _activity) {
+ public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
+ String _hint, int _userHandle) {
activity = _activity;
+ extras = _extras;
+ intent = _intent;
+ hint = _hint;
+ userHandle = _userHandle;
}
@Override
public void run() {
@@ -10449,6 +10458,31 @@
}
public Bundle getAssistContextExtras(int requestType) {
+ PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
+ UserHandle.getCallingUserId());
+ if (pae == null) {
+ return null;
+ }
+ synchronized (pae) {
+ while (!pae.haveResult) {
+ try {
+ pae.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ if (pae.result != null) {
+ pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
+ }
+ }
+ synchronized (this) {
+ mPendingAssistExtras.remove(pae);
+ mHandler.removeCallbacks(pae);
+ }
+ return pae.extras;
+ }
+
+ private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
+ int userHandle) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"getAssistContextExtras()");
PendingAssistExtras pae;
@@ -10462,13 +10496,13 @@
extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
if (activity.app == null || activity.app.thread == null) {
Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
- return extras;
+ return null;
}
if (activity.app.pid == Binder.getCallingPid()) {
Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
- return extras;
+ return null;
}
- pae = new PendingAssistExtras(activity);
+ pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
try {
activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
requestType);
@@ -10476,25 +10510,10 @@
mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
} catch (RemoteException e) {
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
- return extras;
+ return null;
}
+ return pae;
}
- synchronized (pae) {
- while (!pae.haveResult) {
- try {
- pae.wait();
- } catch (InterruptedException e) {
- }
- }
- if (pae.result != null) {
- extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
- }
- }
- synchronized (this) {
- mPendingAssistExtras.remove(pae);
- mHandler.removeCallbacks(pae);
- }
- return extras;
}
public void reportAssistContextExtras(IBinder token, Bundle extras) {
@@ -10503,7 +10522,38 @@
pae.result = extras;
pae.haveResult = true;
pae.notifyAll();
+ if (pae.intent == null) {
+ // Caller is just waiting for the result.
+ return;
+ }
}
+
+ // We are now ready to launch the assist activity.
+ synchronized (this) {
+ boolean exists = mPendingAssistExtras.remove(pae);
+ mHandler.removeCallbacks(pae);
+ if (!exists) {
+ // Timed out.
+ return;
+ }
+ }
+ pae.intent.replaceExtras(extras);
+ if (pae.hint != null) {
+ pae.intent.putExtra(pae.hint, true);
+ }
+ pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ closeSystemDialogs("assist");
+ try {
+ mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist action.", e);
+ }
+ }
+
+ public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
+ return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
}
public void registerProcessObserver(IProcessObserver observer) {
@@ -12538,7 +12588,7 @@
void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
- pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
+ pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
boolean printedAnything = false;
@@ -13033,6 +13083,7 @@
pw.println(" OOM levels:");
printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
+ printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
@@ -13636,7 +13687,8 @@
return true;
}
- ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
+ ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
+ String[] args) {
ArrayList<ProcessRecord> procs;
synchronized (this) {
if (args != null && args.length > start
@@ -13651,6 +13703,9 @@
ProcessRecord proc = mLruProcesses.get(i);
if (proc.pid == pid) {
procs.add(proc);
+ } else if (allPkgs && proc.pkgList != null
+ && proc.pkgList.containsKey(args[start])) {
+ procs.add(proc);
} else if (proc.processName.equals(args[start])) {
procs.add(proc);
}
@@ -13667,7 +13722,7 @@
final void dumpGraphicsHardwareUsage(FileDescriptor fd,
PrintWriter pw, String[] args) {
- ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
+ ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
if (procs == null) {
pw.println("No process found for: " + args[0]);
return;
@@ -13703,7 +13758,7 @@
}
final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
- ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
+ ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
if (procs == null) {
pw.println("No process found for: " + args[0]);
return;
@@ -13829,7 +13884,8 @@
static final int[] DUMP_MEM_OOM_ADJ = new int[] {
ProcessList.NATIVE_ADJ,
- ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
+ ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
+ ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
@@ -13837,7 +13893,7 @@
};
static final String[] DUMP_MEM_OOM_LABEL = new String[] {
"Native",
- "System", "Persistent", "Foreground",
+ "System", "Persistent", "Persistent Service", "Foreground",
"Visible", "Perceptible",
"Heavy Weight", "Backup",
"A Services", "Home",
@@ -13845,7 +13901,7 @@
};
static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
"native",
- "sys", "pers", "fore",
+ "sys", "pers", "persvc", "fore",
"vis", "percept",
"heavy", "backup",
"servicea", "home",
@@ -13871,6 +13927,7 @@
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
+ boolean packages = false;
int opti = 0;
while (opti < args.length) {
@@ -13891,6 +13948,8 @@
oomOnly = true;
} else if ("--local".equals(opt)) {
localOnly = true;
+ } else if ("--package".equals(opt)) {
+ packages = true;
} else if ("-h".equals(opt)) {
pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
pw.println(" -a: include all available information for each process.");
@@ -13898,6 +13957,8 @@
pw.println(" -c: dump in a compact machine-parseable representation.");
pw.println(" --oom: only show processes organized by oom adj.");
pw.println(" --local: only collect details locally, don't call process.");
+ pw.println(" --package: interpret process arg as package, dumping all");
+ pw.println(" processes that have loaded that package.");
pw.println("If [process] is specified it can be the name or ");
pw.println("pid of a specific process to dump.");
return;
@@ -13911,7 +13972,7 @@
long realtime = SystemClock.elapsedRealtime();
final long[] tmpLong = new long[1];
- ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
+ ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
if (procs == null) {
// No Java processes. Maybe they want to print a native process.
if (args != null && args.length > opti
@@ -13966,7 +14027,7 @@
return;
}
- if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
+ if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
dumpDetails = true;
}
@@ -14082,7 +14143,7 @@
long nativeProcTotalPss = 0;
- if (!isCheckinRequest && procs.size() > 1) {
+ if (!isCheckinRequest && procs.size() > 1 && !packages) {
// If we are showing aggregations, also look for native processes to
// include so that our aggregations are more accurate.
updateCpuStatsNow();
@@ -16752,7 +16813,8 @@
} else {
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
|Context.BIND_IMPORTANT)) != 0) {
- adj = clientAdj;
+ adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
+ ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index a021919..6983ec4 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -871,6 +871,16 @@
if (BatteryStatsHelper.checkWifiOnly(mContext)) {
flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
}
+ if (reqUid >= 0) {
+ // By default, if the caller is only interested in a specific package, then
+ // we only dump the aggregated data since charged.
+ if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_UNPLUGGED_ONLY
+ |BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
+ flags |= BatteryStats.DUMP_CHARGED_ONLY;
+ // Also if they are doing -c, we don't want history.
+ flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
+ }
+ }
if (useCheckinFormat) {
List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
if (isRealCheckin) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 0ea66b9..5b22255 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -97,6 +97,10 @@
// rather not kill it!
static final int FOREGROUND_APP_ADJ = 0;
+ // This is a process that the system or a persistent process has bound to,
+ // and indicated it is important.
+ static final int PERSISTENT_SERVICE_ADJ = -11;
+
// This is a system persistent process, such as telephony. Definitely
// don't want to kill it, but doing so is not completely fatal.
static final int PERSISTENT_PROC_ADJ = -12;
@@ -336,6 +340,8 @@
return buildOomTag("vis ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
} else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
+ } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
+ return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
} else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
} else if (setAdj >= ProcessList.SYSTEM_ADJ) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 28e46a4..bffb541 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -791,7 +791,7 @@
reqPackage = arg;
// Include all details, since we know we are only going to
// be dumping a smaller set of data. In fact only the details
- // container per-package data, so that are needed to be able
+ // contain per-package data, so this is needed to be able
// to dump anything at all when filtering by package.
dumpDetails = true;
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index 920fdfb..f549f3d 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -226,12 +226,15 @@
GLES20.GL_VERTEX_SHADER);
int fshader = loadShader(context, com.android.internal.R.raw.color_fade_frag,
GLES20.GL_FRAGMENT_SHADER);
+ GLES20.glReleaseShaderCompiler();
if (vshader == 0 || fshader == 0) return false;
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vshader);
GLES20.glAttachShader(mProgram, fshader);
+ GLES20.glDeleteShader(vshader);
+ GLES20.glDeleteShader(fshader);
GLES20.glLinkProgram(mProgram);
@@ -254,6 +257,11 @@
return true;
}
+ private void destroyGLShaders() {
+ GLES20.glDeleteProgram(mProgram);
+ checkGlErrors("glDeleteProgram");
+ }
+
private boolean initGLBuffers() {
//Fill vertices
setQuad(mVertexBuffer, 0, 0, mDisplayWidth, mDisplayHeight);
@@ -288,6 +296,11 @@
return true;
}
+ private void destroyGLBuffers() {
+ GLES20.glDeleteBuffers(2, mGLBuffers, 0);
+ checkGlErrors("glDeleteBuffers");
+ }
+
private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) {
if (DEBUG) {
Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
@@ -314,10 +327,20 @@
Slog.d(TAG, "dismiss");
}
- destroyScreenshotTexture();
- destroyEglSurface();
- destroySurface();
- mPrepared = false;
+ if (mPrepared) {
+ attachEglContext();
+ try {
+ destroyScreenshotTexture();
+ destroyGLShaders();
+ destroyGLBuffers();
+ destroyEglSurface();
+ } finally {
+ detachEglContext();
+ }
+ destroySurface();
+ GLES20.glFlush();
+ mPrepared = false;
+ }
}
/**
@@ -468,14 +491,8 @@
private void destroyScreenshotTexture() {
if (mTexNamesGenerated) {
mTexNamesGenerated = false;
- if (attachEglContext()) {
- try {
- GLES20.glDeleteTextures(1, mTexNames, 0);
- checkGlErrors("glDeleteTextures");
- } finally {
- detachEglContext();
- }
- }
+ GLES20.glDeleteTextures(1, mTexNames, 0);
+ checkGlErrors("glDeleteTextures");
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 97748e8..09dc477 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -651,7 +651,10 @@
mDisplayDevices.add(device);
addLogicalDisplayLocked(device);
- updateDisplayStateLocked(device);
+ Runnable work = updateDisplayStateLocked(device);
+ if (work != null) {
+ work.run();
+ }
scheduleTraversalLocked(false);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index e8ab673..b0ddf2ac 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -44,11 +44,6 @@
assertRunOnServiceThread();
mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
mAddress, mService.getPhysicalAddress(), mDeviceType));
- if (reason == HdmiControlService.INITIATED_BY_SCREEN_ON) {
- oneTouchPlay(new IHdmiControlCallback.Stub() {
- @Override public void onComplete(int result) throws RemoteException {}
- });
- }
}
@Override
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 5deb2b8..ddf02e9 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,9 @@
package com.android.server.search;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.app.AppGlobals;
+import android.app.IActivityManager;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -32,6 +34,7 @@
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -262,6 +265,25 @@
}
@Override
+ public boolean launchAssistAction(int requestType, String hint, int userHandle) {
+ ComponentName comp = getAssistIntent(userHandle);
+ if (comp == null) {
+ return false;
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(Intent.ACTION_ASSIST);
+ intent.setComponent(comp);
+ IActivityManager am = ActivityManagerNative.getDefault();
+ return am.launchAssistIntent(intent, requestType, hint, userHandle);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return true;
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index a8245e7..8a36335 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -116,7 +116,7 @@
public WallpaperObserver(WallpaperData wallpaper) {
super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
- CLOSE_WRITE | DELETE | DELETE_SELF);
+ CLOSE_WRITE | MOVED_TO | DELETE | DELETE_SELF);
mWallpaperDir = getWallpaperDir(wallpaper.userId);
mWallpaper = wallpaper;
mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
@@ -137,9 +137,11 @@
File changedFile = new File(mWallpaperDir, path);
if (mWallpaperFile.equals(changedFile)) {
notifyCallbacksLocked(mWallpaper);
- if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
+ final boolean written = (event == CLOSE_WRITE || event == MOVED_TO);
+ if (mWallpaper.wallpaperComponent == null
+ || event != CLOSE_WRITE // includes the MOVED_TO case
|| mWallpaper.imageWallpaperPending) {
- if (event == CLOSE_WRITE) {
+ if (written) {
mWallpaper.imageWallpaperPending = false;
}
bindWallpaperComponentLocked(mImageWallpaper, true,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8437d52..837672a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7226,11 +7226,14 @@
}
public void updateShowImeWithHardKeyboard() {
- boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(
+ final boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(
mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0,
mCurrentUserId) == 1;
synchronized (mWindowMap) {
- mShowImeWithHardKeyboard = showImeWithHardKeyboard;
+ if (mShowImeWithHardKeyboard != showImeWithHardKeyboard) {
+ mShowImeWithHardKeyboard = showImeWithHardKeyboard;
+ mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+ }
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d1aba3c..f8f20dc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -53,6 +53,7 @@
import android.net.ConnectivityManager;
import android.net.ProxyInfo;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -288,7 +289,7 @@
}
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|| KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
- manageMonitoringCertificateNotification(intent);
+ new MonitoringCertNotificationTask().execute(intent);
}
if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUserData(userHandle);
@@ -1610,60 +1611,91 @@
}
}
- private void manageMonitoringCertificateNotification(Intent intent) {
- final NotificationManager notificationManager = getNotificationManager();
+ private class MonitoringCertNotificationTask extends AsyncTask<Intent, Void, Void> {
+ @Override
+ protected Void doInBackground(Intent... params) {
+ int userHandle = params[0].getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_ALL);
- final boolean hasCert = !(new TrustedCertificateStore().userAliases().isEmpty());
- if (! hasCert) {
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- for (UserInfo user : mUserManager.getUsers()) {
- notificationManager.cancelAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
+ if (userHandle == UserHandle.USER_ALL) {
+ for (UserInfo userInfo : mUserManager.getUsers()) {
+ manageNotification(userInfo.getUserHandle());
}
+ } else {
+ manageNotification(new UserHandle(userHandle));
}
- return;
- }
- final boolean isManaged = getDeviceOwner() != null;
- int smallIconId;
- String contentText;
- if (isManaged) {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
- getDeviceOwnerName());
- smallIconId = R.drawable.stat_sys_certificate_info;
- } else {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
- smallIconId = android.R.drawable.stat_sys_warning;
+ return null;
}
- Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
- dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- dialogIntent.setPackage("com.android.settings");
- // Notification will be sent individually to all users. The activity should start as
- // whichever user is current when it starts.
- PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
- PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
-
- Notification noti = new Notification.Builder(mContext)
- .setSmallIcon(smallIconId)
- .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
- .setContentText(contentText)
- .setContentIntent(notifyIntent)
- .setPriority(Notification.PRIORITY_HIGH)
- .setShowWhen(false)
- .setColor(mContext.getResources().getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .build();
-
- // If this is a boot intent, this will fire for each user. But if this is a storage changed
- // intent, it will fire once, so we need to notify all users.
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- for (UserInfo user : mUserManager.getUsers()) {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
+ private void manageNotification(UserHandle userHandle) {
+ if (!mUserManager.isUserRunning(userHandle)) {
+ return;
}
- } else {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
+
+ boolean hasCert = false;
+ final long id = Binder.clearCallingIdentity();
+ try {
+ KeyChainConnection kcs = KeyChain.bindAsUser(mContext, userHandle);
+ try {
+ if (!kcs.getService().getUserCaAliases().getList().isEmpty()) {
+ hasCert = true;
+ }
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
+ } finally {
+ kcs.close();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ if (!hasCert) {
+ getNotificationManager().cancelAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, userHandle);
+ return;
+ }
+
+ int smallIconId;
+ String contentText;
+ final String ownerName = getDeviceOwnerName();
+ if (ownerName != null) {
+ contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed, ownerName);
+ smallIconId = R.drawable.stat_sys_certificate_info;
+ } else {
+ contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
+ smallIconId = android.R.drawable.stat_sys_warning;
+ }
+
+ Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
+ dialogIntent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ dialogIntent.setPackage("com.android.settings");
+ PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0,
+ dialogIntent, PendingIntent.FLAG_UPDATE_CURRENT, null, userHandle);
+
+ final Context userContext;
+ try {
+ userContext = mContext.createPackageContextAsUser("android", 0, userHandle);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Create context as " + userHandle + " failed", e);
+ return;
+ }
+ final Notification noti = new Notification.Builder(userContext)
+ .setSmallIcon(smallIconId)
+ .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
+ .setContentText(contentText)
+ .setContentIntent(notifyIntent)
+ .setOngoing(true)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setShowWhen(false)
+ .setColor(mContext.getResources().getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .build();
+
+ getNotificationManager().notifyAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, noti, userHandle);
}
}
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index de1dc17..af4ee22 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -365,7 +365,7 @@
}
private boolean hasConnection(String callId) {
- return mConferenceById.containsKey(callId);
+ return mConnectionById.containsKey(callId);
}
private RemoteConnection findConnectionForAction(
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 8e43772..52d0516 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -850,7 +850,8 @@
|| radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
|| radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
|| radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
- || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA;
}
/** @hide */
@@ -861,7 +862,6 @@
|| radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
|| radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
|| radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
- || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD
- || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
}
}
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 7b9cf4e..3363ca6 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -533,10 +533,9 @@
int dBm;
if(isGsm()) {
- if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ dBm = getLteDbm();
+ if (dBm == INVALID) {
dBm = getGsmDbm();
- } else {
- dBm = getLteDbm();
}
} else {
int cdmaDbm = getCdmaDbm();
diff --git a/tests/VoiceEnrollment/AndroidManifest.xml b/tests/VoiceEnrollment/AndroidManifest.xml
index 6321222..46f6ff5 100644
--- a/tests/VoiceEnrollment/AndroidManifest.xml
+++ b/tests/VoiceEnrollment/AndroidManifest.xml
@@ -1,16 +1,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.test.voiceenrollment">
+ <uses-permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES" />
<application
android:permission="android.permission.MANAGE_VOICE_KEYPHRASES">
- <activity android:name="TestEnrollmentActivity" android:label="Voice Enrollment Application"
- android:theme="@android:style/Theme.Material.Light.Voice">
+ <activity
+ android:name="TestEnrollmentActivity"
+ android:label="Voice Enrollment Application"
+ android:theme="@android:style/Theme.Material.Light.Voice">
<intent-filter>
<action android:name="com.android.intent.action.MANAGE_VOICE_KEYPHRASES" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <meta-data android:name="android.voice_enrollment"
+ <meta-data
+ android:name="android.voice_enrollment"
android:resource="@xml/enrollment_application"/>
</application>
</manifest>
diff --git a/tests/VoiceEnrollment/res/layout/main.xml b/tests/VoiceEnrollment/res/layout/main.xml
new file mode 100644
index 0000000..9d2b9d9
--- /dev/null
+++ b/tests/VoiceEnrollment/res/layout/main.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/enroll"
+ android:onClick="onEnrollButtonClicked"
+ android:padding="20dp" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/reenroll"
+ android:onClick="onReEnrollButtonClicked"
+ android:padding="20dp" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/unenroll"
+ android:onClick="onUnEnrollButtonClicked"
+ android:padding="20dp" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/VoiceEnrollment/res/values/strings.xml b/tests/VoiceEnrollment/res/values/strings.xml
new file mode 100644
index 0000000..07bac2a
--- /dev/null
+++ b/tests/VoiceEnrollment/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+
+ 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">
+
+ <string name="enroll">Enroll</string>
+ <string name="reenroll">Re-enroll</string>
+ <string name="unenroll">Un-enroll</string>
+</resources>
\ No newline at end of file
diff --git a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java
new file mode 100644
index 0000000..9e544a5
--- /dev/null
+++ b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2014 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.test.voiceenrollment;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.voice.AlwaysOnHotwordDetector;
+import android.util.Log;
+
+import com.android.internal.app.IVoiceInteractionManagerService;
+
+/**
+ * Utility class for the enrollment operations like enroll;re-enroll & un-enroll.
+ */
+public class EnrollmentUtil {
+ private static final String TAG = "TestEnrollmentUtil";
+
+ /**
+ * Activity Action: Show activity for managing the keyphrases for hotword detection.
+ * This needs to be defined by an activity that supports enrolling users for hotword/keyphrase
+ * detection.
+ */
+ public static final String ACTION_MANAGE_VOICE_KEYPHRASES =
+ KeyphraseEnrollmentInfo.ACTION_MANAGE_VOICE_KEYPHRASES;
+
+ /**
+ * Intent extra: The intent extra for the specific manage action that needs to be performed.
+ * Possible values are {@link AlwaysOnHotwordDetector#MANAGE_ACTION_ENROLL},
+ * {@link AlwaysOnHotwordDetector#MANAGE_ACTION_RE_ENROLL}
+ * or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL}.
+ */
+ public static final String EXTRA_VOICE_KEYPHRASE_ACTION =
+ KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_ACTION;
+
+ /**
+ * Intent extra: The hint text to be shown on the voice keyphrase management UI.
+ */
+ public static final String EXTRA_VOICE_KEYPHRASE_HINT_TEXT =
+ KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_HINT_TEXT;
+ /**
+ * Intent extra: The voice locale to use while managing the keyphrase.
+ */
+ public static final String EXTRA_VOICE_KEYPHRASE_LOCALE =
+ KeyphraseEnrollmentInfo.EXTRA_VOICE_KEYPHRASE_LOCALE;
+
+ /** Simple recognition of the key phrase */
+ public static final int RECOGNITION_MODE_VOICE_TRIGGER =
+ SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER;
+ /** Trigger only if one user is identified */
+ public static final int RECOGNITION_MODE_USER_IDENTIFICATION =
+ SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
+
+ private final IVoiceInteractionManagerService mModelManagementService;
+
+ public EnrollmentUtil() {
+ mModelManagementService = IVoiceInteractionManagerService.Stub.asInterface(
+ ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
+ }
+
+ /**
+ * Adds/Updates a sound model.
+ * The sound model must contain a valid UUID,
+ * exactly 1 keyphrase,
+ * and users for which the keyphrase is valid - typically the current user.
+ *
+ * @param soundModel The sound model to add/update.
+ * @return {@code true} if the call succeeds, {@code false} otherwise.
+ */
+ public boolean addOrUpdateSoundModel(KeyphraseSoundModel soundModel) {
+ if (!verifyKeyphraseSoundModel(soundModel)) {
+ return false;
+ }
+
+ int status = SoundTrigger.STATUS_ERROR;
+ try {
+ status = mModelManagementService.updateKeyphraseSoundModel(soundModel);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateKeyphraseSoundModel", e);
+ }
+ return status == SoundTrigger.STATUS_OK;
+ }
+
+ /**
+ * Gets the sound model for the given keyphrase, null if none exists.
+ * This should be used for re-enrollment purposes.
+ * If a sound model for a given keyphrase exists, and it needs to be updated,
+ * it should be obtained using this method, updated and then passed in to
+ * {@link #addOrUpdateSoundModel(KeyphraseSoundModel)} without changing the IDs.
+ *
+ * @param keyphraseId The keyphrase ID to look-up the sound model for.
+ * @param bcp47Locale The locale for with to look up the sound model for.
+ * @return The sound model if one was found, null otherwise.
+ */
+ @Nullable
+ public KeyphraseSoundModel getSoundModel(int keyphraseId, String bcp47Locale) {
+ if (keyphraseId <= 0) {
+ Log.e(TAG, "Keyphrase must have a valid ID");
+ return null;
+ }
+
+ KeyphraseSoundModel model = null;
+ try {
+ model = mModelManagementService.getKeyphraseSoundModel(keyphraseId, bcp47Locale);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateKeyphraseSoundModel");
+ }
+
+ if (model == null) {
+ Log.w(TAG, "No models present for the gien keyphrase ID");
+ return null;
+ } else {
+ return model;
+ }
+ }
+
+ /**
+ * Deletes the sound model for the given keyphrase id.
+ *
+ * @param keyphraseId The keyphrase ID to look-up the sound model for.
+ * @return {@code true} if the call succeeds, {@code false} otherwise.
+ */
+ @Nullable
+ public boolean deleteSoundModel(int keyphraseId, String bcp47Locale) {
+ if (keyphraseId <= 0) {
+ Log.e(TAG, "Keyphrase must have a valid ID");
+ return false;
+ }
+
+ int status = SoundTrigger.STATUS_ERROR;
+ try {
+ status = mModelManagementService.deleteKeyphraseSoundModel(keyphraseId, bcp47Locale);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateKeyphraseSoundModel");
+ }
+ return status == SoundTrigger.STATUS_OK;
+ }
+
+ private boolean verifyKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
+ if (soundModel == null) {
+ Log.e(TAG, "KeyphraseSoundModel must be non-null");
+ return false;
+ }
+ if (soundModel.uuid == null) {
+ Log.e(TAG, "KeyphraseSoundModel must have a UUID");
+ return false;
+ }
+ if (soundModel.data == null) {
+ Log.e(TAG, "KeyphraseSoundModel must have data");
+ return false;
+ }
+ if (soundModel.keyphrases == null || soundModel.keyphrases.length != 1) {
+ Log.e(TAG, "Keyphrase must be exactly 1");
+ return false;
+ }
+ Keyphrase keyphrase = soundModel.keyphrases[0];
+ if (keyphrase.id <= 0) {
+ Log.e(TAG, "Keyphrase must have a valid ID");
+ return false;
+ }
+ if (keyphrase.recognitionModes < 0) {
+ Log.e(TAG, "Recognition modes must be valid");
+ return false;
+ }
+ if (keyphrase.locale == null) {
+ Log.e(TAG, "Locale must not be null");
+ return false;
+ }
+ if (keyphrase.text == null) {
+ Log.e(TAG, "Text must not be null");
+ return false;
+ }
+ if (keyphrase.users == null || keyphrase.users.length == 0) {
+ Log.e(TAG, "Keyphrase must have valid user(s)");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java
index 7fbd965..2494db7 100644
--- a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java
+++ b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java
@@ -16,8 +16,106 @@
package com.android.test.voiceenrollment;
+import java.util.Random;
+import java.util.UUID;
+
import android.app.Activity;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
public class TestEnrollmentActivity extends Activity {
- // TODO(sansid): Add a test enrollment flow here.
+ private static final String TAG = "TestEnrollmentActivity";
+ private static final boolean DBG = true;
+
+ /** Keyphrase related constants, must match those defined in enrollment_application.xml */
+ private static final int KEYPHRASE_ID = 101;
+ private static final int RECOGNITION_MODES = SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER;
+ private static final String BCP47_LOCALE = "fr-FR";
+ private static final String TEXT = "Hello There";
+
+ private EnrollmentUtil mEnrollmentUtil;
+ private Random mRandom;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ if (DBG) Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ mEnrollmentUtil = new EnrollmentUtil();
+ mRandom = new Random();
+ }
+
+ /**
+ * Called when the user clicks the enroll button.
+ * Performs a fresh enrollment.
+ */
+ public void onEnrollButtonClicked(View v) {
+ Keyphrase kp = new Keyphrase(KEYPHRASE_ID, RECOGNITION_MODES, BCP47_LOCALE, TEXT,
+ new int[] { UserManager.get(this).getUserHandle() /* current user */});
+ UUID modelUuid = UUID.randomUUID();
+ // Generate a fake model to push.
+ byte[] data = new byte[1024];
+ mRandom.nextBytes(data);
+ KeyphraseSoundModel soundModel = new KeyphraseSoundModel(modelUuid, null, data,
+ new Keyphrase[] { kp });
+ boolean status = mEnrollmentUtil.addOrUpdateSoundModel(soundModel);
+ if (status) {
+ Toast.makeText(
+ this, "Successfully enrolled, model UUID=" + modelUuid, Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to enroll!!!" + modelUuid, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * Called when the user clicks the un-enroll button.
+ * Clears the enrollment information for the user.
+ */
+ public void onUnEnrollButtonClicked(View v) {
+ KeyphraseSoundModel soundModel = mEnrollmentUtil.getSoundModel(KEYPHRASE_ID, BCP47_LOCALE);
+ if (soundModel == null) {
+ Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ boolean status = mEnrollmentUtil.deleteSoundModel(KEYPHRASE_ID, BCP47_LOCALE);
+ if (status) {
+ Toast.makeText(this, "Successfully un-enrolled, model UUID=" + soundModel.uuid,
+ Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to un-enroll!!!", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * Called when the user clicks the re-enroll button.
+ * Uses the previously enrolled sound model and makes changes to it before pushing it back.
+ */
+ public void onReEnrollButtonClicked(View v) {
+ KeyphraseSoundModel soundModel = mEnrollmentUtil.getSoundModel(KEYPHRASE_ID, BCP47_LOCALE);
+ if (soundModel == null) {
+ Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ // Generate a fake model to push.
+ byte[] data = new byte[2048];
+ mRandom.nextBytes(data);
+ KeyphraseSoundModel updated = new KeyphraseSoundModel(soundModel.uuid,
+ soundModel.vendorUuid, data, soundModel.keyphrases);
+ boolean status = mEnrollmentUtil.addOrUpdateSoundModel(updated);
+ if (status) {
+ Toast.makeText(this, "Successfully re-enrolled, model UUID=" + updated.uuid,
+ Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show();
+ }
+ }
}
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 9bed899..cb34448 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -40,6 +40,7 @@
kCommandPackage,
kCommandCrunch,
kCommandSingleCrunch,
+ kCommandDaemon
} Command;
/*
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 41d8502..1e9e3e2 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -23,6 +23,10 @@
#include <errno.h>
#include <fcntl.h>
+#include <iostream>
+#include <string>
+#include <sstream>
+
using namespace android;
#ifndef AAPT_VERSION
@@ -2506,6 +2510,37 @@
return NO_ERROR;
}
+int runInDaemonMode(Bundle* bundle) {
+ std::cout << "Ready" << std::endl;
+ for (std::string line; std::getline(std::cin, line);) {
+ if (line == "quit") {
+ return NO_ERROR;
+ }
+ std::stringstream ss;
+ ss << line;
+ std::string s;
+
+ std::string command, parameterOne, parameterTwo;
+ std::getline(ss, command, ' ');
+ std::getline(ss, parameterOne, ' ');
+ std::getline(ss, parameterTwo, ' ');
+ if (command[0] == 's') {
+ bundle->setSingleCrunchInputFile(parameterOne.c_str());
+ bundle->setSingleCrunchOutputFile(parameterTwo.c_str());
+ std::cout << "Crunching " << parameterOne << std::endl;
+ if (doSingleCrunch(bundle) != NO_ERROR) {
+ std::cout << "Error" << std::endl;
+ }
+ std::cout << "Done" << std::endl;
+ } else {
+ // in case of invalid command, just bail out.
+ std::cerr << "Unknown command" << std::endl;
+ return -1;
+ }
+ }
+ return -1;
+}
+
char CONSOLE_DATA[2925] = {
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 736ae26..2857b59 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -234,6 +234,7 @@
case kCommandPackage: return doPackage(bundle);
case kCommandCrunch: return doCrunch(bundle);
case kCommandSingleCrunch: return doSingleCrunch(bundle);
+ case kCommandDaemon: return runInDaemonMode(bundle);
default:
fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
return 1;
@@ -275,6 +276,8 @@
bundle.setCommand(kCommandCrunch);
else if (argv[1][0] == 's')
bundle.setCommand(kCommandSingleCrunch);
+ else if (argv[1][0] == 'm')
+ bundle.setCommand(kCommandDaemon);
else {
fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
wantUsage = true;
diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h
index 089dde5..e84c4c5 100644
--- a/tools/aapt/Main.h
+++ b/tools/aapt/Main.h
@@ -36,6 +36,7 @@
extern int doPackage(Bundle* bundle);
extern int doCrunch(Bundle* bundle);
extern int doSingleCrunch(Bundle* bundle);
+extern int runInDaemonMode(Bundle* bundle);
extern int calcPercent(long uncompressedLen, long compressedLen);