diff options
122 files changed, 2531 insertions, 773 deletions
diff --git a/api/current.txt b/api/current.txt index abb330e96a56..054f1cdd8b71 100644 --- a/api/current.txt +++ b/api/current.txt @@ -267,6 +267,7 @@ package android { field public static final int addPrintersActivity = 16843750; // 0x10103e6 field public static final int addStatesFromChildren = 16842992; // 0x10100f0 field public static final int adjustViewBounds = 16843038; // 0x101011e + field public static final int advancedPrintOptionsActivity = 16843761; // 0x10103f1 field public static final int alertDialogIcon = 16843605; // 0x1010355 field public static final int alertDialogStyle = 16842845; // 0x101005d field public static final int alertDialogTheme = 16843529; // 0x1010309 @@ -19013,6 +19014,16 @@ package android.print { field public static final int STATE_STARTED = 3; // 0x3 } + public static final class PrintJobInfo.Builder { + ctor public PrintJobInfo.Builder(android.print.PrintJobInfo); + method public android.print.PrintJobInfo build(); + method public void putAdvancedOption(java.lang.String, java.lang.String); + method public void putAdvancedOption(java.lang.String, int); + method public void setAttributes(android.print.PrintAttributes); + method public void setCopies(int); + method public void setPages(android.print.PageRange[]); + } + public final class PrintManager { method public java.util.List<android.print.PrintJob> getPrintJobs(); method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes); @@ -19095,10 +19106,13 @@ package android.printservice { method public boolean cancel(); method public boolean complete(); method public boolean fail(java.lang.String); + method public int getAdvancedIntOption(java.lang.String); + method public java.lang.String getAdvancedStringOption(java.lang.String); method public android.printservice.PrintDocument getDocument(); method public android.print.PrintJobId getId(); method public android.print.PrintJobInfo getInfo(); method public java.lang.String getTag(); + method public boolean hasAdvancedOption(java.lang.String); method public boolean isBlocked(); method public boolean isCancelled(); method public boolean isCompleted(); @@ -19120,6 +19134,7 @@ package android.printservice { method protected void onDisconnected(); method protected abstract void onPrintJobQueued(android.printservice.PrintJob); method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob); + field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO"; field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService"; field public static final java.lang.String SERVICE_META_DATA = "android.printservice"; } @@ -25779,6 +25794,7 @@ package android.util { method public boolean equals(android.util.DisplayMetrics); method public void setTo(android.util.DisplayMetrics); method public void setToDefaults(); + field public static final int DENSITY_400 = 400; // 0x190 field public static final int DENSITY_DEFAULT = 160; // 0xa0 field public static final int DENSITY_HIGH = 240; // 0xf0 field public static final int DENSITY_LOW = 120; // 0x78 diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 1067eb1b2add..bb04063905d5 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -68,9 +68,10 @@ public class ActivityManager { private final Handler mHandler; /** - * <meta-data> string for a 'home' Activity that names a package that is to be + * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code + * <meta-data>}</a> name for a 'home' Activity that declares a package that is to be * uninstalled in lieu of the declaring one. The package named here must be - * signed with the same certificate as the one declaring the <meta-data>. + * signed with the same certificate as the one declaring the {@code <meta-data>}. */ public static final String META_HOME_ALTERNATE = "android.app.home.alternate"; diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index e42bdf51269a..072c5bb229d3 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -518,21 +518,31 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { } } - Face[] faces = new Face[numFaces]; + ArrayList<Face> faceList = new ArrayList<Face>(); if (faceDetectMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE) { for (int i = 0; i < numFaces; i++) { - faces[i] = new Face(faceRectangles[i], faceScores[i]); + if (faceScores[i] <= Face.SCORE_MAX && + faceScores[i] >= Face.SCORE_MIN) { + faceList.add(new Face(faceRectangles[i], faceScores[i])); + } } } else { // CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL for (int i = 0; i < numFaces; i++) { - Point leftEye = new Point(faceLandmarks[i*6], faceLandmarks[i*6+1]); - Point rightEye = new Point(faceLandmarks[i*6+2], faceLandmarks[i*6+3]); - Point mouth = new Point(faceLandmarks[i*6+4], faceLandmarks[i*6+5]); - faces[i] = new Face(faceRectangles[i], faceScores[i], faceIds[i], - leftEye, rightEye, mouth); + if (faceScores[i] <= Face.SCORE_MAX && + faceScores[i] >= Face.SCORE_MIN && + faceIds[i] >= 0) { + Point leftEye = new Point(faceLandmarks[i*6], faceLandmarks[i*6+1]); + Point rightEye = new Point(faceLandmarks[i*6+2], faceLandmarks[i*6+3]); + Point mouth = new Point(faceLandmarks[i*6+4], faceLandmarks[i*6+5]); + Face face = new Face(faceRectangles[i], faceScores[i], faceIds[i], + leftEye, rightEye, mouth); + faceList.add(face); + } } } + Face[] faces = new Face[faceList.size()]; + faceList.toArray(faces); return faces; } diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java index 908aadd5a314..01e5bac01d85 100644 --- a/core/java/android/hardware/display/VirtualDisplay.java +++ b/core/java/android/hardware/display/VirtualDisplay.java @@ -19,7 +19,13 @@ import android.os.IBinder; import android.view.Display; /** - * Represents a virtual display. + * Represents a virtual display. The content of a virtual display is rendered to a + * {@link android.view.Surface} that you must provide to {@link DisplayManager#createVirtualDisplay + * createVirtualDisplay()}. + * <p>Because a virtual display renders to a surface provided by the application, it will be + * released automatically when the process terminates and all remaining windows on it will + * be forcibly removed. However, you should also explicitly call {@link #release} when you're + * done with it. * * @see DisplayManager#createVirtualDisplay */ diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 486e75a5ca30..6743c6cf67f8 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -49,6 +49,8 @@ import android.util.Log; * <h3>Developer Guides</h3> * <p>For more information about using NFC, read the * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p> + * <p>To perform basic file sharing between devices, read + * <a href="{@docRoot}training/beam-files/index.html">Sharing Files with NFC</a>. * </div> */ public final class NfcAdapter { @@ -309,8 +311,12 @@ public final class NfcAdapter { final Context mContext; /** - * A callback to be invoked when the system has found a tag in - * reader mode. + * A callback to be invoked when the system finds a tag while the foreground activity is + * operating in reader mode. + * <p>Register your {@code ReaderCallback} implementation with {@link + * NfcAdapter#enableReaderMode} and disable it with {@link + * NfcAdapter#disableReaderMode}. + * @see NfcAdapter#enableReaderMode */ public interface ReaderCallback { public void onTagDiscovered(Tag tag); diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java index 9f935c8311b1..c6f0a6848f91 100644 --- a/core/java/android/print/PrintJobInfo.java +++ b/core/java/android/print/PrintJobInfo.java @@ -439,7 +439,7 @@ public final class PrintJobInfo implements Parcelable { /** * Sets the included pages. * - * @return The included pages. + * @param pageRanges The included pages. * * @hide */ @@ -601,6 +601,81 @@ public final class PrintJobInfo implements Parcelable { } } + /** + * Builder for creating a {@link PrintJobInfo}. + */ + public static final class Builder { + private final PrintJobInfo mPrototype; + + /** + * Constructor. + * + * @param prototype Prototype to use as a starting point. + * Can be null. + */ + public Builder(PrintJobInfo prototype) { + mPrototype = (prototype != null) + ? new PrintJobInfo(prototype) + : new PrintJobInfo(); + } + + /** + * Sets the number of copies. + * + * @param copies The number of copies. + */ + public void setCopies(int copies) { + mPrototype.mCopies = copies; + } + + /** + * Sets the print job attributes. + * + * @param attributes The attributes. + */ + public void setAttributes(PrintAttributes attributes) { + mPrototype.mAttributes = attributes; + } + + /** + * Sets the included pages. + * + * @param pages The included pages. + */ + public void setPages(PageRange[] pages) { + mPrototype.mPageRanges = pages; + } + + /** + * Puts an advanced (printer specific) option. + * + * @param key The option key. + * @param value The option value. + */ + public void putAdvancedOption(String key, String value) { + + } + + /** + * Puts an advanced (printer specific) option. + * + * @param key The option key. + * @param value The option value. + */ + public void putAdvancedOption(String key, int value) { + + } + + /** + * Creates a new {@link PrintJobInfo} instance. + * + * @return The new instance. + */ + public PrintJobInfo build() { + return mPrototype; + } + } + public static final Parcelable.Creator<PrintJobInfo> CREATOR = new Creator<PrintJobInfo>() { @Override diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java index d1dbedf9ef63..fdeb3730b90e 100644 --- a/core/java/android/printservice/PrintJob.java +++ b/core/java/android/printservice/PrintJob.java @@ -304,7 +304,7 @@ public final class PrintJob { /** * Gets the print job tag. * - * @return tag The tag or null. + * @return The tag or null. * * @see #setTag(String) */ @@ -313,6 +313,40 @@ public final class PrintJob { return getInfo().getTag(); } + /** + * Gets the value of an advanced (printer specific) print option. + * + * @param key The option key. + * @return The option value. + */ + public String getAdvancedStringOption(String key) { + PrintService.throwIfNotCalledOnMainThread(); + return null; + } + + /** + * Gets whether this job has a given advanced (printer specific) print + * option. + * + * @param key The option key. + * @return Whether the option is present. + */ + public boolean hasAdvancedOption(String key) { + PrintService.throwIfNotCalledOnMainThread(); + return false; + } + + /** + * Gets the value of an advanced (printer specific) print option. + * + * @param key The option key. + * @return The option value. + */ + public int getAdvancedIntOption(String key) { + PrintService.throwIfNotCalledOnMainThread(); + return 0; + } + @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index e73a53bee819..0fc5f7f035a6 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -16,6 +16,7 @@ package android.printservice; +import android.R; import android.app.Service; import android.content.ComponentName; import android.content.Context; @@ -189,6 +190,28 @@ public abstract class PrintService extends Service { */ public static final String SERVICE_META_DATA = "android.printservice"; + /** + * If you declared an optional activity with advanced print options via the + * {@link R.attr#advancedPrintOptionsActivity advancedPrintOptionsActivity} + * attribute, this extra is used to pass in the currently constructed {@link + * PrintJobInfo} to your activity allowing you to modify it. After you are + * done, you must return the modified {@link PrintJobInfo} via the same extra. + * <p> + * You cannot modify the passed in {@link PrintJobInfo} directly, rather you + * should build another one using the {@link PrintJobInfo.Builder} class. You + * can specify any standard properties and add advanced, printer specific, + * ones via {@link PrintJobInfo.Builder#putAdvancedOption(String, String) + * PrintJobInfo.Builder#putAdvancedOption(String, String)} and {@link + * PrintJobInfo.Builder#putAdvancedOption(String, int) + * PrintJobInfo.Builder#putAdvancedOption(String, int)}. The advanced options + * are not interpreted by the system, they will not be visible to applications, + * and can only be accessed by your print service via {@link + * PrintJob#getAdvancedStringOption(String) PrintJob.getAdvancedStringOption(String)} + * and {@link PrintJob#getAdvancedIntOption(String) PrintJob.getAdvancedIntOption(String)}. + * </p> + */ + public static final String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO"; + private Handler mHandler; private IPrintServiceClient mClient; diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index dae47b88c4e2..6cda90536c58 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -67,6 +67,14 @@ public class DisplayMetrics { public static final int DENSITY_XHIGH = 320; /** + * Intermediate density for screens that sit somewhere between + * {@link #DENSITY_XHIGH} (320dpi) and {@link #DENSITY_XXHIGH} (480 dpi). + * This is not a density that applications should target, instead relying + * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. + */ + public static final int DENSITY_400 = 400; + + /** * Standard quantized DPI for extra-extra-high-density screens. Applications * should not generally worry about this density; relying on XHIGH graphics * being scaled up to it should be sufficient for almost all cases. diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 4614c53eb9b2..01ac8fdba6d0 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -29,6 +29,7 @@ import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; +import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.util.IntProperty; import android.util.MathUtils; @@ -176,6 +177,9 @@ class FastScroller { */ private int mState; + /** Whether the preview image is visible. */ + private boolean mShowingPreview; + private BaseAdapter mListAdapter; private SectionIndexer mSectionIndexer; @@ -769,6 +773,8 @@ class FastScroller { mDecorAnimation = new AnimatorSet(); mDecorAnimation.playTogether(fadeOut, slideOut); mDecorAnimation.start(); + + mShowingPreview = false; } /** @@ -790,6 +796,8 @@ class FastScroller { mDecorAnimation = new AnimatorSet(); mDecorAnimation.playTogether(fadeIn, fadeOut, slideIn); mDecorAnimation.start(); + + mShowingPreview = false; } /** @@ -809,6 +817,8 @@ class FastScroller { mDecorAnimation = new AnimatorSet(); mDecorAnimation.playTogether(fadeIn, slideIn); mDecorAnimation.start(); + + mShowingPreview = true; } private void postAutoHide() { @@ -982,9 +992,10 @@ class FastScroller { if (mCurrentSection != sectionIndex) { mCurrentSection = sectionIndex; - if (transitionPreviewLayout(sectionIndex)) { + final boolean hasPreview = transitionPreviewLayout(sectionIndex); + if (!mShowingPreview && hasPreview) { transitionToDragging(); - } else { + } else if (mShowingPreview && !hasPreview) { transitionToVisible(); } } @@ -1072,7 +1083,7 @@ class FastScroller { mPreviewAnimation.start(); - return (text != null && text.length() > 0); + return !TextUtils.isEmpty(text); } /** @@ -1184,7 +1195,19 @@ class FastScroller { / positionsInSection; } - return (section + posWithinSection) / sectionCount; + float result = (section + posWithinSection) / sectionCount; + + // Fake out the scroll bar for the last item. Since the section indexer + // won't ever actually move the list in this end space, make scrolling + // across the last item account for whatever space is remaining. + if (firstVisibleItem > 0 && firstVisibleItem + visibleItemCount == totalItemCount) { + final View lastChild = mList.getChildAt(visibleItemCount - 1); + final float lastItemVisible = (float) (mList.getHeight() - mList.getPaddingBottom() + - lastChild.getTop()) / lastChild.getHeight(); + result += (1 - result) * lastItemVisible; + } + + return result; } /** diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java index 061bb00cfd53..b152297275a8 100644 --- a/core/java/android/widget/ViewFlipper.java +++ b/core/java/android/widget/ViewFlipper.java @@ -90,7 +90,7 @@ public class ViewFlipper extends ViewAnimator { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); - getContext().registerReceiver(mReceiver, filter); + getContext().registerReceiver(mReceiver, filter, null, mHandler); if (mAutoStart) { // Automatically start when requested diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index 45a38be8aee4..63ff5a074108 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -43,4 +43,5 @@ interface IKeyguardService { oneway void showAssistant(); oneway void dispatch(in MotionEvent event); oneway void launchCamera(); + oneway void onBootCompleted(); } diff --git a/core/res/res/layout/input_method.xml b/core/res/res/layout/input_method.xml index 00a3990ba430..e50da00542dd 100644 --- a/core/res/res/layout/input_method.xml +++ b/core/res/res/layout/input_method.xml @@ -23,6 +23,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:gravity="start|bottom" > <LinearLayout diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index eb731a3c12e2..a7b512d3fb47 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Intentar en <xliff:g id="COUNT">%d</xliff:g> s"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Vuelve a intentar más tarde."</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Salir de pantalla completa: deslizar abajo"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Desliza el dedo hacia abajo para salir de la pantalla completa."</string> </resources> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index 742d3da44961..066694dddfef 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Proovige uuesti <xliff:g id="COUNT">%d</xliff:g> sekundi pärast"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Proovige hiljem uuesti"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Täisekraani sulgemiseks pühkige ülevalt alla"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Täisekraanilt väljumiseks pühkige ülevalt alla."</string> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 92d687fd2bd9..61112f238f4d 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"امتحان پس از <xliff:g id="COUNT">%d</xliff:g> ثانیه"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"بعداً دوباره امتحان کنید"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"برای خروج از تمام صفحه از بالا به پایین بکشید"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"برای خروج از حالت تمام صفحه، انگشت خود را به تندی از بالای صفحه به پایین بکشید."</string> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 385ed4bb03d7..ad27a23b2b7c 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Réessayer dans <xliff:g id="COUNT">%d</xliff:g> s"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Réessayez plus tard"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Balayez vers le bas pour quitter plein écran"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Balayez vers le bas pour quitter le mode plein écran"</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 9a44a3159437..0953fe3cd5a5 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Réessayer dans <xliff:g id="COUNT">%d</xliff:g> s"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Veuillez réessayer ultérieurement."</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Balayer vers le bas pour quitter le plein écran"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Faites glisser le doigt vers le bas pour quitter le mode plein écran."</string> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 73575bd6da5d..9426c2d91621 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -205,8 +205,8 @@ <string name="permgroupdesc_camera" msgid="2933667372289567714">"चित्र या वीडियो कैप्चर के लिए कैमरे पर सीधी पहुंच."</string> <string name="permgrouplab_screenlock" msgid="8275500173330718168">"स्क्रीन लॉक करें"</string> <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"आपके उपकरण की लॉक स्क्रीन का व्यवहार प्रभावित करने की क्षमता."</string> - <string name="permgrouplab_appInfo" msgid="8028789762634147725">"आपके एप्स की जानकारी"</string> - <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"अपने उपकरण पर अन्य एप्स के व्यवहार को प्रभावित करने की क्षमता."</string> + <string name="permgrouplab_appInfo" msgid="8028789762634147725">"आपके ऐप्स की जानकारी"</string> + <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"अपने उपकरण पर अन्य ऐप्स के व्यवहार को प्रभावित करने की क्षमता."</string> <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"वॉलपेपर"</string> <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"उपकरण की वॉलपेपर सेटिंग बदलें."</string> <string name="permgrouplab_systemClock" msgid="406535759236612992">"घड़ी"</string> @@ -225,8 +225,8 @@ <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"सिस्टम का निम्न-स्तर पहुंच और नियंत्रण."</string> <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"डेवलपमेंट टूल"</string> <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"सुविधाएं जो केवल एप्स डेवलपर के लिए आवश्यक हैं."</string> - <string name="permgrouplab_display" msgid="4279909676036402636">"अन्य एप्स UI"</string> - <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्य एप्स के UI को प्रभावित करें."</string> + <string name="permgrouplab_display" msgid="4279909676036402636">"अन्य ऐप्स UI"</string> + <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्य ऐप्स के UI को प्रभावित करें."</string> <string name="permgrouplab_storage" msgid="1971118770546336966">"संग्रहण"</string> <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB संग्रहण में पहुंचें."</string> <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्ड में पहुंचें."</string> @@ -243,7 +243,7 @@ <string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति बार अक्षम या बदलें"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"एप्स को स्थिति बार अक्षम करने या सिस्टम आइकन को जोड़ने या निकालने देता है."</string> <string name="permlab_statusBarService" msgid="7247281911387931485">"स्थिति बार"</string> - <string name="permdesc_statusBarService" msgid="716113660795976060">"एप्स को स्थिति बार होने देता है."</string> + <string name="permdesc_statusBarService" msgid="716113660795976060">"ऐप्स को स्थिति बार होने देता है."</string> <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्थिति बार विस्तृत/संक्षिप्त करें"</string> <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"एप्स को स्थिति बार को विस्तृत या संक्षिप्त करने देता है."</string> <string name="permlab_install_shortcut" msgid="4279070216371564234">"शॉर्टकट इंस्टॉल करें"</string> @@ -251,7 +251,7 @@ <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट अनइंस्टॉल करें"</string> <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"एप्लिकेशन को उपयोगकर्ता के हस्तक्षेप के बिना होमस्क्रीन शॉर्टकट निकालने की अनुमति देता है."</string> <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"आउटगोइंग कॉल को कहीं और भेजें"</string> - <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"एप्स को आउटगोइंग कॉल संसाधित करने और डायल किए जाने वाला नंबर बदलने देता है. यह अनुमति एप्स को आउटगोइंग कॉल की निगरानी करने, रीडायरेक्ट करने, या उन्हें रोकने देती है."</string> + <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ऐप्स को आउटगोइंग कॉल संसाधित करने और डायल किए जाने वाला नंबर बदलने देता है. यह अनुमति ऐप्स को आउटगोइंग कॉल की निगरानी करने, रीडायरेक्ट करने, या उन्हें रोकने देती है."</string> <string name="permlab_receiveSms" msgid="8673471768947895082">"पाठ संदेश (SMS) प्राप्त करें"</string> <string name="permdesc_receiveSms" msgid="6424387754228766939">"एप्स को SMS संदेशों को प्राप्त और संसाधित करने देता है. इसका अर्थ है कि एप्स आपके उपकरण पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्हें हटा सकता है."</string> <string name="permlab_receiveMms" msgid="1821317344668257098">"पाठ संदेश (MMS) प्राप्त करें"</string> @@ -259,7 +259,7 @@ <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"आपातकालीन प्रसारण प्राप्त करें"</string> <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"एप्स को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने देता है. यह अनुमति केवल सिस्टम एप्स में उपलब्ध है."</string> <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण संदेश पढ़ें"</string> - <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"एप्स को आपके उपकरण द्वारा प्राप्त सेल प्रसारण संदेशों को पढ़ने देता है. कुछ स्थानों पर आपको आपातकालीन स्थितियों की चेतावनी देने के लिए सेल प्रसारण अलर्ट वितरित किए जाते हैं. आपातकालीन सेल प्रसारण प्राप्त होने पर दुर्भावनापूर्ण एप्स आपके उपकरण के निष्पादन या संचालन में हस्तक्षेप कर सकते हैं."</string> + <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप्स को आपके उपकरण द्वारा प्राप्त सेल प्रसारण संदेशों को पढ़ने देता है. कुछ स्थानों पर आपको आपातकालीन स्थितियों की चेतावनी देने के लिए सेल प्रसारण अलर्ट वितरित किए जाते हैं. आपातकालीन सेल प्रसारण प्राप्त होने पर दुर्भावनापूर्ण ऐप्स आपके उपकरण के निष्पादन या संचालन में हस्तक्षेप कर सकते हैं."</string> <string name="permlab_sendSms" msgid="5600830612147671529">"SMS संदेश भेजें"</string> <string name="permdesc_sendSms" msgid="7094729298204937667">"एप्स को SMS संदेशों को भेजने देता है. इसके परिणामस्वरूप अप्रत्याशित शुल्क लागू हो सकते हैं. दुर्भावनापूर्ण एप्स आपकी पुष्टि के बिना संदेश भेजकर आपका धन व्यय कर सकते हैं."</string> <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"संदेश-द्वारा-जवाब भेजें ईवेंट"</string> @@ -272,7 +272,7 @@ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"एप्स को आपके फ़ोन या सिम कार्ड में संग्रहीत SMS संदेशों को लिखने देता है. दुर्भावनापूर्ण एप्स आपके संदेशों को हटा सकते हैं."</string> <string name="permlab_receiveWapPush" msgid="5991398711936590410">"पाठ संदेश (WAP) प्राप्त करें"</string> <string name="permdesc_receiveWapPush" msgid="748232190220583385">"एप्स को WAP संदेशों को प्राप्त और संसाधित करने देता है. इस अनुमति में आपको भेजे गए संदेशों की निगरानी आपको दिखाए बिना करने और हटाने की क्षमता शामिल है."</string> - <string name="permlab_getTasks" msgid="6466095396623933906">"चल रहे एप्स पुनर्प्राप्त करें"</string> + <string name="permlab_getTasks" msgid="6466095396623933906">"चल रहे ऐप्स पुनर्प्राप्त करें"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"एप्स को वर्तमान में और हाल ही में चल रहे कार्यों के बारे में जानकारी को पुन: प्राप्त करने देता है. इससे एप्स उपकरण पर उपयोग किए गए एप्स के बारे में जानकारी खोज सकता है."</string> <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"उपयोगकर्ताओं के बीच सहभागिता करें"</string> <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"एप्स को उपकरण पर भिन्न उपयोगकर्ताओं के बीच कार्य निष्पादित करने देता है. दुर्भावनापूर्ण एप्स उपयोगकर्ताओं के बीच सुरक्षा का उल्लंघन करने के लिए इसका उपयोग कर सकते हैं."</string> @@ -280,49 +280,49 @@ <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"उपयोगकर्ताओं के बीच सभी संभव सहभागिता करने देता है."</string> <string name="permlab_manageUsers" msgid="1676150911672282428">"उपयोगकर्ता प्रबंधित करें"</string> <string name="permdesc_manageUsers" msgid="8409306667645355638">"एप्स को उपकरण पर क्वेरी, निर्माण और हटाने सहित उपयोगकर्ताओं को प्रबंधित करने की सुविधा देता है."</string> - <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे एप्स के विवरण प्राप्त करें"</string> + <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे ऐप्स के विवरण प्राप्त करें"</string> <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"एप्स को वर्तमान में और हाल ही में चल रहे कार्यों की जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्स अन्य एप्स के बारे में निजी जानकारी खोज सकते हैं."</string> - <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे एप्स पुन: क्रमित करें"</string> + <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे ऐप्स पुन: क्रमित करें"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"एप्स को कार्यों को अग्रभूमि और पृष्ठभूमि पर ले जाने देता है. एप्स आपके इनपुट के बिना यह कर सकता है."</string> <string name="permlab_removeTasks" msgid="6821513401870377403">"चलने वाले एप्स रोकें"</string> - <string name="permdesc_removeTasks" msgid="1394714352062635493">"किसी एप्स को कार्यों को निकालने और उनके एप्स समाप्त करने देता है. दुर्भावनापूर्ण एप्स अन्य एप्स का व्यवहार बाधित कर सकते हैं."</string> + <string name="permdesc_removeTasks" msgid="1394714352062635493">"किसी ऐप्स को कार्यों को निकालने और उनके ऐप्स समाप्त करने देता है. दुर्भावनापूर्ण ऐप्स अन्य ऐप्स का व्यवहार बाधित कर सकते हैं."</string> <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"गतिविधि स्टैक प्रबंधित करें"</string> <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"एप्स को ऐसे गतिविधि स्टैक जोड़ने, निकालने, और बदलने देता है जिनमें अन्य एप्स चलते हों. दुर्भावनापूर्ण एप्स अन्य एप्स के व्यवहार में बाधा डाल सकते हैं."</string> <string name="permlab_startAnyActivity" msgid="2918768238045206456">"कोई गतिविधि प्रारंभ करें"</string> - <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा या निर्यात की स्थिति पर ध्यान दिए बिना, एप्स को कोई गतिविधि प्रारंभ करने देता है."</string> + <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा या निर्यात की स्थिति पर ध्यान दिए बिना, ऐप्स को कोई गतिविधि प्रारंभ करने देता है."</string> <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"स्क्रीन संगतता सेट करें"</string> - <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"एप्स को अन्य एप्स के स्क्रीन संगतता मोड को नियंत्रित करने देता है. दुर्भावनापूर्ण एप्स अन्य एप्स का व्यवहार बाधित कर सकते हैं."</string> - <string name="permlab_setDebugApp" msgid="3022107198686584052">"एप्स डीबग करना सक्षम करें"</string> + <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"ऐप्स को अन्य ऐप्स के स्क्रीन संगतता मोड को नियंत्रित करने देता है. दुर्भावनापूर्ण ऐप्स अन्य ऐप्स का व्यवहार बाधित कर सकते हैं."</string> + <string name="permlab_setDebugApp" msgid="3022107198686584052">"ऐप्स डीबग करना सक्षम करें"</string> <string name="permdesc_setDebugApp" msgid="4474512416299013256">"एप्स को अन्य एप्स के लिए डीबग किया जाना चालू करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग अन्य एप्स को समाप्त करने के लिए कर सकते हैं."</string> <string name="permlab_changeConfiguration" msgid="4162092185124234480">"सिस्टम प्रदर्शन सेटिंग बदलें"</string> <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"एप्स को वर्तमान कॉन्फ़िगरेशन, जैसे स्थान या समग्र अक्षरों का आकार, बदलने देता है."</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करें"</string> <string name="permdesc_enableCarMode" msgid="4853187425751419467">"एप्स को कार मोड सक्षम करने देता है."</string> - <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य एप्स बंद करें"</string> - <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"एप्स को अन्य एप्स की पृष्ठभूमि प्रक्रियाओं को समाप्त करने देता है. यह अन्य एप्स का चलना रोक सकता है."</string> - <string name="permlab_forceStopPackages" msgid="2329627428832067700">"अन्य एप्स बलपूर्वक बंद करें"</string> + <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य ऐप्स बंद करें"</string> + <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"एप्स को अन्य ऐप्स की पृष्ठभूमि प्रक्रियाओं को समाप्त करने देता है. यह अन्य एप्स का चलना रोक सकता है."</string> + <string name="permlab_forceStopPackages" msgid="2329627428832067700">"अन्य ऐप्स बलपूर्वक बंद करें"</string> <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"एप्स को अन्य एप्स बलपूर्वक बंद करने देता है."</string> - <string name="permlab_forceBack" msgid="652935204072584616">"एप्स को बलपूर्वक बंद करें"</string> - <string name="permdesc_forceBack" msgid="3892295830419513623">"एप्स को अग्रभूमि में चल रही कोई भी गतिविधि बलपूर्वक बंद करने और वापस जाने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permlab_forceBack" msgid="652935204072584616">"ऐप्स को बलपूर्वक बंद करें"</string> + <string name="permdesc_forceBack" msgid="3892295830419513623">"एप्स को अग्रभूमि में चल रही कोई भी गतिविधि बलपूर्वक बंद करने और वापस जाने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_dump" msgid="1681799862438954752">"सिस्टम की आंतरिक स्थिति पुनर्प्राप्त करें"</string> - <string name="permdesc_dump" msgid="1778299088692290329">"एप्स को सिस्टम की आंतरिक स्थिति पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्स विभिन्न प्रकार की निजी और सुरक्षा जानकारी प्राप्त कर सकते हैं जिनकी उन्हें सामान्यत: आवश्यकता नहीं होती."</string> + <string name="permdesc_dump" msgid="1778299088692290329">"ऐप्स को सिस्टम की आंतरिक स्थिति पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण ऐप्स विभिन्न प्रकार की निजी और सुरक्षा जानकारी प्राप्त कर सकते हैं जिनकी उन्हें सामान्यत: आवश्यकता नहीं होती."</string> <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"स्क्रीन सामग्री पुनर्प्राप्त करें"</string> - <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"एप्स को सक्रिय विंडो की सामग्री पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्स विंडो की संपूर्ण सामग्री प्राप्त कर सकते हैं और पासवर्ड को छोड़कर इसके सभी पाठ जांच सकते हैं."</string> + <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ऐप्स को सक्रिय विंडो की सामग्री पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण ऐप्स विंडो की संपूर्ण सामग्री प्राप्त कर सकते हैं और पासवर्ड को छोड़कर इसके सभी पाठ जांच सकते हैं."</string> <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"आसान तरीका को अस्थायी रूप से सक्षम करें"</string> <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"एप्स को उपकरण पर आसान तरीका को अस्थायी रूप से सक्षम करने देता है. दुर्भावनापूर्ण एप्स उपयोगकर्ता की सहमति के बिना आसान तरीका को सक्षम कर सकते हैं."</string> <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"विंडो जानकारी प्राप्त करें"</string> - <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"एप्स को विंडो प्रबंधक से windows के बारे में जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्स आंतरिक सिस्टम उपयोग के लिए अभिप्रेत जानकारी को प्राप्त कर सकते हैं."</string> + <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ऐप्स को विंडो प्रबंधक से windows के बारे में जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण ऐप्स आंतरिक सिस्टम उपयोग के लिए अभिप्रेत जानकारी को प्राप्त कर सकते हैं."</string> <string name="permlab_filter_events" msgid="8675535648807427389">"ईवेंट फ़िल्टर करें"</string> - <string name="permdesc_filter_events" msgid="8006236315888347680">"एप्स को इनपुट फ़िल्टर पंजीकृत करने देता है, जो सभी उपयोगकर्ता ईवेंट के स्ट्रीम को भेजे जाने से पहले फ़िल्टर करता है. दुर्भावनापूर्ण एप्स उपयोगकर्ता के हस्तक्षेप के बिना सिस्टम UI को नियंत्रित कर सकता है."</string> + <string name="permdesc_filter_events" msgid="8006236315888347680">"ऐप्स को इनपुट फ़िल्टर पंजीकृत करने देता है, जो सभी उपयोगकर्ता ईवेंट के स्ट्रीम को भेजे जाने से पहले फ़िल्टर करता है. दुर्भावनापूर्ण ऐप्स उपयोगकर्ता के हस्तक्षेप के बिना सिस्टम UI को नियंत्रित कर सकता है."</string> <string name="permlab_magnify_display" msgid="5973626738170618775">"डिस्प्ले को आवर्धित करें"</string> <string name="permdesc_magnify_display" msgid="7121235684515003792">"एप्स को डिस्प्ले की सामग्री आवर्धित करने देता है. दुर्भावनापूर्ण एप्स डिस्प्ले सामग्री को इस तरह से बदल सकते हैं कि उपकरण अनुपयोगी रेंडर होता है."</string> <string name="permlab_shutdown" msgid="7185747824038909016">"आंशिक शटडाउन"</string> <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि प्रबंधक को शटडाउन स्थिति में रखता है. पूर्ण शटडाउन निष्पादित नहीं करता है."</string> - <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"एप्स स्विच करने से रोकता है"</string> - <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"उपयोगकर्ता को दूसरे एप्स पर स्विच करने से रोकता है."</string> + <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ऐप्स स्विच करने से रोकता है"</string> + <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"उपयोगकर्ता को दूसरे ऐप्स पर स्विच करने से रोकता है."</string> <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान एप्स की जानकारी प्राप्त करें"</string> <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"धारक को स्क्रीन के अग्रभाग में स्थित वर्तमान एप्स के बारे में निजी जानकारी प्राप्त करने देती है."</string> - <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सभी एप्स की लॉन्चिंग की निगरानी करें और उसे नियंत्रित करें"</string> + <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सभी ऐप्स की लॉन्चिंग की निगरानी करें और उसे नियंत्रित करें"</string> <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"एप्स को यह निगरानी और नियंत्रित करने देता है कि सिस्टम कैसे गतिविधियां लॉन्च करता है. दुर्भावनापूर्ण एप्स सिस्टम को पूरी तरह से जोखिम में डाल सकते हैं. इस अनुमति की आवश्यकता केवल विकास के लिए है, सामान्य उपयोग के लिए कभी नहीं."</string> <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"पैकेज निकाले गए प्रसारण भेजें"</string> <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"एप्स को कोई ऐसी सूचना प्रसारित करने देता है जिसे किसी एप्स पैकेज ने निकाल दिया गया हो. दुर्भावनापूर्ण एप्स इसका उपयोग चल रहे अन्य एप्स को समाप्त करने के लिए कर सकते हैं."</string> @@ -332,111 +332,111 @@ <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"एप्स को वह सूचना प्रसारित करने देता है जो WAP PUSH संदेश को प्राप्त हुआ है. दुर्भावनापूर्ण एप्स इसका उपयोग नकली MMS संदेश प्राप्त करने या किसी वेबपृष्ठ की सामग्री को दुर्भावनापूर्ण दूसरे रूप से चुपचाप प्रतिस्थापित करने के लिए कर सकते हैं."</string> <string name="permlab_setProcessLimit" msgid="2451873664363662666">"चल रही प्रक्रियाओं की संख्या सीमित करें"</string> <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"एप्स को चलाई जाने वाली अधिकतम प्रक्रियाओं को नियंत्रित करने देता है. सामान्य एप्स के लिए कभी आवश्यक नहीं होती."</string> - <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि एप्स को बलपूर्वक बंद करें"</string> + <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि ऐप्स को बलपूर्वक बंद करें"</string> <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"एप्स को यह नियंत्रित करने देता है कि पृष्ठभूमि में जाते ही गतिविधियां पूर्ण हो जाती है या नही. सामान्य एप्स के लिए कभी आवश्यकता नहीं होती."</string> <string name="permlab_batteryStats" msgid="2789610673514103364">"बैटरी के आंकड़े पढ़ें"</string> <string name="permdesc_batteryStats" msgid="5897346582882915114">"एप्स को वर्तमान निम्न-स्तरीय बैटरी उपयोग डेटा पढ़ने देती है. एप्स को आपके द्वारा उपयोग किए जाने वाले एप्स के बारे में विस्तृत जानकारी ढूंढने दे सकती है."</string> <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"बैटरी के आंकड़े संशोधित करें"</string> - <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"एप्स को बैटरी के संकलित आंकड़ों को संशोधित करने देती है. सामान्य एप्स के द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"ऐप्स को बैटरी के संकलित आंकड़ों को संशोधित करने देती है. सामान्य ऐप्स के द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"एप्स संचालन आंकड़े प्राप्त करें"</string> <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"एप्स को संकलित एप्स संचालन आंकड़े प्राप्त करने देता है. सामान्य एप्स के द्वारा उपयोग के लिए नहीं."</string> <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"एप्स कार्यवाही के आंकड़े बदलें"</string> <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"एप्स को एप्स कार्यवाही के एकत्रित आंकड़े बदलने देता है. सामान्य एप्स के द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_backup" msgid="470013022865453920">"सिस्टम सुरक्षा नियंत्रित और पुनर्स्थापित करें"</string> - <string name="permdesc_backup" msgid="6912230525140589891">"एप्स को सिस्टम के बैकअप को नियंत्रित और क्रियाविधि को पुर्नस्थापित करने देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_backup" msgid="6912230525140589891">"एप्स को सिस्टम के बैकअप को नियंत्रित और क्रियाविधि को पुर्नस्थापित करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण सुरक्षा या पुनर्स्थापना कार्यवाही की पुष्टि करें"</string> - <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"एप्स को पूर्ण बैकअप पुष्टिकरण UI लॉन्च करने देता है. किसी एप्स द्वारा उपयोग के लिए नहीं."</string> + <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"ऐप्स को पूर्ण बैकअप पुष्टिकरण UI लॉन्च करने देता है. किसी ऐप्स द्वारा उपयोग के लिए नहीं."</string> <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"अनधिकृत विंडो दिखाएं"</string> - <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"किसी एप्स को ऐसी विंडो बनाने देता है जिनका उपयोग आंतरिक सिस्टम उपयोगकर्ता इंटरफ़ेस द्वारा किया जाना है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> - <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"अन्य एप्स पर खींचें"</string> + <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_manageAppTokens" msgid="1286505717050121370">"एप्स टोकन प्रबंधित करें"</string> - <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"एप्स को उनके सामान्य Z-क्रमों पर न पहुंचते हुए उनके स्वयं के टोकन बनाने और प्रबंधित करने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</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> <string name="permdesc_freezeScreen" msgid="8558923789222670064">"पूर्ण-स्क्रीन संक्रमण के लिए एप्स को अस्थायी रूप से स्क्रीन को स्थिर करने देता है."</string> <string name="permlab_injectEvents" msgid="1378746584023586600">"कुंजियों और नियंत्रण बटन को दबाएं"</string> - <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"एप्स को स्वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) को अन्य एप्स को वितरित करने देता है. दुर्भावनापूर्ण एप्स टेबलेट को टेक ओवर करने में इसका उपयोग कर सकते हैं."</string> - <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"एप्स को स्वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) अन्य एप्स को वितरित करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग फ़ोन को टेक ओवर करने में कर सकते हैं."</string> + <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"ऐप्स को स्वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) को अन्य ऐप्स को वितरित करने देता है. दुर्भावनापूर्ण ऐप्स टेबलेट को टेक ओवर करने में इसका उपयोग कर सकते हैं."</string> + <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"ऐप्स को स्वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) अन्य ऐप्स को वितरित करने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग फ़ोन को टेक ओवर करने में कर सकते हैं."</string> <string name="permlab_readInputState" msgid="469428900041249234">"आप जो भी लिखते हैं और जो कार्यवाहियां करते हैं उन्हें रिकॉर्ड करें"</string> - <string name="permdesc_readInputState" msgid="8387754901688728043">"एप्स को अन्य एप्स के साथ सहभागिता करते समय भी आपके द्वारा दबाई जाने वाली कुंजियां देखने देता है (जैसे कोई पासवर्ड लिखना). सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_readInputState" msgid="8387754901688728043">"एप्स को अन्य एप्स के साथ सहभागिता करते समय भी आपके द्वारा दबाई जाने वाली कुंजियां देखने देता है (जैसे कोई पासवर्ड लिखना). सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindInputMethod" msgid="3360064620230515776">"किसी इनपुट विधि से आबद्ध करें"</string> - <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"आसान तरीका सेवा से आबद्ध करें"</string> - <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी आसान तरीका सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी आसान तरीका सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindPrintService" msgid="8462815179572748761">"प्रिंट सेवा से आबद्ध करें"</string> - <string name="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिंट स्पूलर सेवा से आबद्ध करें"</string> - <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवा से आबद्ध रहें"</string> <string name="permdesc_bindNfcService" msgid="6120647629174066862">"धारक को ऐसे एप्स से आबद्ध रहने देता है जो NFC कार्ड का अनुकरण कर रहे हैं. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string> - <string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindVpnService" msgid="4708596021161473255">"किसी VPN सेवा से आबद्ध करें"</string> - <string name="permdesc_bindVpnService" msgid="2067845564581693905">"धारक को किसी Vpn सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindVpnService" msgid="2067845564581693905">"धारक को किसी Vpn सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindWallpaper" msgid="8716400279937856462">"वॉलपेपर से आबद्ध करें"</string> - <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"धारक को किसी वॉलपेपर के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"धारक को किसी वॉलपेपर के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"किसी विजेट सेवा से आबद्ध करें"</string> - <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"धारक को किसी विजेट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"धारक को किसी विजेट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"किसी उपकरण व्यवस्थापक के साथ सहभागिता करें"</string> - <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"धारक को किसी उपकरण व्यवस्थापक को उद्देश्य भेजने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"धारक को किसी उपकरण व्यवस्थापक को उद्देश्य भेजने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</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> + <string name="permdesc_setOrientation" msgid="3046126619316671476">"ऐप्स को किसी भी समय स्क्रीन का रोटेशन बदलने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सूचक गति बदलें"</string> - <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"एप्स को माउस या ट्रैकपैड सूचक गति को किसी भी समय बदलने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"एप्स को माउस या ट्रैकपैड सूचक गति को किसी भी समय बदलने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"कीबोर्ड लेआउट बदलें"</string> - <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"एप्स को कीबोर्ड लेआउट बदलने देता है. सामान्य एप्स के लिए कभी आवश्यक नहीं है."</string> + <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"ऐप्स को कीबोर्ड लेआउट बदलने देता है. सामान्य ऐप्स के लिए कभी आवश्यक नहीं है."</string> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"एप्स को Linux सिग्नल भेजें"</string> - <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="permlab_deletePackages" msgid="184385129537705938">"एप्स हटाएं"</string> + <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="permlab_deletePackages" msgid="184385129537705938">"ऐप्स हटाएं"</string> <string name="permdesc_deletePackages" msgid="7411480275167205081">"एप्स को Android पैकेज हटाने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग महत्वपूर्ण एप्स हटाने के लिए कर सकते हैं."</string> - <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्य एप्स का डेटा हटाएं"</string> + <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्य ऐप्स का डेटा हटाएं"</string> <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"एप्स को उपयोगकर्ता डेटा साफ़ करने देता है."</string> - <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"अन्य एप्स के संचय हटाएं"</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="permlab_installPackages" msgid="2199128482820306924">"सीधे एप्स इंस्टॉल करें"</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_movePackage" msgid="3289890271645921411">"एप्स संसाधनों को ले जाएं"</string> - <string name="permdesc_movePackage" msgid="319562217778244524">"एप्स को एप्स संसाधनों को आंतरिक से बाहरी मीडिया में और इसके विपरीत ले जाने देता है."</string> + <string name="permlab_movePackage" msgid="3289890271645921411">"ऐप्स संसाधनों को ले जाएं"</string> + <string name="permdesc_movePackage" msgid="319562217778244524">"ऐप्स को ऐप्स संसाधनों को आंतरिक से बाहरी मीडिया में और इसके विपरीत ले जाने देता है."</string> <string name="permlab_readLogs" msgid="6615778543198967614">"संवेदनशील लॉग डेटा पढ़ें"</string> - <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"किसी एप्स को सिस्टम की विभिन्न लॉग फ़ाइलों से पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी शामिल करते हुए, टेबलेट के साथ आप क्या कर रहे हैं इस बारे में सामान्य जानकारी खोजने देता है."</string> - <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"एप्स को सिस्टम की विभिन्न लॉग फ़ाइलें पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी सहित, यह इसे इस बारे में सामान्य जानकारी खोजने देता है कि आप फ़ोन से क्या कर रहे हैं."</string> + <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"किसी ऐप्स को सिस्टम की विभिन्न लॉग फ़ाइलों से पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी शामिल करते हुए, टेबलेट के साथ आप क्या कर रहे हैं इस बारे में सामान्य जानकारी खोजने देता है."</string> + <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"ऐप्स को सिस्टम की विभिन्न लॉग फ़ाइलें पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी सहित, यह इसे इस बारे में सामान्य जानकारी खोजने देता है कि आप फ़ोन से क्या कर रहे हैं."</string> <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"प्लेबैक के लिए किसी भी मीडिया डीकोडर का उपयोग करें"</string> <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"एप्स को प्लेबैक डीकोड करने के लिए किसी भी इंस्टॉल किए गए डीकोडर का उपयोग करने देता है."</string> <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"विश्वसनीय क्रेडेंशियल प्रबंधित करें"</string> <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"एप्स को CA प्रमाणपत्रों को विश्वसनीय क्रेडेंशियल के रूप में इंस्टॉल और अनइंस्टॉल करने दें"</string> <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्वामित्व वाले संसाधनों को पढ़ें/लिखें"</string> - <string name="permdesc_diagnostic" msgid="6608295692002452283">"एप्स को diag समूह के स्वामित्व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्टम की स्थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string> - <string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्स घटकों को सक्षम या अक्षम करें"</string> - <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"एप्स को यह बदलने देता है कि किसी अन्य एप्स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्स महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्स घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string> - <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"एप्स को यह बदलने देता है कि किसी अन्य एप्स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्स महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्स घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string> + <string name="permdesc_diagnostic" msgid="6608295692002452283">"ऐप्स को diag समूह के स्वामित्व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्टम की स्थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string> + <string name="permlab_changeComponentState" msgid="6335576775711095931">"ऐप्स घटकों को सक्षम या अक्षम करें"</string> + <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"ऐप्स को यह बदलने देता है कि किसी अन्य ऐप्स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण ऐप्स महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे ऐप्स घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string> + <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"ऐप्स को यह बदलने देता है कि किसी अन्य ऐप्स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण ऐप्स महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे ऐप्स घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string> <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमति दें या रद्द करें"</string> <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"एप्स को उसके या अन्य एप्स के लिए विशेष अनुमतियां देने या रद्द करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग उन सुविधाओं तक पहुंचने के लिए कर सकते हैं जो आपने उन्हें नहीं दी हैं."</string> - <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्स सेट करें"</string> + <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा ऐप्स सेट करें"</string> <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्स को आपके पसंदीदा एप्स को संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्स को स्पूफ़ करके, चलाए जाने वाले एप्स को चुपचाप बदल सकते हैं."</string> <string name="permlab_writeSettings" msgid="2226195290955224730">"सिस्टम सेटिंग बदलें"</string> <string name="permdesc_writeSettings" msgid="7775723441558907181">"एप्स को सिस्टम सेटिंग डेटा संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपके सिस्टम के कॉन्फ़िगरेशन को दूषित कर सकते हैं."</string> <string name="permlab_writeSecureSettings" msgid="204676251876718288">"सुरक्षित सिस्टम सेटिंग बदलें"</string> - <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"एप्स को सिस्टम के सुरक्षित सेटिंग डेटा को संशोधित करने देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</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="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> <string name="permlab_broadcastSticky" msgid="7919126372606881614">"स्टिकी प्रसारण भेजें"</string> - <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"एप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टेबलेट की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string> - <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"एप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string> + <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टेबलेट की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string> + <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string> <string name="permlab_readContacts" msgid="8348481131899886131">"अपने संपर्क पढ़ें"</string> <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"एप्स को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति एप्स को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string> <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"एप्स को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति एप्स को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string> @@ -447,8 +447,8 @@ <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> - <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string> + <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string> + <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string> <string name="permlab_readProfile" msgid="4701889852612716678">"स्वयं का संपर्क कार्ड पढ़ें"</string> <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"एप्स को आपके उपकरण में संग्रहीत व्यक्तिगत प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी, पढ़ने देता है. इसका अर्थ है कि एप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string> <string name="permlab_writeProfile" msgid="907793628777397643">"स्वयं का संपर्क कार्ड बदलें"</string> @@ -474,21 +474,21 @@ <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"अनुमानित स्थान (नेटवर्क-आधारित)"</string> <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"एप्स को आपका अनुमानित स्थान प्राप्त करने देती है. इस स्थान को सेल टॉवर और Wi-Fi जैसे नेटवर्क स्थान स्रोतों का उपयोग करके स्थान सेवाओं द्वारा प्राप्त किया गया है. एप्स द्वारा इन स्थान सेवाओं का उपयोग करने के लिए इन्हें चालू होना चाहिए और आपके उपकरण में उपलब्ध होना चाहिए. एप्स इसका उपयोग यह पता लगाने में कर सकते हैं कि आप लगभग कहां पर हैं."</string> <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger में पहुंचें"</string> - <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"एप्स को SurfaceFlinger निम्न-स्तर सुविधाएं उपयोग करने देता है."</string> + <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ऐप्स को SurfaceFlinger निम्न-स्तर सुविधाएं उपयोग करने देता है."</string> <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ़्रेम बफ़र पढ़ें"</string> - <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"एप्स को फ़्रेम बफ़र की सामग्री पढ़ने देता है."</string> + <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ऐप्स को फ़्रेम बफ़र की सामग्री पढ़ने देता है."</string> <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi डिस्प्ले को कॉन्फ़िगर करें"</string> <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"एप्स को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string> <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi डिस्प्ले को नियंत्रित करें"</string> <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"एप्स को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string> <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ऑडियो आउटपुट को कैप्चर करें"</string> - <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"एप्स को ऑडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> + <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ऐप्स को ऑडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"हॉटवर्ड पहचान"</string> <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"एप्लिकेशन को हॉटवर्ड पहचान के लिए ऑडियो कैप्चर करने देती है. कैप्चर पृष्ठभूमि में हो सकता है लेकिन वह अन्य ऑडियो कैप्चर (उदा. कैमकॉर्डर) को नहीं रोकता."</string> <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"वीडियो आउटपुट को कैप्चर करें"</string> - <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"एप्स को वीडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> + <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ऐप्स को वीडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित वीडियो आउटपुट को कैप्चर करें"</string> - <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"एप्स को सुरक्षित वीडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> + <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ऐप्स को सुरक्षित वीडियो आउटपुट को कैप्चर और रीडायरेक्ट करने देता है."</string> <string name="permlab_mediaContentControl" msgid="8749790560720562511">"मीडिया प्लेबैक और मेटाडेटा एक्सेस नियंत्रित करें"</string> <string name="permdesc_mediaContentControl" msgid="1637478200272062">"एप्लिकेशन को मीडिया प्लेबैक नियंत्रित करने देती है और मीडिया जानकारी (शीर्षक, लेखक...) एक्सेस करने देती है."</string> <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"अपनी ऑडियो सेटिंग बदलें"</string> @@ -501,53 +501,53 @@ <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"पहले से इंस्टॉल किए गए सिस्टम एप्स को कैमरे को संकेतक LED का उपयोग करने से अक्षम करती है."</string> <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"स्थायी रूप से टेबलेट अक्षम करें"</string> <string name="permlab_brick" product="default" msgid="8337817093326370537">"फ़ोन को स्थायी रूप से अक्षम करें"</string> - <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"एप्स को संपूर्ण टेबलेट को स्थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string> - <string name="permdesc_brick" product="default" msgid="5788903297627283099">"एप्स को संपूर्ण फ़ोन को स्थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string> + <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"ऐप्स को संपूर्ण टेबलेट को स्थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string> + <string name="permdesc_brick" product="default" msgid="5788903297627283099">"ऐप्स को संपूर्ण फ़ोन को स्थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string> <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"टेबलेट रीबूट के लिए बाध्य करें"</string> <string name="permlab_reboot" product="default" msgid="2898560872462638242">"फ़ोन रीबूट के लिए बाध्य करें"</string> - <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"एप्स को टेबलेट रीबूट करने के लिए बाध्य करने देता है."</string> - <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"एप्स को फ़ोन बलपूर्वक रीबूट करने देता है."</string> + <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ऐप्स को टेबलेट रीबूट करने के लिए बाध्य करने देता है."</string> + <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ऐप्स को फ़ोन बलपूर्वक रीबूट करने देता है."</string> <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB संग्रहण फ़ाइल सिस्टम पर पहुंचें"</string> <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD कार्ड फ़ाइल सिस्टम पर पहुंचें"</string> - <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"एप्स को निकाले जाने योग्य संग्रहण के लिए फ़ाइल सिस्टम माउंट और अनमाउंट करने देता है."</string> + <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ऐप्स को निकाले जाने योग्य संग्रहण के लिए फ़ाइल सिस्टम माउंट और अनमाउंट करने देता है."</string> <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB संग्रहण मिटाएं"</string> <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD कार्ड मिटाएं"</string> - <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"एप्स को निकालने योग्य संग्रहण फ़ॉर्मेट करने देता है."</string> + <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ऐप्स को निकालने योग्य संग्रहण फ़ॉर्मेट करने देता है."</string> <string name="permlab_asec_access" msgid="3411338632002193846">"मोबाइल संग्रहण पर जानकारी प्राप्त करें"</string> <string name="permdesc_asec_access" msgid="3094563844593878548">"एप्स को मोबाइल संग्रहण की जानकारी प्राप्त करने देता है."</string> <string name="permlab_asec_create" msgid="6414757234789336327">"मोबाइल संग्रहण बनाएं"</string> - <string name="permdesc_asec_create" msgid="4558869273585856876">"एप्स को मोबाइल संग्रहण बनाने देता है."</string> + <string name="permdesc_asec_create" msgid="4558869273585856876">"ऐप्स को मोबाइल संग्रहण बनाने देता है."</string> <string name="permlab_asec_destroy" msgid="526928328301618022">"मोबाइल संग्रहण नष्ट करें"</string> - <string name="permdesc_asec_destroy" msgid="7218749286145526537">"एप्स को मोबाइल संग्रहण नष्ट करने देता है."</string> + <string name="permdesc_asec_destroy" msgid="7218749286145526537">"ऐप्स को मोबाइल संग्रहण नष्ट करने देता है."</string> <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"मोबाइल संग्रहण माउंट/अनमाउंट करें"</string> - <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"एप्स को मोबाइल संग्रहण माउंट/अनमाउंट करने देता है."</string> + <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"ऐप्स को मोबाइल संग्रहण माउंट/अनमाउंट करने देता है."</string> <string name="permlab_asec_rename" msgid="7496633954080472417">"मोबाइल संग्रहण का नाम बदलें"</string> - <string name="permdesc_asec_rename" msgid="1794757588472127675">"एप्स को मोबाइल संग्रहण का नाम बदलने देता है."</string> + <string name="permdesc_asec_rename" msgid="1794757588472127675">"ऐप्स को मोबाइल संग्रहण का नाम बदलने देता है."</string> <string name="permlab_vibrate" msgid="7696427026057705834">"कंपन नियंत्रित करें"</string> - <string name="permdesc_vibrate" msgid="6284989245902300945">"एप्स को कंपनकर्ता नियंत्रित करने देता है."</string> + <string name="permdesc_vibrate" msgid="6284989245902300945">"ऐप्स को कंपनकर्ता नियंत्रित करने देता है."</string> <string name="permlab_flashlight" msgid="2155920810121984215">"फ़्लैशलाइट नियंत्रित करें"</string> - <string name="permdesc_flashlight" msgid="6522284794568368310">"एप्स को फ़्लैशलाइट नियंत्रित करने देता है."</string> + <string name="permdesc_flashlight" msgid="6522284794568368310">"ऐप्स को फ़्लैशलाइट नियंत्रित करने देता है."</string> <string name="permlab_manageUsb" msgid="1113453430645402723">"USB उपकरणों की प्राथमिकताएं और अनुमतियां प्रबंधित करें"</string> - <string name="permdesc_manageUsb" msgid="7776155430218239833">"एप्स को USB उपकरणों की प्राथमिकताओं और अनुमतियों को प्रबंधित करने देता है."</string> + <string name="permdesc_manageUsb" msgid="7776155430218239833">"ऐप्स को USB उपकरणों की प्राथमिकताओं और अनुमतियों को प्रबंधित करने देता है."</string> <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP प्रोटोकॉल लागू करें"</string> <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB प्रोटोकॉल लागू करने के लिए कर्नेल MTP ड्राइवर में पहुंच की अनुमति देता है."</string> <string name="permlab_hardware_test" msgid="4148290860400659146">"परीक्षण हार्डवेयर"</string> - <string name="permdesc_hardware_test" msgid="6597964191208016605">"एप्स को हार्डवेयर परीक्षण के लिए विविध सहायक उपकरणों को नियंत्रित करने देता है."</string> + <string name="permdesc_hardware_test" msgid="6597964191208016605">"ऐप्स को हार्डवेयर परीक्षण के लिए विविध सहायक उपकरणों को नियंत्रित करने देता है."</string> <string name="permlab_callPhone" msgid="3925836347681847954">"फ़ोन नंबर पर सीधे कॉल करें"</string> <string name="permdesc_callPhone" msgid="3740797576113760827">"एप्स को आपके हस्तक्षेप के बिना फ़ोन नंबर पर कॉल करने देता है. इसके परिणाम अप्रत्याशित शुल्क या कॉल हो सकते हैं. ध्यान दें कि यह एप्स को आपातकालीन नंबर पर कॉल नहीं करने देता. दुर्भावनापूर्ण एप्स आपकी पुष्टि के बिना कॉल करके आपका धन व्यय कर सकते हैं."</string> <string name="permlab_callPrivileged" msgid="4198349211108497879">"किसी भी फ़ोन नंबर पर सीधे कॉल करें"</string> - <string name="permdesc_callPrivileged" msgid="1689024901509996810">"एप्स को आपके हस्तक्षेप के बिना आपातकालीन नंबरों सहित, किसी भी फ़ोन नंबर पर कॉल करने देता है. दुर्भावनापूर्ण एप्स आपातकालीन सेवाओं पर अनावश्यक और अवैध कॉल कर सकते हैं."</string> + <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ऐप्स को आपके हस्तक्षेप के बिना आपातकालीन नंबरों सहित, किसी भी फ़ोन नंबर पर कॉल करने देता है. दुर्भावनापूर्ण ऐप्स आपातकालीन सेवाओं पर अनावश्यक और अवैध कॉल कर सकते हैं."</string> <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"सीधे CDMA टेबलेट सेटअप प्रारंभ करें"</string> <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"सीधे CDMA फ़ोन सेटअप प्रारंभ करें"</string> - <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"एप्स को CDMA प्रावधान प्रारंभ करने देता है. दुर्भावनापूर्ण एप्स अनावश्यक रूप से CDMA प्रावधान प्रारंभ कर सकते हैं."</string> + <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ऐप्स को CDMA प्रावधान प्रारंभ करने देता है. दुर्भावनापूर्ण ऐप्स अनावश्यक रूप से CDMA प्रावधान प्रारंभ कर सकते हैं."</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्थान के बारे में नई जानकारी की सूचनाओं को नियंत्रित करें"</string> - <string name="permdesc_locationUpdates" msgid="1120741557891438876">"एप को रेडियो से स्थान के बारे में नई जानकारी की सूचनाएं सक्षम/अक्षम करने देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_locationUpdates" msgid="1120741557891438876">"एप को रेडियो से स्थान के बारे में नई जानकारी की सूचनाएं सक्षम/अक्षम करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_checkinProperties" msgid="7855259461268734914">"चेकइन गुणों में पहुंचें"</string> - <string name="permdesc_checkinProperties" msgid="4024526968630194128">"एप्स को चेकइन सेवा द्वारा अपलोड किए गए गुणों पर पढ़ें/लिखें पहुंच देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_checkinProperties" msgid="4024526968630194128">"एप्स को चेकइन सेवा द्वारा अपलोड किए गए गुणों पर पढ़ें/लिखें पहुंच देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_bindGadget" msgid="776905339015863471">"विजेट चुनें"</string> - <string name="permdesc_bindGadget" msgid="8261326938599049290">"एप्स को सिस्टम को यह बताने देता है कि किस एप्स द्वारा कौन से विजेट का उपयोग किया जा सकता है. कोई एप्स, इस अनुमति के साथ अन्य एप्स के निजी डेटा पर पहुंच सकते हैं. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_bindGadget" msgid="8261326938599049290">"एप्स को सिस्टम को यह बताने देता है कि किस एप्स द्वारा कौन से विजेट का उपयोग किया जा सकता है. कोई एप्स, इस अनुमति के साथ अन्य एप्स के निजी डेटा पर पहुंच सकते हैं. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"फ़ोन स्थिति बदलें"</string> - <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"एप्स को उपकरण की फ़ोन सुविधाएं नियंत्रित करने देता है. इस अनुमति वाला कोई एप्स आपको सूचित किए बिना नेटवर्क स्विच कर सकता है, फ़ोन का रेडियो चालू और बंद कर सकता है और ऐसे ही अन्य कार्य कर सकता है."</string> + <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ऐप्स को उपकरण की फ़ोन सुविधाएं नियंत्रित करने देता है. इस अनुमति वाला कोई ऐप्स आपको सूचित किए बिना नेटवर्क स्विच कर सकता है, फ़ोन का रेडियो चालू और बंद कर सकता है और ऐसे ही अन्य कार्य कर सकता है."</string> <string name="permlab_readPhoneState" msgid="9178228524507610486">"फ़ोन की स्थिति और पहचान पढ़ें"</string> <string name="permdesc_readPhoneState" msgid="1639212771826125528">"एप्स को उपकरण की फ़ोन सुविधाओं तक पहुंचने देता है. यह अनुमति एप्स को फ़ोन नंबर और उपकरण आईडी, कॉल सक्रिय है या नहीं, और कॉल द्वारा कनेक्ट किया गया दूरस्थ नंबर निर्धारित करने देती है."</string> <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्क्रिय होने से रोकें"</string> @@ -559,32 +559,32 @@ <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"एप्लिकेशन को फ़ोन के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string> <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"टेबलेट चालू या बंद करें"</string> <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फ़ोन चालू या बंद करें"</string> - <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"एप्स को टेबलेट चालू या बंद करने देता है."</string> - <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"एप्स को फ़ोन चालू या बंद करने देता है."</string> + <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ऐप्स को टेबलेट चालू या बंद करने देता है."</string> + <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"ऐप्स को फ़ोन चालू या बंद करने देता है."</string> <string name="permlab_factoryTest" msgid="3715225492696416187">"फ़ैक्ट्री परीक्षण मोड में चलाएं"</string> <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"टेबलेट हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्न-स्तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्ध जब कोई टेबलेट निर्माता परीक्षण मोड में चल रहा हो."</string> <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"फ़ोन हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्न-स्तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्ध जब कोई फ़ोन निर्माता परीक्षण मोड में चल रहा हो."</string> <string name="permlab_setWallpaper" msgid="6627192333373465143">"वॉलपेपर सेट करें"</string> - <string name="permdesc_setWallpaper" msgid="7373447920977624745">"एप्स को सिस्टम वॉलपेपर सेट करने देता है."</string> + <string name="permdesc_setWallpaper" msgid="7373447920977624745">"ऐप्स को सिस्टम वॉलपेपर सेट करने देता है."</string> <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"अपने वॉलपेपर का आकार एडजस्ट करें"</string> - <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"एप्स को सिस्टम वॉलपेपर आकार संकेत सेट करने देता है."</string> + <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="permdesc_setTime" product="tablet" msgid="1896341438151152881">"एप्स को टेबलेट की घड़ी का समय बदलने देता है."</string> - <string name="permdesc_setTime" product="default" msgid="1855702730738020">"एप्स को फ़ोन की घड़ी का समय बदलने देता है."</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> - <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"एप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string> - <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"एप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string> + <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ऐप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string> + <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ऐप्स को टेबलेट का समय क्षेत्र बदलने देता है."</string> <string name="permlab_accountManagerService" msgid="4829262349691386986">"खाता प्रबंधक सेवा के रूप में कार्य करें"</string> - <string name="permdesc_accountManagerService" msgid="1948455552333615954">"एप्स को खाता प्रमाणकों को कॉल करने देता है."</string> + <string name="permdesc_accountManagerService" msgid="1948455552333615954">"ऐप्स को खाता प्रमाणकों को कॉल करने देता है."</string> <string name="permlab_getAccounts" msgid="1086795467760122114">"उपकरण पर खाते ढूंढें"</string> <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"एप्स को टेबलेट द्वारा ज्ञात खातों की सूची प्राप्त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्हें आपके द्वारा इंस्टॉल किए गए एप्स ने बनाया है."</string> <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"एप्स को फ़ोन द्वारा ज्ञात खातों की सूची प्राप्त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्हें आपके द्वारा इंस्टॉल किए गए एप्स ने बनाया है."</string> <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"खाते बनाएं और पासवर्ड सेट करें"</string> <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"एप्िलकेशन को खाता बनाने और उनके पासवर्ड प्राप्त करने और सेट करने सहित, खाता प्रबंधक की खाता प्रमाणक क्षमताओं का उपयोग करने देता है."</string> <string name="permlab_manageAccounts" msgid="4983126304757177305">"खाते जोडें या निकालें"</string> - <string name="permdesc_manageAccounts" msgid="8698295625488292506">"एप्स को खाते जोड़ना और निकालना और उनके पासवर्ड हटाने जैसे कार्य करने देता है."</string> + <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ऐप्स को खाते जोड़ना और निकालना और उनके पासवर्ड हटाने जैसे कार्य करने देता है."</string> <string name="permlab_useCredentials" msgid="235481396163877642">"उपकरण पर खातों का उपयोग करें"</string> <string name="permdesc_useCredentials" msgid="7984227147403346422">"एप्स को प्रमाणीकरण टोकन का अनुरोध करने देता है."</string> <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क कनेक्शन देखें"</string> @@ -596,9 +596,9 @@ <string name="permlab_changeNetworkState" msgid="958884291454327309">"नेटवर्क कनेक्टिविटी बदलें"</string> <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"एप्स को नेटवर्क कनेक्टिविटी की स्थिति बदलने देता है."</string> <string name="permlab_changeTetherState" msgid="5952584964373017960">"टेदर की गई कनेक्टिविटी बदलें"</string> - <string name="permdesc_changeTetherState" msgid="1524441344412319780">"एप्स को टेदर की गई नेटवर्क कनेक्टिविटी की स्थिति बदलने देता है."</string> + <string name="permdesc_changeTetherState" msgid="1524441344412319780">"ऐप्स को टेदर की गई नेटवर्क कनेक्टिविटी की स्थिति बदलने देता है."</string> <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"पृष्ठभूमि डेटा उपयोग सेटिंग बदलें"</string> - <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"एप्स को पृष्ठभूमि डेटा उपयोग सेटिंग बदलने देता है."</string> + <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"ऐप्स को पृष्ठभूमि डेटा उपयोग सेटिंग बदलने देता है."</string> <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi कनेक्शन देखें"</string> <string name="permdesc_accessWifiState" msgid="5002798077387803726">"एप्स को Wi-Fi नेटवर्क के बारे में जानकारी, जैसे WI-Fi सक्षम है या नहीं और कनेक्ट किए गए Wi-Fi उपकरणों के नाम, देखने देता है."</string> <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi से कनेक्ट और डिस्कनेक्ट करें"</string> @@ -607,23 +607,23 @@ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"एप्स को Wi-Fi नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके टेबलेट पर ही नहीं, बल्कि सभी उपकरणों पर भेजे गए पैकेट प्राप्त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string> <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"एप्स को Wi-Fi नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके फ़ोन पर ही नहीं, बल्कि सभी उपकरणों पर भेजे गए पैकेट प्राप्त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string> <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth सेटिंग पर पहुंचें"</string> - <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी एप्स को स्थानीय Bluetooth टेबलेट कॉन्फ़िगर करने की और रिमोट उपकरणों के साथ खोजने और युग्मित करने देता है."</string> - <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"एप्स को स्थानीय Bluetooth फ़ोन कॉन्फ़िगर करने देता है, और रिमोट उपकरणों के साथ खोजने और युग्मित करने देता है."</string> + <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी ऐप्स को स्थानीय Bluetooth टेबलेट कॉन्फ़िगर करने की और रिमोट उपकरणों के साथ खोजने और युग्मित करने देता है."</string> + <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ऐप्स को स्थानीय Bluetooth फ़ोन कॉन्फ़िगर करने देता है, और रिमोट उपकरणों के साथ खोजने और युग्मित करने देता है."</string> <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"एप्लिकेशन के द्वारा Bluetooth युग्मन करने देती है"</string> <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"एप्लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्थ उपकरणों के साथ युग्मित करने देती है."</string> <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"एप्लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्थ उपकरणों के साथ युग्मित करने देती है."</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> - <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"एप्स को WiMAX नेटवर्क से टेबलेट को कनेक्ट और डिस्कनेक्ट करने देता है."</string> - <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"एप्स को WiMAX नेटवर्क से फ़ोन को कनेक्ट और डिस्कनेक्ट करने देता है."</string> + <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ऐप्स को WiMAX नेटवर्क से टेबलेट को कनेक्ट और डिस्कनेक्ट करने देता है."</string> + <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ऐप्स को WiMAX नेटवर्क से फ़ोन को कनेक्ट और डिस्कनेक्ट करने देता है."</string> <string name="permlab_bluetooth" msgid="6127769336339276828">"Bluetooth उपकरणों के साथ युग्मित करें"</string> - <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"एप्स को टेबलेट पर Bluetooth का कॉन्फ़िगरेशन देखने, और युग्मित उपकरणों के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string> - <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"एप्स को फ़ोन पर Bluetooth का कॉन्फ़िगरेशन देखने, और युग्मित उपकरणों के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string> + <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ऐप्स को टेबलेट पर Bluetooth का कॉन्फ़िगरेशन देखने, और युग्मित उपकरणों के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string> + <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ऐप्स को फ़ोन पर Bluetooth का कॉन्फ़िगरेशन देखने, और युग्मित उपकरणों के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string> <string name="permlab_nfc" msgid="4423351274757876953">"नियर फ़ील्ड कम्यूनिकेशन नियंत्रित करें"</string> <string name="permdesc_nfc" msgid="7120611819401789907">"एप्स को नियर फ़ील्ड कम्यूनिकेशन (NFC) टैग, कार्ड, और रीडर के साथ संचार करने देता है."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"अपना स्क्रीन लॉक अक्षम करें"</string> - <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"एप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा अक्षम करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल प्राप्त करते समय फ़ोन, कीलॉक को अक्षम कर देता है, फिर कॉल समाप्त होने पर कीलॉक को पुन: सक्षम कर देता है."</string> + <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ऐप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा अक्षम करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल प्राप्त करते समय फ़ोन, कीलॉक को अक्षम कर देता है, फिर कॉल समाप्त होने पर कीलॉक को पुन: सक्षम कर देता है."</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"एप्स को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग एप्स किसी खाते के साथ समन्वयित है या नहीं."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्वयन बंद या चालू टॉगल करें"</string> @@ -631,11 +631,11 @@ <string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string> <string name="permdesc_readSyncStats" msgid="1510143761757606156">"एप्स को किसी खाते के समन्वयन आंकड़े, साथ ही समन्वयित ईवेंट का इतिहास और समन्वयित डेटा की मात्रा पढ़ने देता है."</string> <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ग्राहकी-प्राप्त फ़ीड पढ़ें"</string> - <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"एप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string> + <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ऐप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string> <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ग्राहकी-प्राप्त फ़ीड लिखें"</string> <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"एप्स को आपके वर्तमान समन्वयित फ़ीड को संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपके समन्वयित फ़ीड को बदल सकते है."</string> <string name="permlab_readDictionary" msgid="4107101525746035718">"शब्दकोश में आपके द्वारा जोड़े गए शब्दों को पढ़ें"</string> - <string name="permdesc_readDictionary" msgid="659614600338904243">"एप्स को ऐसे सभी शब्दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता शब्दकोश में संग्रहीत किए गए हों."</string> + <string name="permdesc_readDictionary" msgid="659614600338904243">"ऐप्स को ऐसे सभी शब्दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता शब्दकोश में संग्रहीत किए गए हों."</string> <string name="permlab_writeDictionary" msgid="2183110402314441106">"उपयोगकर्ता द्वारा परिभाषित शब्दकोश में शब्द जोड़ें"</string> <string name="permdesc_writeDictionary" msgid="8185385716255065291">"एप्स को उपयोगकर्ता शब्दकोश में नए शब्द लिखने देता है."</string> <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"अपने USB संग्रहण की सामग्री पढ़ें"</string> @@ -653,17 +653,17 @@ <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="permdesc_cache_filesystem" msgid="5578967642265550955">"ऐप्स को संचय फ़ाइल सिस्टम पढ़ने और लिखने देता है."</string> <string name="permlab_use_sip" msgid="5986952362795870502">"इंटरनेट कॉल करें/प्राप्त करें"</string> <string name="permdesc_use_sip" msgid="4717632000062674294">"एप्स को इंटरनेट कॉल करने/प्राप्त करने के लिए SIP सेवा का उपयोग करने देता है."</string> <string name="permlab_bind_call_service" msgid="6724009726671246551">"इन-कॉल स्क्रीन से सहभागिता करें"</string> <string name="permdesc_bind_call_service" msgid="8732547662442572435">"एप्लिकेशन को यह नियंत्रित करने देती है कि उपयोगकर्ता को इन-कॉल स्क्रीन कब और कैसी दिखाई देती है."</string> <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ऐतिहासिक नेटवर्क उपयोग पढें"</string> - <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"किसी एप्स को विशिष्ट नेटवर्क और एप्स के लिए ऐतिहासिक नेटवर्क उपयोग को पढ़ने देता है."</string> + <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"किसी एप्स को विशिष्ट नेटवर्क और ऐप्स के लिए ऐतिहासिक नेटवर्क उपयोग को पढ़ने देता है."</string> <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"नेटवर्क नीति प्रबंधित करें"</string> - <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"एप्स को नेटवर्क नीतियां प्रबंधित करने और एप्स-विशिष्ट नियमों को परिभाषित करने देता है."</string> + <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ऐप्स को नेटवर्क नीतियां प्रबंधित करने और ऐप्स-विशिष्ट नियमों को परिभाषित करने देता है."</string> <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब बदलें"</string> - <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"एप्स को यह संशोधित करने देता है कि एप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"एप्स को यह संशोधित करने देता है कि ऐप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"सॉकेट मार्क बदलें"</string> <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"एप्स को रूटिंग के लिए सॉकेट मार्क बदलने देता है"</string> <string name="permlab_accessNotifications" msgid="7673416487873432268">"सूचनाओं तक पहुंचें"</string> @@ -671,7 +671,7 @@ <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"सूचना श्रवणकर्ता सेवा से जुड़ें"</string> <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को सूचना श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string> <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करें"</string> - <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्थितियों के अवलोकनों को सुनें"</string> <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"एप्स को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string> @@ -691,7 +691,7 @@ <string name="policylab_expirePassword" msgid="885279151847254056">"स्क्रीन लॉक करें पासवर्ड समाप्ति सेट करें"</string> <string name="policydesc_expirePassword" msgid="1729725226314691591">"नियंत्रित करें कि कितने समय में लॉक-स्क्रीन पासवर्ड बदला जाना चाहिए."</string> <string name="policylab_encryptedStorage" msgid="8901326199909132915">"संग्रहण एन्क्रिप्शन सेट करें"</string> - <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"संग्रहीत एप्स डेटा को एन्क्रिप्ट किया जाना आवश्यक है."</string> + <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"संग्रहीत ऐप्स डेटा को एन्क्रिप्ट किया जाना आवश्यक है."</string> <string name="policylab_disableCamera" msgid="6395301023152297826">"कैमरों को अक्षम करें"</string> <string name="policydesc_disableCamera" msgid="2306349042834754597">"सभी उपकरण कैमरों का उपयोग रोकें."</string> <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"कीगार्ड में सुविधाएं अक्षम करें"</string> @@ -945,15 +945,15 @@ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"एप्स को आपके टेबलेट में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे एप्स ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्य एप्स द्वारा लागू नहीं की जा सकती."</string> <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"एप्स को आपके फ़ोन में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे एप्स ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्य एप्स द्वारा लागू नहीं की जा सकती."</string> <string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करें"</string> - <string name="permdesc_setAlarm" msgid="316392039157473848">"एप्स को इंस्टॉल किए गए अलार्म घड़ी एप्स में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी एप्स में यह सुविधा न हो."</string> + <string name="permdesc_setAlarm" msgid="316392039157473848">"ऐप्स को इंस्टॉल किए गए अलार्म घड़ी ऐप्स में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी ऐप्स में यह सुविधा न हो."</string> <string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्वनिमेल जोड़ें"</string> <string name="permdesc_addVoicemail" msgid="6604508651428252437">"एप्स को आपके ध्वनिमेल इनबॉक्स में संदेश जोड़ने देता है."</string> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउज़र भौगोलिक-स्थान अनुमतियों को बदलें"</string> - <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"एप्स को ब्राउज़र के भौगोलिक-स्थान की अनुमतियां संशोधित करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग एकपक्षीय वेबसाइट को स्थान जानकारी भेजने में कर सकते हैं."</string> + <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ऐप्स को ब्राउज़र के भौगोलिक-स्थान की अनुमतियां संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग एकपक्षीय वेबसाइट को स्थान जानकारी भेजने में कर सकते हैं."</string> <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"पैकेज सत्यापित करें"</string> <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"एप्लिकेशन को इंस्टॉल करने योग्य पैकेज सत्यापित करने देता है."</string> <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"पैकेज प्रमाणक से आबद्ध करें"</string> - <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"धारक को पैकेज प्रमाणक के अनुरोध की अनुमति देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> + <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"धारक को पैकेज प्रमाणक के अनुरोध की अनुमति देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_serialPort" msgid="546083327654631076">"सीरियल पोर्ट पर पहुंचें"</string> <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API का उपयोग करके धारक को सीरियल पोर्ट पर पहुंच प्रदान करता है."</string> <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"बाह्य रूप से सामग्री प्रदाताओं पर पहुंच"</string> @@ -1120,7 +1120,7 @@ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्टम सेटिंग > Apps > डाउनलोड किए गए में डिफ़ॉल्ट साफ करें."</string> <string name="chooseActivity" msgid="7486876147751803333">"कोई क्रिया चुनें"</string> <string name="chooseUsbActivity" msgid="6894748416073583509">"USB उपकरण के लिए कोई एप्स चुनें"</string> - <string name="noApplications" msgid="2991814273936504689">"कोई भी एप्स यह कार्यवाही नहीं कर सकता."</string> + <string name="noApplications" msgid="2991814273936504689">"कोई भी ऐप्स यह कार्यवाही नहीं कर सकता."</string> <string name="aerr_title" msgid="1905800560317137752"></string> <string name="aerr_application" msgid="932628488013092776">"दुर्भाग्यवश, <xliff:g id="APPLICATION">%1$s</xliff:g> रुक गया है."</string> <string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्यवश, <xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रिया रुक गई है."</string> @@ -1139,20 +1139,20 @@ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"स्केल"</string> <string name="screen_compat_mode_show" msgid="4013878876486655892">"हमेशा दिखाएं"</string> <string name="screen_compat_mode_hint" msgid="1064524084543304459">"इसे सिस्टम सेटिंग > Apps > डाउनलोड किए गए में पुन: सक्षम करें."</string> - <string name="smv_application" msgid="3307209192155442829">"एप्स <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने उसकी स्वयं लागू होने वाली StrictMode नीति का उल्लंघन किया है."</string> + <string name="smv_application" msgid="3307209192155442829">"ऐप्स <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने उसकी स्वयं लागू होने वाली StrictMode नीति का उल्लंघन किया है."</string> <string name="smv_process" msgid="5120397012047462446">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> ने उसकी स्व-प्रवर्तित StrictMode नीति का उल्लंघन किया है."</string> <string name="android_upgrading_title" msgid="1584192285441405746">"Android अपग्रेड हो रहा है..."</string> <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> एप्स अनुकूलित हो रहा है."</string> <string name="android_upgrading_starting_apps" msgid="451464516346926713">"एप्स प्रारंभ होने वाले हैं"</string> <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त हो रहा है."</string> <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चल रही है"</string> - <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"एप्स पर स्विच करने के लिए स्पर्श करें"</string> + <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"ऐप्स पर स्विच करने के लिए स्पर्श करें"</string> <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"एप्स स्विच करें?"</string> - <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"दूसरा एप्स पहले से चल रहा है जिसे किसी नए एप्स को प्रारंभ करने के पहले बंद किया जाना आवश्यक है."</string> + <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"दूसरा एप्स पहले से चल रहा है जिसे किसी नए ऐप्स को प्रारंभ करने के पहले बंद किया जाना आवश्यक है."</string> <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> पर वापस लौटें"</string> - <string name="old_app_description" msgid="2082094275580358049">"नया एप्स प्रारंभ न करें."</string> + <string name="old_app_description" msgid="2082094275580358049">"नया ऐप्स प्रारंभ न करें."</string> <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> प्रारंभ करें"</string> - <string name="new_app_description" msgid="1932143598371537340">"पुराने एप्स को बिना सहेजे बंद करें."</string> + <string name="new_app_description" msgid="1932143598371537340">"पुराने ऐप्स को बिना सहेजे बंद करें."</string> <string name="sendText" msgid="5209874571959469142">"पाठ के लिए किसी क्रिया को चुनें"</string> <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर वॉल्यूम"</string> <string name="volume_music" msgid="5421651157138628171">"मीडिया वॉल्यूम"</string> @@ -1247,7 +1247,7 @@ <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB संग्रहण बंद करें"</string> <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB संग्रहण बंद करने में कोई समस्या हुई थी. जांचें कि आपने USB होस्ट अनमाउंट किया है या नहीं, तब पुन: प्रयास करें."</string> <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB संग्रहण चालू करें"</string> - <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि आप USB संग्रहण चालू करते हैं, तो आपके द्वारा उपयोग किए जा रहे कुछ एप्स रुक जाएंगे और हो सकता है कि वे तब तक अनुपलब्ध रहें जब तक कि आप USB संग्रहण बंद नहीं कर देते."</string> + <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि आप USB संग्रहण चालू करते हैं, तो आपके द्वारा उपयोग किए जा रहे कुछ ऐप्स रुक जाएंगे और हो सकता है कि वे तब तक अनुपलब्ध रहें जब तक कि आप USB संग्रहण बंद नहीं कर देते."</string> <string name="dlg_error_title" msgid="7323658469626514207">"USB कार्यवाही विफल"</string> <string name="dlg_ok" msgid="7376953167039865701">"ठीक है"</string> <string name="usb_mtp_notification_title" msgid="3699913097391550394">"किसी मीडिया उपकरण के रूप में कनेक्ट किया गया"</string> @@ -1296,9 +1296,9 @@ <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD कार्ड निकाला गया. एक नया सम्मिलित करें."</string> <string name="activity_list_empty" msgid="1675388330786841066">"कोई मिलती-जुलती गतिविधि नहीं मिली."</string> <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"घटक उपयोग आंकड़ों की नई जानकारी पाएं"</string> - <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"एप्स को घटक उपयोग के संकलित आंकड़े संशोधित करने देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"ऐप्स को घटक उपयोग के संकलित आंकड़े संशोधित करने देता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> <string name="permlab_copyProtectedData" msgid="4341036311211406692">"सामग्री की प्रतिलिपि बनाएं"</string> - <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"एप्स को सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा शुरू करने देता है. सामान्य एप्स द्वारा उपयोग करने के लिए नहीं."</string> + <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> @@ -1316,7 +1316,7 @@ <string name="ime_action_default" msgid="2840921885558045721">"निष्पादित करें"</string> <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> के उपयोग द्वारा \n नंबर डायल करें"</string> <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> का उपयोग करके\n संपर्क बनाएं"</string> - <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्न एक या अधिक एप्स अभी और भविष्य में आपके खाते में पहुंच की अनुमति का अनुरोध करते हैं."</string> + <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> @@ -1413,7 +1413,7 @@ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</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="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> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 417c18ed99e6..eccabddf7fa0 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Coba <xliff:g id="COUNT">%d</xliff:g> detik lagi"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Coba lagi nanti"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Gesek ke bawah untuk keluar dari layar penuh"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Gesek dari atas ke bawah untuk keluar dari layar penuh."</string> </resources> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index a8025d895b3e..2152c332c962 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"კიდევ ერთხელ სცადეთ <xliff:g id="COUNT">%d</xliff:g> წამში"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"სცადეთ მოგვიანებით"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ჩამოასრიალეთ ზევიდან სრული ეკრანის დასახურად"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ჩამოასრიალეთ ზევიდან სრული ეკრანის დასახურად."</string> </resources> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 6dace3c4dc37..c04e0d43fb66 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"សូមព្យាយាមម្ដងទៀតនៅពេលក្រោយ។"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"អូសចុះក្រោម ដើម្បីចេញពីការបង្ហាញពេញអេក្រង់"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"អូសពីលើចុះក្រោម ដើម្បីចេញពីការបង្ហាញពេញអេក្រង់។"</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 1a0b2d99c445..9ed05d6d7dfb 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g>초 후에 다시 시도하세요."</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"나중에 다시 시도"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"전체화면을 종료하려면 위에서 아래로 스와이프"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"전체화면을 종료하려면 위에서 아래로 스와이프하세요."</string> </resources> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 88d76e748c7b..66fbefea32a1 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Cuba <xliff:g id="COUNT">%d</xliff:g> saat lagi"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Cuba sebentar lagi"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Leret ke bawah untuk keluar dari skrin penuh"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Leret ke bawah dari atas untuk keluar dari skrin penuh."</string> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 15a6130ee22c..1ea7b9adf807 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Tente novamente em <xliff:g id="COUNT">%d</xliff:g> segundos"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize para baixo para sair da tela inteira"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize de cima para baixo para sair da tela inteira"</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 534808426b19..2e59477f2a55 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Повтор через <xliff:g id="COUNT">%d</xliff:g> сек."</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Повторите попытку позже."</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Чтобы вернуться в обычный режим, проведите пальцем вниз"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Чтобы вернуться в обычный режим, проведите пальцем вниз."</string> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index cd865aa0e802..d47c64f4c0ec 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Skúste to zas o <xliff:g id="COUNT">%d</xliff:g> s"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Skúste to znova neskôr"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celej obraz. ukončíte posunutím nadol"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celej obrazovky ukončíte posunutím nadol."</string> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index b0667587062e..a587950998fc 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Jaribu tena baada ya sekunde <xliff:g id="COUNT">%d</xliff:g>"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Jaribu tena baadaye"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Telezesha kidole kwa kasi chini kuanzia juu ili uondoke kwenye skrini kamili"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Telezesha kidole kwa kasi chini kuanzia juu ili uondoke kwenye skrini kamili."</string> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index bc396ed39060..cf2f78b57c8d 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Subukan muli sa <xliff:g id="COUNT">%d</xliff:g> seg"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Subukang muli sa ibang pagkakataon"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Mag-swipe pababa upang lumabas sa full screen"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Mag-swipe pababa mula sa itaas upang lumabas sa full screen."</string> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 99a137b0756d..9e1bd8b2327d 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> saniye içinde tekrar deneyin"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Daha sonra tekrar deneyin"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Tam ekrandan çıkmak için aşağıya hızlıca kaydırın"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Tam ekrandan çıkmak için yukarıdan aşağıya hızlıca kaydırın."</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 82752b7fdda6..6fe43a05d976 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"Hãy thử lại sau <xliff:g id="COUNT">%d</xliff:g> giây"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Hãy thử lại sau"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Vuốt từ trên xuống để thoát toàn màn hình"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Vuốt từ trên xuống để thoát toàn màn hình."</string> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index dbfd0399965a..05d5c34fc13a 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g>秒后重试"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"稍后重试"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"从顶部向下滑动即可退出全屏模式"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"从顶部向下滑动即可退出全屏模式。"</string> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 2d2e77e98151..e3ca5b934c62 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1649,5 +1649,5 @@ <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> 秒後再試一次"</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string> - <string name="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下滑動即可結束全螢幕。"</string> + <string name="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下快速滑動即可退出全螢幕。"</string> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 9ee8baeb5afb..42e3b50376c8 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2621,6 +2621,9 @@ <!-- Fully qualified class name of an activity that allows the user to manually add printers to this print service. --> <attr name="addPrintersActivity" format="string"/> + <!-- Fully qualified class name of an activity with advanced print options + specific to this print service. --> + <attr name="advancedPrintOptionsActivity" format="string"/> <!-- The vendor name if this print service is vendor specific. --> <attr name="vendor" format="string"/> </declare-styleable> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index aad62520e309..f96195c8cd8d 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -53,7 +53,7 @@ <!-- Minimum size of the fastscroll overlay --> <dimen name="fastscroll_overlay_size">104dp</dimen> <!-- Text size of the fastscroll overlay --> - <dimen name="fastscroll_overlay_text_size">24sp</dimen> + <dimen name="fastscroll_overlay_text_size">52sp</dimen> <!-- Padding of the fastscroll overlay --> <dimen name="fastscroll_overlay_padding">16dp</dimen> <!-- Width of the fastscroll thumb --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 463573375651..81879392c222 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2080,6 +2080,7 @@ <public type="attr" name="accessibilityLiveRegion" id="0x010103ee" /> <public type="attr" name="windowTranslucentStatus" id="0x010103ef" /> <public type="attr" name="windowTranslucentNavigation" id="0x010103f0" /> + <public type="attr" name="advancedPrintOptionsActivity" id="0x10103f1"/> <public type="style" name="Theme.Holo.NoActionBar.TranslucentDecor" id="0x010301e1" /> <public type="style" name="Theme.Holo.Light.NoActionBar.TranslucentDecor" id="0x010301e2" /> diff --git a/docs/html/design/videos/index.jd b/docs/html/design/videos/index.jd index 8ddd4aa6e896..91a784a0b31e 100644 --- a/docs/html/design/videos/index.jd +++ b/docs/html/design/videos/index.jd @@ -1,7 +1,70 @@ page.title=Videos @jd:body -<p>The Android Design Team was pleased to present five fantastic design-oriented sessions at Google I/O 2012. Visit these pages to view the videos and presentations from the conference.</p> +<p>The Android Design Team presents design-oriented sessions at Google I/O every year. Visit these pages to view the videos and presentations from the conferences.</p> + +<img src="{@docRoot}images/home/io-logo-2013-alt.png"> + +<div class="vspace size-2"> </div> + +<div class="layout-content-row"> + <div class="layout-content-col span-7"> + <h3 id="design-for-success"><a href="https://developers.google.com/events/io/2013/sessions/326368573">Enchant, Simplify, Amaze: Android's Design Principles</a></h3> + <p>Want to enchant people, simplify their lives, and make them feel amazing with your app? Learn how Android's Design Principles can help you create products that resonate with people. Find out about the meaning and research behind the principles. See real-world examples and practices from the Android Design team. Discover techniques for applying the principles in your daily work. No design experience necessary.</p> + </div> + <div class="layout-content-col span-6"> + <iframe width="355" height="200" src="//www.youtube.com/embed/s0HIP8EdlnE" frameborder="0" allowfullscreen=""></iframe> + </div> +</div> + +<div class="vspace size-2"> </div> + +<div class="layout-content-row"> + <div class="layout-content-col span-7"> + <h3 id="design-for-success"><a href="https://developers.google.com/events/io/2013/sessions/326301704">Structure in Android App Design</a></h3> + <p>Life is simple when your app is simple. But when your apps gets more complex, how do you choose between spinners, tabs, and drawers for navigation? Members of the Android Design team look at techniques for making your app predictable and pleasing to use.</p> + </div> + <div class="layout-content-col span-6"> + <iframe width="355" height="200" src="//www.youtube.com/embed/XpqyiBR0lJ4" frameborder="0" allowfullscreen=""></iframe> + </div> +</div> + +<div class="vspace size-2"> </div> + +<div class="layout-content-row"> + <div class="layout-content-col span-7"> + <h3 id="design-for-success"><a href="https://developers.google.com/events/io/2013/sessions/326425499">Fireside Chat with the Android Team</a></h3> + <p>Pull up a chair and join the Android platform team for a fireside chat. It's your opportunity to ask us about the platform and learn a little bit more about why things work the way they do, from the people who built it. </p> + </div> + <div class="layout-content-col span-6"> + <iframe width="355" height="200" src="//www.youtube.com/embed/A5OOJDIrYls" frameborder="0" allowfullscreen=""></iframe> + </div> +</div> + +<div class="vspace size-2"> </div> + +<div class="layout-content-row"> + <div class="layout-content-col span-7"> + <h3 id="design-for-success"><a href="https://developers.google.com/events/io/2013/sessions/326483138">Agile UX Research Practice in Android</a></h3> + <p>In the Android UX team, it is critical to get user feedback frequently and consistently so that we are able to iterate and develop the best-in-class designs for our users. We will discuss how the team applied ""Pulse Studies"" (iterative research sessions) in order to put new ideas, designs, and concepts in front of users on a regular basis; it requires minimal advance planning, it can have an immediate product impact, and it can meet urgent needs. </p> + </div> + <div class="layout-content-col span-6"> + <iframe width="355" height="200" src="//www.youtube.com/embed/6MOeVNbh9cY" frameborder="0" allowfullscreen=""></iframe> + </div> +</div> + +<div class="vspace size-2"> </div> + +<div class="layout-content-row"> + <div class="layout-content-col span-7"> + <h3 id="design-for-success"><a href="https://developers.google.com/events/io/2013/sessions/326460111">Cognitive Science and Design</a></h3> + <p>This session will provide an in-depth look at human perception and cognition, and its implications for interactive and visual design. The human brain is purely treated as an information processing machine, and we will teach the audience its attributes, its advantages, its limitations, and generally how to hack it. </p> + </div> + <div class="layout-content-col span-6"> + <iframe width="355" height="200" src="//www.youtube.com/embed/z2exxj4COhU" frameborder="0" allowfullscreen=""></iframe> + </div> +</div> + <img src="{@docRoot}design/media/extras_googleio_12.png"> <div class="vspace size-2"> </div> diff --git a/docs/html/images/home/io-logo-2013-alt.png b/docs/html/images/home/io-logo-2013-alt.png Binary files differnew file mode 100644 index 000000000000..1cdb4f4bec20 --- /dev/null +++ b/docs/html/images/home/io-logo-2013-alt.png diff --git a/docs/html/training/animation/index.jd b/docs/html/training/animation/index.jd index b2815fcce95a..b6940f82221f 100644 --- a/docs/html/training/animation/index.jd +++ b/docs/html/training/animation/index.jd @@ -1,5 +1,5 @@ page.title=Adding Animations -page.tags="animation","views","layout","user interface" +page.tags="Animator","views","layout","user interface" trainingnavtop=true startpage=true diff --git a/docs/html/training/beam-files/index.jd b/docs/html/training/beam-files/index.jd index 71550924a8f8..e4bac2e4577b 100644 --- a/docs/html/training/beam-files/index.jd +++ b/docs/html/training/beam-files/index.jd @@ -1,4 +1,5 @@ page.title=Sharing Files with NFC +page.tags="NfcAdapter","Android Beam","share","file transfer" trainingnavtop=true startpage=true diff --git a/docs/html/training/secure-file-sharing/index.jd b/docs/html/training/secure-file-sharing/index.jd index 19a10428176d..aa009fc2caa5 100644 --- a/docs/html/training/secure-file-sharing/index.jd +++ b/docs/html/training/secure-file-sharing/index.jd @@ -1,4 +1,5 @@ page.title=Sharing Files +page.tags="FileProvider","share","ContentProvider" trainingnavtop=true startpage=true diff --git a/docs/html/training/secure-file-sharing/setup-sharing.jd b/docs/html/training/secure-file-sharing/setup-sharing.jd index d1ab99317ea9..8c8fa0ff6cc1 100644 --- a/docs/html/training/secure-file-sharing/setup-sharing.jd +++ b/docs/html/training/secure-file-sharing/setup-sharing.jd @@ -30,6 +30,14 @@ trainingnavtop=true implementation of {@link android.support.v4.content.FileProvider} to your app, and how to specify the files you want to offer to other apps. </p> + +<p class="note"> + <strong>Note:</strong> The {@link android.support.v4.content.FileProvider} class is part of the + <a href="{@docRoot}tools/support-library/features.html#v4">v4 Support Library</a>. For information + about including this library in your application, see + <a href="{@docRoot}tools/support-library/setup.html">Support Library Setup</a>. +</p> + <h2 id="DefineProvider">Specify the FileProvider</h2> <p> Defining a {@link android.support.v4.content.FileProvider} for your app requires an entry in diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index 7865ec8138de..6dbb3cd1da61 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -812,6 +812,7 @@ public final class RemoteController final OnClientUpdateListener l; synchronized(mInfoLock) { l = mOnClientUpdateListener; + mMetadataEditor = null; } if (l != null) { l.onClientChange(clearing); diff --git a/packages/FusedLocation/res/values-pt-rPT/strings.xml b/packages/FusedLocation/res/values-pt-rPT/strings.xml index 0d2cccc66dc0..2707fa9da7c7 100644 --- a/packages/FusedLocation/res/values-pt-rPT/strings.xml +++ b/packages/FusedLocation/res/values-pt-rPT/strings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_label" msgid="5379477904423203699">"Fused Location"</string> + <string name="app_label" msgid="5379477904423203699">"Localização Fundida"</string> </resources> diff --git a/packages/InputDevices/res/values-ka-rGE/strings.xml b/packages/InputDevices/res/values-ka-rGE/strings.xml index 17ca30240df1..6e507aa33278 100644 --- a/packages/InputDevices/res/values-ka-rGE/strings.xml +++ b/packages/InputDevices/res/values-ka-rGE/strings.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_label" msgid="8016145283189546017">"Input Devices"</string> + <string name="app_label" msgid="8016145283189546017">"შეყვანის მოწყობილობები"</string> <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-ის კლავიატურა"</string> - <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ინგლისური (ბრიტ.)"</string> + <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ინგლისური (გართ. სამ.)"</string> <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ინგლისური (აშშ)"</string> <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ინგლისური (აშშ), საერთაშორისო სტილი"</string> - <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ანგლისური (აშშ), Colemak სტილი"</string> + <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ინგლისური (აშშ), Colemak სტილი"</string> <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ინგლისური (აშშ), Dvorak სტილი"</string> <string name="keyboard_layout_german_label" msgid="8451565865467909999">"გერმანული"</string> <string name="keyboard_layout_french_label" msgid="813450119589383723">"ფრანგული"</string> diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml index 5a80358249e5..a4cbfd7437ad 100644 --- a/packages/InputDevices/res/values-ru/strings.xml +++ b/packages/InputDevices/res/values-ru/strings.xml @@ -5,19 +5,19 @@ <string name="keyboard_layouts_label" msgid="6688773268302087545">"Клавиатура Android"</string> <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"английский (Великобритания)"</string> <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"английский (США)"</string> - <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), International style"</string> - <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), Colemak style"</string> - <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), Dvorak style"</string> + <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"английский (США, международная)"</string> + <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"английский (США, Colemak)"</string> + <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"английский (США, Dvorak)"</string> <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немецкий"</string> <string name="keyboard_layout_french_label" msgid="813450119589383723">"французский"</string> - <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Французский (Канада)"</string> + <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"французский (Канада)"</string> <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"русский"</string> - <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, Mac style"</string> + <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"русский (Mac)"</string> <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"испанский"</string> - <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"швейцарский французский"</string> - <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"швейцарский немецкий"</string> - <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Нидерландский (Бельгия)"</string> - <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Болгарский"</string> + <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"французский (Швейцария)"</string> + <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"немецкий (Швейцария)"</string> + <string name="keyboard_layout_belgian" msgid="2011984572838651558">"нидерландский (Бельгия)"</string> + <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"болгарский"</string> <string name="keyboard_layout_italian" msgid="6497079660449781213">"итальянский"</string> <string name="keyboard_layout_danish" msgid="8036432066627127851">"датский"</string> <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвежский"</string> @@ -28,7 +28,7 @@ <string name="keyboard_layout_estonian" msgid="8775830985185665274">"эстонский"</string> <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"венгерский"</string> <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландский"</string> - <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Португальский (Бразилия)"</string> + <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"португальский (Бразилия)"</string> <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португальский"</string> <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словацкий"</string> <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словенский"</string> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index fdc06a64556a..e94cf18ca709 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -16,10 +16,6 @@ package com.android.keyguard; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState; - import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -55,6 +51,9 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.RemoteViews.OnClickHandler; +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardSecurityModel.SecurityMode; +import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState; import java.io.File; import java.lang.ref.WeakReference; @@ -280,7 +279,7 @@ public class KeyguardHostView extends KeyguardViewBase { if (newState != mTransportState) { mTransportState = newState; if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed"); - KeyguardHostView.this.post(mSwitchPageRunnable); + KeyguardHostView.this.postShowAppropriateWidgetPage(); } } @Override @@ -292,7 +291,7 @@ public class KeyguardHostView extends KeyguardViewBase { if (newState != mTransportState) { mTransportState = newState; if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed"); - KeyguardHostView.this.post(mSwitchPageRunnable); + KeyguardHostView.this.postShowAppropriateWidgetPage(); } } } @@ -496,6 +495,7 @@ public class KeyguardHostView extends KeyguardViewBase { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); + removeCallbacks(mSwitchPageRunnable); mAppWidgetHost.stopListening(); KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks); } @@ -1438,7 +1438,7 @@ public class KeyguardHostView extends KeyguardViewBase { mAppWidgetToShow = ss.appWidgetToShow; setInsets(ss.insets); if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState); - post(mSwitchPageRunnable); + postShowAppropriateWidgetPage(); } @Override @@ -1471,13 +1471,22 @@ public class KeyguardHostView extends KeyguardViewBase { } } - private void showAppropriateWidgetPage() { + void showAppropriateWidgetPage() { int state = mTransportState; ensureTransportPresentOrRemoved(state); + if (mAppWidgetContainer.isLayoutRequested()) { + postShowAppropriateWidgetPage(); + return; + } int pageToShow = getAppropriateWidgetPage(state); mAppWidgetContainer.setCurrentPage(pageToShow); } + void postShowAppropriateWidgetPage() { + removeCallbacks(mSwitchPageRunnable); + post(mSwitchPageRunnable); + } + /** * Examines the current state and adds the transport to the widget pager when the state changes. * diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java index d7c5fe2f0c16..36b2446c6b68 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java @@ -141,6 +141,10 @@ public class KeyguardService extends Service { checkPermission(); mKeyguardViewMediator.launchCamera(); } + public void onBootCompleted() { + checkPermission(); + mKeyguardViewMediator.onBootCompleted(); + } }; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java index b7720ef76f16..a7af6a4c32c6 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java @@ -101,9 +101,7 @@ public class KeyguardTransportControlView extends FrameLayout { new RemoteController.OnClientUpdateListener() { @Override public void onClientChange(boolean clearing) { - if (clearing) { - clearMetadata(); - } + clearMetadata(); } @Override @@ -302,6 +300,7 @@ public class KeyguardTransportControlView extends FrameLayout { mPopulateMetadataWhenAttached = null; } if (DEBUG) Log.v(TAG, "Registering TCV " + this); + mMetadata.clear(); mAudioManager.registerRemoteController(mRemoteController); KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitor); } @@ -321,7 +320,9 @@ public class KeyguardTransportControlView extends FrameLayout { if (DEBUG) Log.v(TAG, "Unregistering TCV " + this); mAudioManager.unregisterRemoteController(mRemoteController); KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitor); + mMetadata.clear(); mUserSeeking = false; + removeCallbacks(mUpdateSeekBars); } void setBadgeIcon(Drawable bmp) { @@ -394,10 +395,10 @@ public class KeyguardTransportControlView extends FrameLayout { Log.e(TAG, "Couldn't get remote control client package icon", e); } setBadgeIcon(badgeIcon); - if (!TextUtils.isEmpty(mMetadata.trackTitle)) { - mTrackTitle.setText(mMetadata.trackTitle); - } - StringBuilder sb = new StringBuilder(); + mTrackTitle.setText(!TextUtils.isEmpty(mMetadata.trackTitle) + ? mMetadata.trackTitle : null); + + final StringBuilder sb = new StringBuilder(); if (!TextUtils.isEmpty(mMetadata.artist)) { if (sb.length() != 0) { sb.append(" - "); @@ -410,7 +411,10 @@ public class KeyguardTransportControlView extends FrameLayout { } sb.append(mMetadata.albumTitle); } - mTrackArtistAlbum.setText(sb.toString()); + + final String trackArtistAlbum = sb.toString(); + mTrackArtistAlbum.setText(!TextUtils.isEmpty(trackArtistAlbum) ? + trackArtistAlbum : null); if (mMetadata.duration >= 0) { setSeekBarsEnabled(true); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 45cd3d4bcd2a..520cea32b013 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -635,15 +635,14 @@ public class KeyguardUpdateMonitor { * PhoneWindowManager in this case. */ protected void dispatchBootCompleted() { - if (!mBootCompleted) { - mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); - } + mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); } /** * Handle {@link #MSG_BOOT_COMPLETED} */ protected void handleBootCompleted() { + if (mBootCompleted) return; mBootCompleted = true; mAudioManager = new AudioManager(mContext); mAudioManager.registerRemoteControlDisplay(mRemoteControlDisplay); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java index a0cad8444ea9..fd7cae66f006 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java @@ -431,17 +431,13 @@ public class KeyguardViewManager { public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) { if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); mScreenOn = true; - final IBinder token; - // If keyguard is disabled, we need to inform PhoneWindowManager with a null + // If keyguard is not showing, we need to inform PhoneWindowManager with a null // token so it doesn't wait for us to draw... - final boolean disabled = - mLockPatternUtils.isLockScreenDisabled() && !mLockPatternUtils.isSecure(); - if (mKeyguardHost == null || disabled) { - token = null; - } else { - token = mKeyguardHost.getWindowToken(); - } + final IBinder token = isShowing() ? mKeyguardHost.getWindowToken() : null; + + if (DEBUG && token == null) Slog.v(TAG, "send wm null token: " + + (mKeyguardHost == null ? "host was null" : "not showing")); if (mKeyguardView != null) { mKeyguardView.onScreenTurnedOn(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java index a37a3a440a7f..b92ae905b028 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java @@ -530,9 +530,6 @@ public class KeyguardViewMediator { mSystemReady = true; mUpdateMonitor.registerCallback(mUpdateCallback); - // Send boot completed message if it hasn't already been sent. - mUpdateMonitor.dispatchBootCompleted(); - // Suppress biometric unlock right after boot until things have settled if it is the // selected security method, otherwise unsuppress it. It must be unsuppressed if it is // not the selected security method for the following reason: if the user starts @@ -1366,4 +1363,8 @@ public class KeyguardViewMediator { Message msg = mHandler.obtainMessage(LAUNCH_CAMERA); mHandler.sendMessage(msg); } + + public void onBootCompleted() { + mUpdateMonitor.dispatchBootCompleted(); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java index 704af6e3aa39..e07e0d077756 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java @@ -40,7 +40,6 @@ import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.TextClock; - import com.android.internal.widget.LockPatternUtils; import java.util.ArrayList; diff --git a/packages/PrintSpooler/res/layout/printer_list_item.xml b/packages/PrintSpooler/res/layout/printer_list_item.xml new file mode 100644 index 000000000000..47eb0b5d768e --- /dev/null +++ b/packages/PrintSpooler/res/layout/printer_list_item.xml @@ -0,0 +1,71 @@ +<?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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:minHeight="?android:attr/listPreferredItemHeight" + android:orientation="horizontal" + android:gravity="start|center_vertical"> + + <ImageView + android:id="@+id/icon" + android:layout_width="32dip" + android:layout_height="32dip" + android:layout_gravity="center_vertical" + android:layout_marginEnd="8dip" + android:duplicateParentState="true" + android:contentDescription="@null" + android:visibility="gone"> + </ImageView> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:duplicateParentState="true"> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceMedium" + android:singleLine="true" + android:ellipsize="end" + android:textIsSelectable="false" + android:gravity="top|start" + android:textColor="@color/item_text_color" + android:duplicateParentState="true"> + </TextView> + + <TextView + android:id="@+id/subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceSmall" + android:singleLine="true" + android:ellipsize="end" + android:textIsSelectable="false" + android:visibility="gone" + android:textColor="@color/print_option_title" + android:duplicateParentState="true"> + </TextView> + + </LinearLayout> + +</LinearLayout> diff --git a/packages/PrintSpooler/res/layout/select_printer_fragment.xml b/packages/PrintSpooler/res/layout/select_printer_fragment.xml new file mode 100644 index 000000000000..bbd012ee77f8 --- /dev/null +++ b/packages/PrintSpooler/res/layout/select_printer_fragment.xml @@ -0,0 +1,26 @@ +<?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. +--> + +<ListView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:paddingStart="@dimen/printer_list_view_padding_start" + android:paddingEnd="@dimen/printer_list_view_padding_end" + android:scrollbarStyle="outsideOverlay" + android:cacheColorHint="@android:color/transparent" + android:scrollbarAlwaysDrawVerticalTrack="true" > +</ListView> diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml index 76666fcdc21e..a6ad391e083a 100644 --- a/packages/PrintSpooler/res/values-af/strings.xml +++ b/packages/PrintSpooler/res/values-af/strings.xml @@ -52,8 +52,8 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Drukkerfout by <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"Drukker het <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> geblokkeer"</string> <plurals name="composite_notification_title_template"> - <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-druktaak"</item> - <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-druktake"</item> + <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-uitdruktaak"</item> + <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-uitdruktake"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Kanselleer"</string> <string name="restart" msgid="2472034227037808749">"Herbegin"</string> diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml index 4071249260d5..3ad5892f9332 100644 --- a/packages/PrintSpooler/res/values-ca/strings.xml +++ b/packages/PrintSpooler/res/values-ca/strings.xml @@ -25,8 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Color"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientació"</string> <string name="label_pages" msgid="6300874667546617333">"Pàgines (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <!-- no translation found for pages_range_example (8558694453556945172) --> - <skip /> + <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Visualització prèvia impressió"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Instal·la un lector de PDF per a visualitz. prèvia"</string> <string name="printing_app_crashed" msgid="854477616686566398">"L\'aplicació d\'impressió ha fallat"</string> @@ -61,8 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"No hi ha connexió amb la impressora"</string> <string name="reason_unknown" msgid="5507940196503246139">"desconegut"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string> - <!-- no translation found for print_error_default_message (8568506918983980567) --> - <skip /> + <string name="print_error_default_message" msgid="8568506918983980567">"No s\'ha pogut generar la tasca d\'impressió"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Blanc i negre"</item> <item msgid="2762241247228983754">"Color"</item> diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml index 549077b26cbb..891ccf21a62d 100644 --- a/packages/PrintSpooler/res/values-es-rUS/strings.xml +++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Color"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string> <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <string name="pages_range_example" msgid="8558694453556945172">"p. ej.: 1–5, 8, 11–13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"Ej.: 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Vista previa de impresión"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar visualizador de PDF para vista previa"</string> <string name="printing_app_crashed" msgid="854477616686566398">"La aplicación de impresión falló"</string> diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml index b5dfb0bacb48..052e06c640d5 100644 --- a/packages/PrintSpooler/res/values-es/strings.xml +++ b/packages/PrintSpooler/res/values-es/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Color"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string> <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <string name="pages_range_example" msgid="8558694453556945172">"p.ej.: 1-5, 8, 11-13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"p. ej.: 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Vista previa de impresión"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar visor PDF para obtener vista previa"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Error de aplicación de impresión"</string> diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml index e07ba075d513..581f2a60090f 100644 --- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml +++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Couleur"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string> <string name="label_pages" msgid="6300874667546617333">"Pages (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <string name="pages_range_example" msgid="8558694453556945172">"p.ex. 1-5, 8, 11-13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string> <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string> diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml index 90048c95cd91..247a21b659c0 100644 --- a/packages/PrintSpooler/res/values-fr/strings.xml +++ b/packages/PrintSpooler/res/values-fr/strings.xml @@ -52,8 +52,8 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression pour \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" bloquée"</string> <plurals name="composite_notification_title_template"> - <item quantity="one" msgid="5866624638054847057">"Tâche d\'impression <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> - <item quantity="other" msgid="8746611264734222865">"Tâches d\'impression <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> + <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tâche d\'impression"</item> + <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tâches d\'impression"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Annuler"</string> <string name="restart" msgid="2472034227037808749">"Redémarrer"</string> diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml index ae29fa4dcc39..a142aa357a24 100644 --- a/packages/PrintSpooler/res/values-in/strings.xml +++ b/packages/PrintSpooler/res/values-in/strings.xml @@ -25,8 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Warna"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string> <string name="label_pages" msgid="6300874667546617333">"(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>) halaman"</string> - <!-- no translation found for pages_range_example (8558694453556945172) --> - <skip /> + <string name="pages_range_example" msgid="8558694453556945172">"misalnya 1—5,8,11—13"</string> <string name="print_preview" msgid="8010217796057763343">"Pratinjau cetak"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Pasang penampil PDF untuk pratinjau"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Aplikasi pencetakan mogok"</string> @@ -61,8 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"Tidak ada sambungan ke printer"</string> <string name="reason_unknown" msgid="5507940196503246139">"tak diketahui"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string> - <!-- no translation found for print_error_default_message (8568506918983980567) --> - <skip /> + <string name="print_error_default_message" msgid="8568506918983980567">"Tidak dapat membuat tugas cetak"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Hitam & Putih"</item> <item msgid="2762241247228983754">"Warna"</item> diff --git a/packages/PrintSpooler/res/values-land/constants.xml b/packages/PrintSpooler/res/values-land/constants.xml new file mode 100644 index 000000000000..d68b77e5ac8b --- /dev/null +++ b/packages/PrintSpooler/res/values-land/constants.xml @@ -0,0 +1,22 @@ +<?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> + + <dimen name="printer_list_view_padding_start">48dip</dimen> + <dimen name="printer_list_view_padding_end">48dip</dimen> + +</resources> diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml index 44ec159c9744..62af20b652c2 100644 --- a/packages/PrintSpooler/res/values-lv/strings.xml +++ b/packages/PrintSpooler/res/values-lv/strings.xml @@ -52,8 +52,8 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Printera kļūda ar darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printeris bloķēja darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <plurals name="composite_notification_title_template"> - <item quantity="one" msgid="5866624638054847057">"Drukas darbs: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> - <item quantity="other" msgid="8746611264734222865">"Drukas darbi: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> + <item quantity="one" msgid="5866624638054847057">"Drukas darbs <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> + <item quantity="other" msgid="8746611264734222865">"Drukas darbi <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Atcelt"</string> <string name="restart" msgid="2472034227037808749">"Restartēt"</string> diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml index 5d19cf32a180..0a64954861ed 100644 --- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml +++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Өнгө"</string> <string name="label_orientation" msgid="2853142581990496477">"Чиглэл"</string> <string name="label_pages" msgid="6300874667546617333">"(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>) хуудас"</string> - <string name="pages_range_example" msgid="8558694453556945172">"жнь. 1–5, 8, 11–13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"ж.нь. 1–5, 8, 11–13"</string> <string name="print_preview" msgid="8010217796057763343">"Хэвлэхээр урьдчилан харах"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Урьдчилан харахын тулд PDF харагчийг суулгах"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Хэвлэгч апп гацсан"</string> diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml index bd205d5057b5..8bf0083de3c8 100644 --- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml +++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml @@ -52,15 +52,15 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Ralat pencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"Pencetak disekat <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <plurals name="composite_notification_title_template"> - <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> kerja cetakan"</item> - <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> kerja cetakan"</item> + <item quantity="one" msgid="5866624638054847057">"Kerja cetakan <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> + <item quantity="other" msgid="8746611264734222865">"Kerja cetakan <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Batal"</string> <string name="restart" msgid="2472034227037808749">"Mulakan semula"</string> <string name="no_connection_to_printer" msgid="2159246915977282728">"Tiada sambungan ke pencetak"</string> <string name="reason_unknown" msgid="5507940196503246139">"tidak diketahui"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string> - <string name="print_error_default_message" msgid="8568506918983980567">"Tidak dapat menjaga kerja cetakan"</string> + <string name="print_error_default_message" msgid="8568506918983980567">"Tidak dapat menjana kerja cetakan"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Hitam & Putih"</item> <item msgid="2762241247228983754">"Warna"</item> diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml index ae0dee2f93b9..577d316b40be 100644 --- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml +++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Cor"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string> <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1—5, 8, 11—13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Pré-visualização de impressão"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar o leitor de PDF para pré-visualização"</string> <string name="printing_app_crashed" msgid="854477616686566398">"A aplicação de impressão bloqueou"</string> @@ -52,8 +52,8 @@ <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"A impressora bloqueou <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <plurals name="composite_notification_title_template"> - <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tarefa de impressão"</item> - <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tarefas de impressão"</item> + <item quantity="one" msgid="5866624638054847057">"Tarefa de impressão: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> + <item quantity="other" msgid="8746611264734222865">"Tarefas de impressão: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Cancelar"</string> <string name="restart" msgid="2472034227037808749">"Reiniciar"</string> diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml index 699de3c3a221..82a8c8ccfd44 100644 --- a/packages/PrintSpooler/res/values-ro/strings.xml +++ b/packages/PrintSpooler/res/values-ro/strings.xml @@ -25,7 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Color"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientare"</string> <string name="label_pages" msgid="6300874667546617333">"Pagini (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <string name="pages_range_example" msgid="8558694453556945172">"de ex.: 1-5, 8, 11-13"</string> + <string name="pages_range_example" msgid="8558694453556945172">"de ex. 1-5, 8, 11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Previzualizați printarea"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Instalați PDF viewer pentru previzualizare"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Aplicația de printare s-a blocat"</string> diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml index dd5ad3be9164..3d4cf6a296f2 100644 --- a/packages/PrintSpooler/res/values-ru/strings.xml +++ b/packages/PrintSpooler/res/values-ru/strings.xml @@ -37,12 +37,12 @@ <string name="search" msgid="5421724265322228497">"Поиск"</string> <string name="all_printers_label" msgid="3178848870161526399">"Все принтеры"</string> <string name="add_print_service_label" msgid="5356702546188981940">"Добавить службу печати"</string> - <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Открыто окно поиска"</string> + <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Окно поиска показано"</string> <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Окно поиска скрыто"</string> <string name="print_add_printer" msgid="1088656468360653455">"Добавить принтер"</string> <plurals name="print_search_result_count_utterance"> <item quantity="one" msgid="4484953260685964252">"Найден <xliff:g id="COUNT">%1$s</xliff:g> принтер"</item> - <item quantity="other" msgid="6533817036607128241">"Найдено несколько принтеров (<xliff:g id="COUNT">%1$s</xliff:g>)"</item> + <item quantity="other" msgid="6533817036607128241">"Найдено принтеров: <xliff:g id="COUNT">%1$s</xliff:g>"</item> </plurals> <string name="choose_print_service" msgid="3740309762324459694">"Выберите службу печати"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Поиск принтеров…"</string> @@ -60,7 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"Нет связи с принтером"</string> <string name="reason_unknown" msgid="5507940196503246139">"неизвестно"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступен"</string> - <string name="print_error_default_message" msgid="8568506918983980567">"Не удалось создать задание печати."</string> + <string name="print_error_default_message" msgid="8568506918983980567">"Не удалось отправить документ на печать."</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Черно-белое"</item> <item msgid="2762241247228983754">"Цветное"</item> diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml index 3176358cdd42..6135a19dcdb9 100644 --- a/packages/PrintSpooler/res/values-sk/strings.xml +++ b/packages/PrintSpooler/res/values-sk/strings.xml @@ -25,8 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Farba"</string> <string name="label_orientation" msgid="2853142581990496477">"Orientácia"</string> <string name="label_pages" msgid="6300874667546617333">"STRÁNKY (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <!-- no translation found for pages_range_example (8558694453556945172) --> - <skip /> + <string name="pages_range_example" msgid="8558694453556945172">"napr. 1–5, 8, 11–13"</string> <string name="print_preview" msgid="8010217796057763343">"Ukážka pred tlačou"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Inštalovať zobrazovač PDF na zobrazenie ukážky"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Aplikácia pre tlač zlyhala"</string> @@ -61,8 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"Žiadne pripojenie k tlačiarni"</string> <string name="reason_unknown" msgid="5507940196503246139">"neznáme"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie je k dispozícii"</string> - <!-- no translation found for print_error_default_message (8568506918983980567) --> - <skip /> + <string name="print_error_default_message" msgid="8568506918983980567">"Tlačovú úlohu nie je možné vytvoriť"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Čiernobiele"</item> <item msgid="2762241247228983754">"Farba"</item> diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml index ee6a47f76de2..a09fa4ca300e 100644 --- a/packages/PrintSpooler/res/values-sr/strings.xml +++ b/packages/PrintSpooler/res/values-sr/strings.xml @@ -53,7 +53,7 @@ <string name="blocked_notification_title_template" msgid="1175435827331588646">"Штампач је блокирао <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <plurals name="composite_notification_title_template"> <item quantity="one" msgid="5866624638054847057">"Задатак штампања <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> - <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> задат(а)ка штампања"</item> + <item quantity="other" msgid="8746611264734222865">"Задаци штампања <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item> </plurals> <string name="cancel" msgid="4373674107267141885">"Откажи"</string> <string name="restart" msgid="2472034227037808749">"Поново покрени"</string> diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml index 62509dbd9bef..b8842e734570 100644 --- a/packages/PrintSpooler/res/values-sw/strings.xml +++ b/packages/PrintSpooler/res/values-sw/strings.xml @@ -60,7 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"Hakuna muunganisho kwa printa"</string> <string name="reason_unknown" msgid="5507940196503246139">"haijulikani"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - haipatikani"</string> - <string name="print_error_default_message" msgid="8568506918983980567">"Haikuweza kuzalisha kazi ya kuchapisha"</string> + <string name="print_error_default_message" msgid="8568506918983980567">"Haikuweza kuunda kazi ya kuchapisha"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Nyeusi na Nyeupe"</item> <item msgid="2762241247228983754">"Rangi"</item> diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml index 5ef653087e02..ab8266610528 100644 --- a/packages/PrintSpooler/res/values-tr/strings.xml +++ b/packages/PrintSpooler/res/values-tr/strings.xml @@ -25,8 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"Renkli"</string> <string name="label_orientation" msgid="2853142581990496477">"Sayfa yönü"</string> <string name="label_pages" msgid="6300874667546617333">"Sayfa (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <!-- no translation found for pages_range_example (8558694453556945172) --> - <skip /> + <string name="pages_range_example" msgid="8558694453556945172">"ör. 1-5,8,11-13"</string> <string name="print_preview" msgid="8010217796057763343">"Yazdırmayı önizle"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"Önizlemek için PDF görüntüleyici yükleyin"</string> <string name="printing_app_crashed" msgid="854477616686566398">"Yazdırma uygulaması kilitlendi"</string> @@ -61,8 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"Yazıcı bağlantısı yok"</string> <string name="reason_unknown" msgid="5507940196503246139">"bilinmiyor"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – kullanılamıyor"</string> - <!-- no translation found for print_error_default_message (8568506918983980567) --> - <skip /> + <string name="print_error_default_message" msgid="8568506918983980567">"Yazdırma işi oluşturulamadı"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"Siyah Beyaz"</item> <item msgid="2762241247228983754">"Renkli"</item> diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml index 5eb640fed439..606baeafa832 100644 --- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml @@ -25,8 +25,7 @@ <string name="label_color" msgid="1108690305218188969">"颜色"</string> <string name="label_orientation" msgid="2853142581990496477">"方向"</string> <string name="label_pages" msgid="6300874667546617333">"页数 (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> - <!-- no translation found for pages_range_example (8558694453556945172) --> - <skip /> + <string name="pages_range_example" msgid="8558694453556945172">"例如:1-5、8、11-13"</string> <string name="print_preview" msgid="8010217796057763343">"打印预览"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"安装 PDF 查看器以便预览"</string> <string name="printing_app_crashed" msgid="854477616686566398">"打印应用崩溃了"</string> @@ -61,8 +60,7 @@ <string name="no_connection_to_printer" msgid="2159246915977282728">"未与打印机建立连接"</string> <string name="reason_unknown" msgid="5507940196503246139">"未知"</string> <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - 无法使用"</string> - <!-- no translation found for print_error_default_message (8568506918983980567) --> - <skip /> + <string name="print_error_default_message" msgid="8568506918983980567">"无法生成打印作业"</string> <string-array name="color_mode_labels"> <item msgid="7602948745415174937">"黑白"</item> <item msgid="2762241247228983754">"彩色"</item> diff --git a/packages/PrintSpooler/res/values/constants.xml b/packages/PrintSpooler/res/values/constants.xml index e5a9d5d2768c..e9c925c0309e 100644 --- a/packages/PrintSpooler/res/values/constants.xml +++ b/packages/PrintSpooler/res/values/constants.xml @@ -26,4 +26,7 @@ <dimen name="print_dialog_frame_max_width_dip">400dip</dimen> -</resources>
\ No newline at end of file + <dimen name="printer_list_view_padding_start">16dip</dimen> + <dimen name="printer_list_view_padding_end">16dip</dimen> + +</resources> diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java index be94ba4c9418..204c15237a2d 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java +++ b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java @@ -22,7 +22,6 @@ import android.app.Dialog; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentTransaction; -import android.app.ListFragment; import android.app.LoaderManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; @@ -47,12 +46,14 @@ import android.printservice.PrintServiceInfo; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Filter; @@ -68,7 +69,7 @@ import java.util.List; /** * This is a fragment for selecting a printer. */ -public final class SelectPrinterFragment extends ListFragment { +public final class SelectPrinterFragment extends Fragment { private static final String LOG_TAG = "SelectPrinterFragment"; @@ -83,6 +84,8 @@ public final class SelectPrinterFragment extends ListFragment { private final ArrayList<PrintServiceInfo> mAddPrinterServices = new ArrayList<PrintServiceInfo>(); + private ListView mListView; + private AnnounceFilterResult mAnnounceFilterResult; public static interface OnPrinterSelectedListener { @@ -97,8 +100,12 @@ public final class SelectPrinterFragment extends ListFragment { } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View content = inflater.inflate(R.layout.select_printer_fragment, container, false); + + // Hook up the list view. + mListView = (ListView) content.findViewById(android.R.id.list); final DestinationAdapter adapter = new DestinationAdapter(); adapter.registerDataSetObserver(new DataSetObserver() { @Override @@ -115,7 +122,23 @@ public final class SelectPrinterFragment extends ListFragment { } } }); - setListAdapter(adapter); + mListView.setAdapter(adapter); + + mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position); + Activity activity = getActivity(); + if (activity instanceof OnPrinterSelectedListener) { + ((OnPrinterSelectedListener) activity).onPrinterSelected(printer.getId()); + } else { + throw new IllegalStateException("the host activity must implement" + + " OnPrinterSelectedListener"); + } + } + }); + + return content; } @Override @@ -133,7 +156,7 @@ public final class SelectPrinterFragment extends ListFragment { @Override public boolean onQueryTextChange(String searchString) { - ((DestinationAdapter) getListAdapter()).getFilter().filter(searchString); + ((DestinationAdapter) mListView.getAdapter()).getFilter().filter(searchString); return true; } }); @@ -177,18 +200,6 @@ public final class SelectPrinterFragment extends ListFragment { } @Override - public void onListItemClick(ListView list, View view, int position, long id) { - PrinterInfo printer = (PrinterInfo) list.getAdapter().getItem(position); - Activity activity = getActivity(); - if (activity instanceof OnPrinterSelectedListener) { - ((OnPrinterSelectedListener) activity).onPrinterSelected(printer.getId()); - } else { - throw new IllegalStateException("the host activity must implement" - + " OnPrinterSelectedListener"); - } - } - - @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_add_printer) { showAddPrinterSelectionDialog(); @@ -260,9 +271,9 @@ public final class SelectPrinterFragment extends ListFragment { } public void updateEmptyView(DestinationAdapter adapter) { - if (getListView().getEmptyView() == null) { + if (mListView.getEmptyView() == null) { View emptyView = getActivity().findViewById(R.id.empty_print_state); - getListView().setEmptyView(emptyView); + mListView.setEmptyView(emptyView); } TextView titleView = (TextView) getActivity().findViewById(R.id.title); View progressBar = getActivity().findViewById(R.id.progress_bar); @@ -450,7 +461,7 @@ public final class SelectPrinterFragment extends ListFragment { public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = getActivity().getLayoutInflater().inflate( - R.layout.printer_dropdown_item, parent, false); + R.layout.printer_list_item, parent, false); } convertView.setEnabled(isEnabled(position)); @@ -539,16 +550,16 @@ public final class SelectPrinterFragment extends ListFragment { public void post() { remove(); - getListView().postDelayed(this, SEARCH_RESULT_ANNOUNCEMENT_DELAY); + mListView.postDelayed(this, SEARCH_RESULT_ANNOUNCEMENT_DELAY); } public void remove() { - getListView().removeCallbacks(this); + mListView.removeCallbacks(this); } @Override public void run() { - final int count = getListView().getAdapter().getCount(); + final int count = mListView.getAdapter().getCount(); final String text; if (count <= 0) { text = getString(R.string.print_no_printers); @@ -556,7 +567,7 @@ public final class SelectPrinterFragment extends ListFragment { text = getActivity().getResources().getQuantityString( R.plurals.print_search_result_count_utterance, count, count); } - getListView().announceForAccessibility(text); + mListView.announceForAccessibility(text); } } } diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 9bf8de8971f0..9d537c5e89e7 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -61,7 +61,7 @@ <string name="usb_debugging_always" msgid="303335496705863070">"Dóna sempre permís des d\'aquest equip"</string> <string name="compat_mode_on" msgid="6623839244840638213">"Zoom per omplir pantalla"</string> <string name="compat_mode_off" msgid="4434467572461327898">"Estira per omplir pant."</string> - <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Desant captura de pantalla..."</string> + <string name="screenshot_saving_ticker" msgid="7403652894056693515">"S\'està desant captura de pantalla..."</string> <string name="screenshot_saving_title" msgid="8242282144535555697">"S\'està desant la captura de pantalla..."</string> <string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla s\'ha desat."</string> <string name="screenshot_saved_title" msgid="6461865960961414961">"S\'ha fet una captura de pantalla."</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index da958bf785a0..8ec75fc912fc 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -22,7 +22,7 @@ <string name="app_label" msgid="7164937344850004466">"सिस्टम UI"</string> <string name="status_bar_clear_all_button" msgid="7774721344716731603">"साफ़ करें"</string> <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"सूची से निकालें"</string> - <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"एप्स जानकारी"</string> + <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ऐप्स जानकारी"</string> <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"कोई हाल ही के एप्स नहीं"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्स खारिज करें"</string> <plurals name="status_bar_accessibility_recent_apps"> @@ -75,7 +75,7 @@ <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string> <string name="accessibility_home" msgid="8217216074895377641">"होम"</string> <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string> - <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के एप्स"</string> + <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के ऐप्स"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"खोजें"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"कैमरा"</string> <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट पद्धति बटन स्विच करें."</string> @@ -146,7 +146,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारिज की गई."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना शेड."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string> - <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"हाल ही के एप्स."</string> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"हाल ही के ऐप्स."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"उपयोगकर्ता <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"मोबाइल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> @@ -166,7 +166,7 @@ <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्थान"</string> <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोध सक्रिय"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string> - <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"एप्स जानकारी"</string> + <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ऐप्स जानकारी"</string> <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वचालित रूप से घूमेगी."</string> <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्क्रीन लैंडस्केप अभिविन्यास में लॉक है."</string> <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्क्रीन पोर्ट्रेट अभिविन्यास में लॉक है."</string> diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 1c43014e54c8..816672f7787c 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -4668,6 +4668,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public void systemBooted() { + if (mKeyguardDelegate != null) { + mKeyguardDelegate.onBootCompleted(); + } synchronized (mLock) { mSystemBooted = true; } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java index 56a282b60577..bf22e2f79085 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java @@ -52,6 +52,7 @@ public class KeyguardServiceDelegate { public int offReason; public int currentUser; public boolean screenIsOn; + public boolean bootCompleted; }; public interface ShowListener { @@ -117,6 +118,9 @@ public class KeyguardServiceDelegate { // This is used to hide the scrim once keyguard displays. mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null)); } + if (mKeyguardState.bootCompleted) { + mKeyguardService.onBootCompleted(); + } } @Override @@ -305,4 +309,11 @@ public class KeyguardServiceDelegate { }); } + public void onBootCompleted() { + if (mKeyguardService != null) { + mKeyguardService.onBootCompleted(); + } + mKeyguardState.bootCompleted = true; + } + } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java index 83be1a801b88..9fb2a504a265 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java @@ -180,6 +180,14 @@ public class KeyguardServiceWrapper implements IKeyguardService { } } + public void onBootCompleted() { + try { + mService.onBootCompleted(); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + public void showAssistant() { // Not used by PhoneWindowManager } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index b5f0697472de..7c61c4400144 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -4467,8 +4467,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { mdst.enableMobileProvisioning(url); } else { if (DBG) log("handleMobileProvisioningAction: on default network"); - Intent newIntent = - new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, + Intent.CATEGORY_APP_BROWSER); + newIntent.setData(Uri.parse(url)); newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); try { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 085f9afd1b83..3ba90981eeed 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -13143,8 +13143,8 @@ public final class ActivityManagerService extends ActivityManagerNative boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( intent.getAction()); if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { - forceStopPackageLocked(ssp, - intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, + forceStopPackageLocked(ssp, UserHandle.getAppId( + intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, false, userId, removed ? "pkg removed" : "pkg changed"); } if (removed) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 26d9bcf58e67..0397fd566645 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -478,37 +478,45 @@ final class ActivityStack { } final int userId = UserHandle.getUserId(info.applicationInfo.uid); + if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); if (task.userId != userId) { // Looking for a different task. + if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": different user"); continue; } final ActivityRecord r = task.getTopActivity(); if (r == null || r.finishing || r.userId != userId || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { + if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": mismatch root " + r); continue; } - //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() - // + "/aff=" + r.task.affinity + " to new cls=" - // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); + if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls=" + + r.task.intent.getComponent().flattenToShortString() + + "/aff=" + r.task.affinity + " to new cls=" + + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); if (task.affinity != null) { if (task.affinity.equals(info.taskAffinity)) { - //Slog.i(TAG, "Found matching affinity!"); + if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!"); return r; } } else if (task.intent != null && task.intent.getComponent().equals(cls)) { - //Slog.i(TAG, "Found matching class!"); + if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); - //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); + if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " + + r.intent); return r; } else if (task.affinityIntent != null && task.affinityIntent.getComponent().equals(cls)) { - //Slog.i(TAG, "Found matching class!"); + if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); - //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); + if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " + + r.intent); return r; + } else if (DEBUG_TASKS) { + Slog.d(TAG, "Not a match: " + task); } } @@ -3575,6 +3583,7 @@ final class ActivityStack { @Override public String toString() { - return "stackId=" + mStackId + " tasks=" + mTaskHistory; + return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this)) + + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}"; } } diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 2895552aede5..523015da0f29 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -1377,12 +1377,23 @@ public final class ActivityStackSupervisor { } final ActivityStack sourceStack; - TaskRecord sourceTask; if (sourceRecord != null) { - sourceTask = sourceRecord.task; - sourceStack = sourceTask.stack; + if (sourceRecord.finishing) { + // If the source is finishing, we can't further count it as our source. This + // is because the task it is associated with may now be empty and on its way out, + // so we don't want to blindly throw it in to that task. Instead we will take + // the NEW_TASK flow and try to find a task for it. + if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { + Slog.w(TAG, "startActivity called from finishing " + sourceRecord + + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); + launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; + } + sourceRecord = null; + sourceStack = null; + } else { + sourceStack = sourceRecord.task.stack; + } } else { - sourceTask = null; sourceStack = null; } @@ -1424,6 +1435,8 @@ public final class ActivityStackSupervisor { } targetStack = intentActivity.task.stack; targetStack.mLastPausedActivity = null; + if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack + + " from " + intentActivity); moveHomeStack(targetStack.isHomeStack()); if (intentActivity.task.intent == null) { // This task was started because of movement of @@ -1663,7 +1676,7 @@ public final class ActivityStackSupervisor { } } } else if (sourceRecord != null) { - sourceTask = sourceRecord.task; + TaskRecord sourceTask = sourceRecord.task; targetStack = sourceTask.stack; moveHomeStack(targetStack.isHomeStack()); if (!addingToTask && @@ -1683,7 +1696,7 @@ public final class ActivityStackSupervisor { targetStack.resumeTopActivityLocked(null); } ActivityOptions.abort(options); - if (r.task == null) Slog.v(TAG, + if (r.task == null) Slog.w(TAG, "startActivityUncheckedLocked: task left null", new RuntimeException("here").fillInStackTrace()); return ActivityManager.START_DELIVERED_TO_TOP; @@ -1712,7 +1725,7 @@ public final class ActivityStackSupervisor { // it. r.setTask(sourceTask, sourceRecord.thumbHolder, false); if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r - + " in existing task " + r.task); + + " in existing task " + r.task + " from source " + sourceRecord); } else { // This not being started from an existing activity, and not part @@ -2060,9 +2073,11 @@ public final class ActivityStackSupervisor { } ActivityRecord findTaskLocked(ActivityRecord r) { + if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); if (!r.isApplicationActivity() && !stack.isHomeStack()) { + if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); continue; } final ActivityRecord ar = stack.findTaskLocked(r); @@ -2070,6 +2085,7 @@ public final class ActivityStackSupervisor { return ar; } } + if (DEBUG_TASKS) Slog.d(TAG, "No task found"); return null; } diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index 1d6970fd4a8c..5e80135ec8e2 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -54,9 +54,9 @@ public final class BroadcastQueue { static final boolean DEBUG_BROADCAST_LIGHT = ActivityManagerService.DEBUG_BROADCAST_LIGHT; static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU; - static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 25; + static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 50; static final int MAX_BROADCAST_SUMMARY_HISTORY - = ActivityManager.isLowRamDeviceStatic() ? 25 : 100; + = ActivityManager.isLowRamDeviceStatic() ? 25 : 300; final ActivityManagerService mService; diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png Binary files differnew file mode 100644 index 000000000000..829378ea9f8f --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_charge_anim100.png diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png Binary files differindex bd44b529ee74..931daeddceb5 100644 --- a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png +++ b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png Binary files differnew file mode 100644 index 000000000000..2773a70691a8 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_charge_anim100.png diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png Binary files differindex c629387c20b8..6e1ac9189e8f 100644 --- a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png +++ b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml index d3c492eacf43..51b474dab97f 100644 --- a/tools/layoutlib/bridge/resources/bars/status_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/status_bar.xml @@ -6,10 +6,12 @@ android:layout_weight="1"/> <ImageView android:layout_height="wrap_content" - android:layout_width="wrap_content"/> + android:layout_width="wrap_content" + android:layout_marginTop="1dp"/> <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" - android:layout_marginLeft="3dip" - android:layout_marginRight="5dip"/> + android:layout_marginLeft="3dp" + android:layout_marginRight="5dp" + android:layout_marginTop="1dp"/> </merge> diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png Binary files differnew file mode 100644 index 000000000000..c7fd7194fafa --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_charge_anim100.png diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..625c61dc4393 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java new file mode 100644 index 000000000000..15cd68789863 --- /dev/null +++ b/tools/layoutlib/bridge/src/android/text/format/Time_Delegate.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.text.format; + +import java.util.Calendar; +import java.util.UnknownFormatConversionException; +import java.util.regex.Pattern; + +import com.android.ide.common.rendering.api.LayoutLog; +import com.android.layoutlib.bridge.Bridge; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +/** + * Delegate used to provide new implementation for native methods of {@link Time} + * + * Through the layoutlib_create tool, some native methods of Time have been replaced by calls to + * methods of the same name in this delegate class. + */ +public class Time_Delegate { + + // Regex to match odd number of '%'. + private static final Pattern p = Pattern.compile("(?<!%)(%%)*%(?!%)"); + + @LayoutlibDelegate + /*package*/ static String format1(Time thisTime, String format) { + + try { + // Change the format by adding changing '%' to "%1$t". This is required to tell the + // formatter which argument to use from the argument list. '%%' is left as is. In the + // replacement string, $0 refers to matched pattern. \\1 means '1', written this way to + // separate it from 0. \\$ means '$', written this way to suppress the special meaning + // of $. + return String.format( + p.matcher(format).replaceAll("$0\\1\\$t"), + timeToCalendar(thisTime, Calendar.getInstance())); + } catch (UnknownFormatConversionException e) { + Bridge.getLog().fidelityWarning(LayoutLog.TAG_STRFTIME, "Unrecognized format", e, format); + return format; + } + } + + private static Calendar timeToCalendar(Time time, Calendar calendar) { + calendar.set(time.year, time.month, time.monthDay, time.hour, time.minute, time.second); + return calendar; + } + +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index baa956d976d0..3692d967e9af 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -45,10 +45,7 @@ public class StatusBar extends CustomBar { // We do know the order though. // 0 is the spacer loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density); - Drawable drawable = loadIcon(2, ResourceType.DRAWABLE, "stat_sys_battery_charge"); - if (drawable instanceof LevelListDrawable) { - ((LevelListDrawable) drawable).setLevel(100); - } + loadIcon(2, "stat_sys_battery_charge_anim100.png", density); } @Override diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java index cd4f82bee925..294d743e8cf9 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java @@ -181,12 +181,18 @@ public class ICU_Delegate { result.longStandAloneMonthNames = result.longMonthNames; result.shortStandAloneMonthNames = result.shortMonthNames; + // The platform code expects this to begin at index 1, rather than 0. It maps it directly to + // the constants from java.util.Calendar.<weekday> result.longWeekdayNames = new String[] { - "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; result.shortWeekdayNames = new String[] { - "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; + "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" }; + result.tinyWeekdayNames = new String[] { + "", "S", "M", "T", "W", "T", "F", "S" }; + result.longStandAloneWeekdayNames = result.longWeekdayNames; result.shortStandAloneWeekdayNames = result.shortWeekdayNames; + result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames; result.fullTimeFormat = ""; result.longTimeFormat = ""; diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath index dbc4cfd392a7..cd8bb0d7d3fb 100644 --- a/tools/layoutlib/create/.classpath +++ b/tools/layoutlib/create/.classpath @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> - <classpathentry excluding="mock_android/" kind="src" path="tests"/> + <classpathentry excluding="mock_data/" kind="src" path="tests"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar"/> + <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar" sourcepath="/ANDROID_PLAT/prebuilts/tools/common/asm-tools/src-4.0.zip"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt index 894611b3e728..72fc9329669b 100644 --- a/tools/layoutlib/create/README.txt +++ b/tools/layoutlib/create/README.txt @@ -71,6 +71,9 @@ class names, for example "android.*.R**" ("*" does not matches dots whilst "**" and "." and "$" are interpreted as-is). In practice we almost but not quite request the inclusion of full packages. +The analyzer is also given a list of classes to exclude. A fake implementation of these +classes is injected by the Generator. + With this information, the analyzer parses the input zip to find all the classes. All classes deriving from the requested bases classes are kept. All classes which name matched the glob pattern are kept. @@ -93,6 +96,7 @@ and lists: - specific methods for which to delegate calls. - specific methods to remove based on their return type. - specific classes to rename. +- specific classes to refactor. Each of these are specific strategies we use to be able to modify the Android code to fit within the Eclipse renderer. These strategies are explained beow. @@ -100,10 +104,7 @@ to fit within the Eclipse renderer. These strategies are explained beow. The core method of the generator is transform(): it takes an input ASM ClassReader and modifies it to produce a byte array suitable for the final JAR file. -The first step of the transformation is changing the name of the class in case -we requested the class to be renamed. This uses the RenameClassAdapter to also rename -all inner classes and references in methods and types. Note that other classes are -not transformed and keep referencing the original name. +The first step of the transformation is to implement the method delegates. The TransformClassAdapter is then used to process the potentially renamed class. All protected or private classes are market as public. @@ -115,11 +116,25 @@ Methods are also changed from protected/private to public. The code of the methods is then kept as-is, except for native methods which are replaced by a stub. Methods that are to be overridden are also replaced by a stub. -The transformed class is then fed through the DelegateClassAdapter to implement -method delegates. - Finally fields are also visited and changed from protected/private to public. +The next step of the transformation is changing the name of the class in case +we requested the class to be renamed. This uses the RenameClassAdapter to also rename +all inner classes and references in methods and types. Note that other classes are +not transformed and keep referencing the original name. + +The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but +updates the references in all classes. This is used to update the references of classes +in the java package that were added in the Dalvik VM but are not a part of the standard +JVM. The existing classes are modified to update all references to these non-standard +classes. An alternate implementation of these (com.android.tools.layoutlib.java.*) is +injected. + +The ClassAdapters are chained together to achieve the desired output. (Look at section +2.2.7 Transformation chains in the asm user guide, link in the References.) The order of +execution of these is: +ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] -> +RefactorClassAdapter -> ClassWriter - Method stubs -------------- @@ -141,19 +156,27 @@ This strategy is now obsolete and replaced by the method delegates. - Strategies ------------ -We currently have 4 strategies to deal with overriding the rendering code +We currently have 6 strategies to deal with overriding the rendering code and make it run in Eclipse. Most of these strategies are implemented hand-in-hand by the bridge (which runs in Eclipse) and the generator. 1- Class Injection -This is the easiest: we currently inject 4 classes, namely: +This is the easiest: we currently inject the following classes: - OverrideMethod and its associated MethodListener and MethodAdapter are used to intercept calls to some specific methods that are stubbed out and change their return value. - CreateInfo class, which configured the generator. Not used yet, but could in theory help us track what the generator changed. +- AutoCloseable is part of Java 7. To enable us to still run on Java 6, a new class is + injected. The implementation for the class has been taken from Android's libcore + (platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java). +- Charsets, IntegralToString and UnsafeByteSequence are not part of the standard JAVA VM. + They are added to the Dalvik VM for performance reasons. An implementation that is very + close to the original (which is at platform/libcore/luni/src/main/java/...) is injected. + Since these classees were in part of the java package, where we can't inject classes, + all references to these have been updated (See strategy 4- Refactoring Classes). 2- Overriding methods @@ -189,7 +212,15 @@ we don't control object creation. This won't rename/replace the inner static methods of a given class. -4- Method erasure based on return type +4- Refactoring classes + +This is very similar to the Renaming classes except that it also updates the reference in +all classes. This is done for classes which are added to the Dalvik VM for performance +reasons but are not present in the Standard Java VM. An implementation for these classes +is also injected. + + +5- Method erasure based on return type This is mostly an implementation detail of the bridge: in the Paint class mentioned above, some inner static classes are used to pass around @@ -201,7 +232,7 @@ example, the inner class Paint$Style in the Paint class should be discarded and bridge will provide its own implementation. -5- Method Delegates +6- Method Delegates This strategy is used to override method implementations. Given a method SomeClass.MethodName(), 1 or 2 methods are generated: @@ -233,7 +264,7 @@ Bytecode opcode list: http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings ASM user guide: - http://download.forge.objectweb.org/asm/asm-guide.pdf + http://download.forge.objectweb.org/asm/asm4-guide.pdf -- diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java new file mode 100644 index 000000000000..b2caa25b9c29 --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.create; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.signature.SignatureReader; +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; + +/** + * Provides the common code for RenameClassAdapter and RefactorClassAdapter. It + * goes through the complete class and finds references to other classes. It + * then calls {@link #renameInternalType(String)} to convert the className to + * the new value, if need be. + */ +public abstract class AbstractClassAdapter extends ClassVisitor { + + /** + * Returns the new FQCN for the class, if the reference to this class needs + * to be updated. Else, it returns the same string. + * @param name Old FQCN + * @return New FQCN if it needs to be renamed, else the old FQCN + */ + abstract String renameInternalType(String name); + + public AbstractClassAdapter(ClassVisitor cv) { + super(Opcodes.ASM4, cv); + } + + /** + * Renames a type descriptor, e.g. "Lcom.package.MyClass;" + * If the type doesn't need to be renamed, returns the input string as-is. + */ + String renameTypeDesc(String desc) { + if (desc == null) { + return null; + } + + return renameType(Type.getType(desc)); + } + + /** + * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an + * object element, e.g. "[Lcom.package.MyClass;" + * If the type doesn't need to be renamed, returns the internal name of the input type. + */ + String renameType(Type type) { + if (type == null) { + return null; + } + + if (type.getSort() == Type.OBJECT) { + String in = type.getInternalName(); + return "L" + renameInternalType(in) + ";"; + } else if (type.getSort() == Type.ARRAY) { + StringBuilder sb = new StringBuilder(); + for (int n = type.getDimensions(); n > 0; n--) { + sb.append('['); + } + sb.append(renameType(type.getElementType())); + return sb.toString(); + } + return type.getDescriptor(); + } + + /** + * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an + * object element, e.g. "[Lcom.package.MyClass;". + * This is like renameType() except that it returns a Type object. + * If the type doesn't need to be renamed, returns the input type object. + */ + Type renameTypeAsType(Type type) { + if (type == null) { + return null; + } + + if (type.getSort() == Type.OBJECT) { + String in = type.getInternalName(); + String newIn = renameInternalType(in); + if (newIn != in) { + return Type.getType("L" + newIn + ";"); + } + } else if (type.getSort() == Type.ARRAY) { + StringBuilder sb = new StringBuilder(); + for (int n = type.getDimensions(); n > 0; n--) { + sb.append('['); + } + sb.append(renameType(type.getElementType())); + return Type.getType(sb.toString()); + } + return type; + } + + /** + * Renames a method descriptor, i.e. applies renameType to all arguments and to the + * return value. + */ + String renameMethodDesc(String desc) { + if (desc == null) { + return null; + } + + Type[] args = Type.getArgumentTypes(desc); + + StringBuilder sb = new StringBuilder("("); + for (Type arg : args) { + String name = renameType(arg); + sb.append(name); + } + sb.append(')'); + + Type ret = Type.getReturnType(desc); + String name = renameType(ret); + sb.append(name); + + return sb.toString(); + } + + + /** + * Renames the ClassSignature handled by ClassVisitor.visit + * or the MethodTypeSignature handled by ClassVisitor.visitMethod. + */ + String renameTypeSignature(String sig) { + if (sig == null) { + return null; + } + SignatureReader reader = new SignatureReader(sig); + SignatureWriter writer = new SignatureWriter(); + reader.accept(new RenameSignatureAdapter(writer)); + sig = writer.toString(); + return sig; + } + + + /** + * Renames the FieldTypeSignature handled by ClassVisitor.visitField + * or MethodVisitor.visitLocalVariable. + */ + String renameFieldSignature(String sig) { + return renameTypeSignature(sig); + } + + + //---------------------------------- + // Methods from the ClassAdapter + + @Override + public void visit(int version, int access, String name, String signature, + String superName, String[] interfaces) { + name = renameInternalType(name); + superName = renameInternalType(superName); + signature = renameTypeSignature(signature); + if (interfaces != null) { + for (int i = 0; i < interfaces.length; ++i) { + interfaces[i] = renameInternalType(interfaces[i]); + } + } + + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + name = renameInternalType(name); + outerName = renameInternalType(outerName); + super.visitInnerClass(name, outerName, innerName, access); + } + + @Override + public void visitOuterClass(String owner, String name, String desc) { + super.visitOuterClass(renameInternalType(owner), name, renameTypeDesc(desc)); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + desc = renameMethodDesc(desc); + signature = renameTypeSignature(signature); + MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions); + return new RenameMethodAdapter(mw); + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + desc = renameTypeDesc(desc); + return super.visitAnnotation(desc, visible); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, + String signature, Object value) { + desc = renameTypeDesc(desc); + return super.visitField(access, name, desc, signature, value); + } + + + //---------------------------------- + + /** + * A method visitor that renames all references from an old class name to a new class name. + */ + public class RenameMethodAdapter extends MethodVisitor { + + /** + * Creates a method visitor that renames all references from a given old name to a given new + * name. The method visitor will also rename all inner classes. + * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). + */ + public RenameMethodAdapter(MethodVisitor mv) { + super(Opcodes.ASM4, mv); + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + desc = renameTypeDesc(desc); + + return super.visitAnnotation(desc, visible); + } + + @Override + public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { + desc = renameTypeDesc(desc); + + return super.visitParameterAnnotation(parameter, desc, visible); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + // The type sometimes turns out to be a type descriptor. We try to detect it and fix. + if (type.indexOf(';') > 0) { + type = renameTypeDesc(type); + } else { + type = renameInternalType(type); + } + super.visitTypeInsn(opcode, type); + } + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + owner = renameInternalType(owner); + desc = renameTypeDesc(desc); + + super.visitFieldInsn(opcode, owner, name, desc); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + // The owner sometimes turns out to be a type descriptor. We try to detect it and fix. + if (owner.indexOf(';') > 0) { + owner = renameTypeDesc(owner); + } else { + owner = renameInternalType(owner); + } + desc = renameMethodDesc(desc); + + super.visitMethodInsn(opcode, owner, name, desc); + } + + @Override + public void visitLdcInsn(Object cst) { + // If cst is a Type, this means the code is trying to pull the .class constant + // for this class, so it needs to be renamed too. + if (cst instanceof Type) { + cst = renameTypeAsType((Type) cst); + } + super.visitLdcInsn(cst); + } + + @Override + public void visitMultiANewArrayInsn(String desc, int dims) { + desc = renameTypeDesc(desc); + + super.visitMultiANewArrayInsn(desc, dims); + } + + @Override + public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { + type = renameInternalType(type); + + super.visitTryCatchBlock(start, end, handler, type); + } + + @Override + public void visitLocalVariable(String name, String desc, String signature, + Label start, Label end, int index) { + desc = renameTypeDesc(desc); + signature = renameFieldSignature(signature); + + super.visitLocalVariable(name, desc, signature, start, end, index); + } + + } + + //---------------------------------- + + public class RenameSignatureAdapter extends SignatureVisitor { + + private final SignatureVisitor mSv; + + public RenameSignatureAdapter(SignatureVisitor sv) { + super(Opcodes.ASM4); + mSv = sv; + } + + @Override + public void visitClassType(String name) { + name = renameInternalType(name); + mSv.visitClassType(name); + } + + @Override + public void visitInnerClassType(String name) { + name = renameInternalType(name); + mSv.visitInnerClassType(name); + } + + @Override + public SignatureVisitor visitArrayType() { + SignatureVisitor sv = mSv.visitArrayType(); + return new RenameSignatureAdapter(sv); + } + + @Override + public void visitBaseType(char descriptor) { + mSv.visitBaseType(descriptor); + } + + @Override + public SignatureVisitor visitClassBound() { + SignatureVisitor sv = mSv.visitClassBound(); + return new RenameSignatureAdapter(sv); + } + + @Override + public void visitEnd() { + mSv.visitEnd(); + } + + @Override + public SignatureVisitor visitExceptionType() { + SignatureVisitor sv = mSv.visitExceptionType(); + return new RenameSignatureAdapter(sv); + } + + @Override + public void visitFormalTypeParameter(String name) { + mSv.visitFormalTypeParameter(name); + } + + @Override + public SignatureVisitor visitInterface() { + SignatureVisitor sv = mSv.visitInterface(); + return new RenameSignatureAdapter(sv); + } + + @Override + public SignatureVisitor visitInterfaceBound() { + SignatureVisitor sv = mSv.visitInterfaceBound(); + return new RenameSignatureAdapter(sv); + } + + @Override + public SignatureVisitor visitParameterType() { + SignatureVisitor sv = mSv.visitParameterType(); + return new RenameSignatureAdapter(sv); + } + + @Override + public SignatureVisitor visitReturnType() { + SignatureVisitor sv = mSv.visitReturnType(); + return new RenameSignatureAdapter(sv); + } + + @Override + public SignatureVisitor visitSuperclass() { + SignatureVisitor sv = mSv.visitSuperclass(); + return new RenameSignatureAdapter(sv); + } + + @Override + public void visitTypeArgument() { + mSv.visitTypeArgument(); + } + + @Override + public SignatureVisitor visitTypeArgument(char wildcard) { + SignatureVisitor sv = mSv.visitTypeArgument(wildcard); + return new RenameSignatureAdapter(sv); + } + + @Override + public void visitTypeVariable(String name) { + mSv.visitTypeVariable(name); + } + + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java index 412695f2661a..1572a4034432 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java @@ -34,6 +34,7 @@ import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.TreeMap; import java.util.regex.Pattern; import java.util.zip.ZipEntry; @@ -57,6 +58,8 @@ public class AsmAnalyzer { private final String[] mDeriveFrom; /** Glob patterns of classes to keep, e.g. "com.foo.*" */ private final String[] mIncludeGlobs; + /** The set of classes to exclude.*/ + private final Set<String> mExcludedClasses; /** * Creates a new analyzer. @@ -69,12 +72,13 @@ public class AsmAnalyzer { * ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is) */ public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen, - String[] deriveFrom, String[] includeGlobs) { + String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses) { mLog = log; mGen = gen; mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>(); mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0]; mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0]; + mExcludedClasses = excludeClasses; } /** @@ -82,9 +86,6 @@ public class AsmAnalyzer { * Fills the generator with classes & dependencies found. */ public void analyze() throws IOException, LogAbortException { - - AsmAnalyzer visitor = this; - Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar); mLog.info("Found %d classes in input JAR%s.", zipClasses.size(), mOsSourceJar.size() > 1 ? "s" : ""); @@ -232,7 +233,7 @@ public class AsmAnalyzer { */ void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses, Map<String, ClassReader> inOutFound) throws LogAbortException { - ClassReader super_clazz = findClass(super_name, zipClasses, inOutFound); + findClass(super_name, zipClasses, inOutFound); for (Entry<String, ClassReader> entry : zipClasses.entrySet()) { String className = entry.getKey(); @@ -363,11 +364,12 @@ public class AsmAnalyzer { className = internalToBinaryClassName(className); - // exclude classes that have already been found + // exclude classes that have already been found or are marked to be excluded if (mInKeep.containsKey(className) || mOutKeep.containsKey(className) || mInDeps.containsKey(className) || - mOutDeps.containsKey(className)) { + mOutDeps.containsKey(className) || + mExcludedClasses.contains(getBaseName(className))) { return; } @@ -451,6 +453,13 @@ public class AsmAnalyzer { } } + private String getBaseName(String className) { + int pos = className.indexOf('$'); + if (pos > 0) { + return className.substring(0, pos); + } + return className; + } // --------------------------------------------------- // --- ClassVisitor, FieldVisitor @@ -682,7 +691,7 @@ public class AsmAnalyzer { } @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { + public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { // pass -- table switch instruction } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java index a9ede265b5d8..b10256127ae8 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java @@ -65,6 +65,9 @@ public class AsmGenerator { /** A map { FQCN => set { method names } } of methods to rewrite as delegates. * The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */ private final HashMap<String, Set<String>> mDelegateMethods; + /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN. + * map old-FQCN => new-FQCN */ + private final HashMap<String, String> mRefactorClasses; /** * Creates a new generator that can generate the output JAR with the stubbed classes. @@ -119,6 +122,17 @@ public class AsmGenerator { mClassesNotRenamed.add(oldFqcn); } + // Create a map of classes to be refactored. + mRefactorClasses = new HashMap<String, String>(); + String[] refactorClasses = createInfo.getJavaPkgClasses(); + n = refactorClasses.length; + for (int i = 0; i < n; i += 2) { + assert i + 1 < n; + String oldFqcn = binaryToInternalClassName(refactorClasses[i]); + String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]); + mRefactorClasses.put(oldFqcn, newFqcn);; + } + // create the map of renamed class -> return type of method to delete. mDeleteReturns = new HashMap<String, Set<String>>(); String[] deleteReturns = createInfo.getDeleteReturns(); @@ -308,14 +322,14 @@ public class AsmGenerator { // original class reader. ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - ClassVisitor rv = cw; + ClassVisitor cv = new RefactorClassAdapter(cw, mRefactorClasses); if (newName != className) { - rv = new RenameClassAdapter(cw, className, newName); + cv = new RenameClassAdapter(cv, className, newName); } - ClassVisitor cv = new TransformClassAdapter(mLog, mStubMethods, + cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), - newName, rv, + newName, cv, stubNativesOnly, stubNativesOnly || hasNativeMethods); Set<String> delegateMethods = mDelegateMethods.get(className); diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index d9550404d48a..7099a4bafab7 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -17,6 +17,10 @@ package com.android.tools.layoutlib.create; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import com.android.tools.layoutlib.java.AutoCloseable; +import com.android.tools.layoutlib.java.Charsets; +import com.android.tools.layoutlib.java.IntegralToString; +import com.android.tools.layoutlib.java.UnsafeByteSequence; /** * Describes the work to be done by {@link AsmGenerator}. @@ -84,6 +88,15 @@ public final class CreateInfo implements ICreateInfo { return DELETE_RETURNS; } + /** + * Returns the list of classes to refactor, must be an even list: the binary FQCN of class to + * replace followed by the new FQCN. All references to the old class should be updated to the + * new class. The list can be empty but must not be null. + */ + @Override + public String[] getJavaPkgClasses() { + return JAVA_PKG_CLASSES; + } //----- /** @@ -95,7 +108,12 @@ public final class CreateInfo implements ICreateInfo { MethodAdapter.class, ICreateInfo.class, CreateInfo.class, - LayoutlibDelegate.class + LayoutlibDelegate.class, + /* Java package classes */ + AutoCloseable.class, + IntegralToString.class, + UnsafeByteSequence.class, + Charsets.class, }; /** @@ -111,6 +129,7 @@ public final class CreateInfo implements ICreateInfo { "android.os.HandlerThread#run", "android.os.Build#getString", "android.text.format.DateFormat#is24HourFormat", + "android.text.format.Time#format1", "android.view.Choreographer#getRefreshRate", "android.view.Display#updateDisplayInfoLocked", "android.view.LayoutInflater#rInflate", @@ -195,6 +214,19 @@ public final class CreateInfo implements ICreateInfo { }; /** + * The list of class references to update, must be an even list: the binary + * FQCN of class to replace followed by the new FQCN. The classes to + * replace are to be excluded from the output. + */ + private final static String[] JAVA_PKG_CLASSES = + new String[] { + "java.lang.AutoCloseable", "com.android.tools.layoutlib.java.AutoCloseable", + "java.nio.charset.Charsets", "com.android.tools.layoutlib.java.Charsets", + "java.lang.IntegralToString", "com.android.tools.layoutlib.java.IntegralToString", + "java.lang.UnsafeByteSequence", "com.android.tools.layoutlib.java.UnsafeByteSequence", + }; + + /** * List of classes for which the methods returning them should be deleted. * The array contains a list of null terminated section starting with the name of the class * to rename in which the methods are deleted, followed by a list of return types identifying diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java index 40c1706d9ed0..9387814ec204 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java @@ -62,4 +62,11 @@ public interface ICreateInfo { */ public abstract String[] getDeleteReturns(); + /** + * Returns the list of classes to refactor, must be an even list: the + * binary FQCN of class to replace followed by the new FQCN. All references + * to the old class should be updated to the new class. + * The list can be empty but must not be null. + */ + public abstract String[] getJavaPkgClasses(); } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java index 9cd74db3445b..ba23048aee7b 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java @@ -18,6 +18,7 @@ package com.android.tools.layoutlib.create; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -86,7 +87,9 @@ public class Main { } try { - AsmGenerator agen = new AsmGenerator(log, osDestJar, new CreateInfo()); + CreateInfo info = new CreateInfo(); + Set<String> excludeClasses = getExcludedClasses(info); + AsmGenerator agen = new AsmGenerator(log, osDestJar, info); AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen, new String[] { // derived from @@ -110,7 +113,8 @@ public class Main { "android.pim.*", // for datepicker "android.os.*", // for android.os.Handler "android.database.ContentObserver", // for Digital clock - }); + }, + excludeClasses); aa.analyze(); agen.generate(); @@ -146,6 +150,16 @@ public class Main { return 1; } + private static Set<String> getExcludedClasses(CreateInfo info) { + String[] refactoredClasses = info.getJavaPkgClasses(); + Set<String> excludedClasses = new HashSet<String>(refactoredClasses.length); + for (int i = 0; i < refactoredClasses.length; i+=2) { + excludedClasses.add(refactoredClasses[i]); + } + return excludedClasses; + + } + private static int listDeps(ArrayList<String> osJarPath, Log log) { DependencyFinder df = new DependencyFinder(log); try { diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java new file mode 100644 index 000000000000..91161f573b33 --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.create; + +import java.util.HashMap; + +import org.objectweb.asm.ClassVisitor; + +public class RefactorClassAdapter extends AbstractClassAdapter { + + private final HashMap<String, String> mRefactorClasses; + + RefactorClassAdapter(ClassVisitor cv, HashMap<String, String> refactorClasses) { + super(cv); + mRefactorClasses = refactorClasses; + } + + @Override + protected String renameInternalType(String oldClassName) { + if (oldClassName != null) { + String newName = mRefactorClasses.get(oldClassName); + if (newName != null) { + return newName; + } + int pos = oldClassName.indexOf('$'); + if (pos > 0) { + newName = mRefactorClasses.get(oldClassName.substring(0, pos)); + if (newName != null) { + return newName + oldClassName.substring(pos); + } + } + } + return oldClassName; + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java index 383cbb8e3373..661074c7327a 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java @@ -16,17 +16,7 @@ package com.android.tools.layoutlib.create; -import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.objectweb.asm.signature.SignatureWriter; /** * This class visitor renames a class from a given old name to a given new name. @@ -36,7 +26,7 @@ import org.objectweb.asm.signature.SignatureWriter; * For inner classes, this handles only the case where the outer class name changes. * The inner class name should remain the same. */ -public class RenameClassAdapter extends ClassVisitor { +public class RenameClassAdapter extends AbstractClassAdapter { private final String mOldName; @@ -49,8 +39,8 @@ public class RenameClassAdapter extends ClassVisitor { * The class visitor will also rename all inner classes and references in the methods. * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). */ - public RenameClassAdapter(ClassWriter cv, String oldName, String newName) { - super(Opcodes.ASM4, cv); + public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) { + super(cv); mOldBase = mOldName = oldName; mNewBase = mNewName = newName; @@ -66,71 +56,6 @@ public class RenameClassAdapter extends ClassVisitor { assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null); } - - /** - * Renames a type descriptor, e.g. "Lcom.package.MyClass;" - * If the type doesn't need to be renamed, returns the input string as-is. - */ - String renameTypeDesc(String desc) { - if (desc == null) { - return null; - } - - return renameType(Type.getType(desc)); - } - - /** - * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an - * object element, e.g. "[Lcom.package.MyClass;" - * If the type doesn't need to be renamed, returns the internal name of the input type. - */ - String renameType(Type type) { - if (type == null) { - return null; - } - - if (type.getSort() == Type.OBJECT) { - String in = type.getInternalName(); - return "L" + renameInternalType(in) + ";"; - } else if (type.getSort() == Type.ARRAY) { - StringBuilder sb = new StringBuilder(); - for (int n = type.getDimensions(); n > 0; n--) { - sb.append('['); - } - sb.append(renameType(type.getElementType())); - return sb.toString(); - } - return type.getDescriptor(); - } - - /** - * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an - * object element, e.g. "[Lcom.package.MyClass;". - * This is like renameType() except that it returns a Type object. - * If the type doesn't need to be renamed, returns the input type object. - */ - Type renameTypeAsType(Type type) { - if (type == null) { - return null; - } - - if (type.getSort() == Type.OBJECT) { - String in = type.getInternalName(); - String newIn = renameInternalType(in); - if (newIn != in) { - return Type.getType("L" + newIn + ";"); - } - } else if (type.getSort() == Type.ARRAY) { - StringBuilder sb = new StringBuilder(); - for (int n = type.getDimensions(); n > 0; n--) { - sb.append('['); - } - sb.append(renameType(type.getElementType())); - return Type.getType(sb.toString()); - } - return type; - } - /** * Renames an internal type name, e.g. "com.package.MyClass". * If the type doesn't need to be renamed, returns the input string as-is. @@ -138,7 +63,8 @@ public class RenameClassAdapter extends ClassVisitor { * The internal type of some of the MethodVisitor turns out to be a type descriptor sometimes so descriptors are renamed too. */ - String renameInternalType(String type) { + @Override + protected String renameInternalType(String type) { if (type == null) { return null; } @@ -155,309 +81,7 @@ public class RenameClassAdapter extends ClassVisitor { if (pos == mOldBase.length() && type.startsWith(mOldBase)) { return mNewBase + type.substring(pos); } - - // The internal type of some of the MethodVisitor turns out to be a type - // descriptor sometimes. This is the case with visitTypeInsn(type) and - // visitMethodInsn(owner). We try to detect it and adjust it here. - if (type.indexOf(';') > 0) { - type = renameTypeDesc(type); - } - return type; } - /** - * Renames a method descriptor, i.e. applies renameType to all arguments and to the - * return value. - */ - String renameMethodDesc(String desc) { - if (desc == null) { - return null; - } - - Type[] args = Type.getArgumentTypes(desc); - - StringBuilder sb = new StringBuilder("("); - for (Type arg : args) { - String name = renameType(arg); - sb.append(name); - } - sb.append(')'); - - Type ret = Type.getReturnType(desc); - String name = renameType(ret); - sb.append(name); - - return sb.toString(); - } - - - /** - * Renames the ClassSignature handled by ClassVisitor.visit - * or the MethodTypeSignature handled by ClassVisitor.visitMethod. - */ - String renameTypeSignature(String sig) { - if (sig == null) { - return null; - } - SignatureReader reader = new SignatureReader(sig); - SignatureWriter writer = new SignatureWriter(); - reader.accept(new RenameSignatureAdapter(writer)); - sig = writer.toString(); - return sig; - } - - - /** - * Renames the FieldTypeSignature handled by ClassVisitor.visitField - * or MethodVisitor.visitLocalVariable. - */ - String renameFieldSignature(String sig) { - if (sig == null) { - return null; - } - SignatureReader reader = new SignatureReader(sig); - SignatureWriter writer = new SignatureWriter(); - reader.acceptType(new RenameSignatureAdapter(writer)); - sig = writer.toString(); - return sig; - } - - - //---------------------------------- - // Methods from the ClassAdapter - - @Override - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - name = renameInternalType(name); - superName = renameInternalType(superName); - signature = renameTypeSignature(signature); - - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - assert outerName.equals(mOldName); - outerName = renameInternalType(outerName); - name = outerName + "$" + innerName; - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - desc = renameMethodDesc(desc); - signature = renameTypeSignature(signature); - MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions); - return new RenameMethodAdapter(mw); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - desc = renameTypeDesc(desc); - return super.visitAnnotation(desc, visible); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - desc = renameTypeDesc(desc); - signature = renameFieldSignature(signature); - return super.visitField(access, name, desc, signature, value); - } - - - //---------------------------------- - - /** - * A method visitor that renames all references from an old class name to a new class name. - */ - public class RenameMethodAdapter extends MethodVisitor { - - /** - * Creates a method visitor that renames all references from a given old name to a given new - * name. The method visitor will also rename all inner classes. - * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass). - */ - public RenameMethodAdapter(MethodVisitor mv) { - super(Opcodes.ASM4, mv); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - desc = renameTypeDesc(desc); - - return super.visitAnnotation(desc, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { - desc = renameTypeDesc(desc); - - return super.visitParameterAnnotation(parameter, desc, visible); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - type = renameInternalType(type); - - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - owner = renameInternalType(owner); - desc = renameTypeDesc(desc); - - super.visitFieldInsn(opcode, owner, name, desc); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - owner = renameInternalType(owner); - desc = renameMethodDesc(desc); - - super.visitMethodInsn(opcode, owner, name, desc); - } - - @Override - public void visitLdcInsn(Object cst) { - // If cst is a Type, this means the code is trying to pull the .class constant - // for this class, so it needs to be renamed too. - if (cst instanceof Type) { - cst = renameTypeAsType((Type) cst); - } - super.visitLdcInsn(cst); - } - - @Override - public void visitMultiANewArrayInsn(String desc, int dims) { - desc = renameTypeDesc(desc); - - super.visitMultiANewArrayInsn(desc, dims); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - type = renameInternalType(type); - - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public void visitLocalVariable(String name, String desc, String signature, - Label start, Label end, int index) { - desc = renameTypeDesc(desc); - signature = renameFieldSignature(signature); - - super.visitLocalVariable(name, desc, signature, start, end, index); - } - - } - - //---------------------------------- - - public class RenameSignatureAdapter extends SignatureVisitor { - - private final SignatureVisitor mSv; - - public RenameSignatureAdapter(SignatureVisitor sv) { - super(Opcodes.ASM4); - mSv = sv; - } - - @Override - public void visitClassType(String name) { - name = renameInternalType(name); - mSv.visitClassType(name); - } - - @Override - public void visitInnerClassType(String name) { - name = renameInternalType(name); - mSv.visitInnerClassType(name); - } - - @Override - public SignatureVisitor visitArrayType() { - SignatureVisitor sv = mSv.visitArrayType(); - return new RenameSignatureAdapter(sv); - } - - @Override - public void visitBaseType(char descriptor) { - mSv.visitBaseType(descriptor); - } - - @Override - public SignatureVisitor visitClassBound() { - SignatureVisitor sv = mSv.visitClassBound(); - return new RenameSignatureAdapter(sv); - } - - @Override - public void visitEnd() { - mSv.visitEnd(); - } - - @Override - public SignatureVisitor visitExceptionType() { - SignatureVisitor sv = mSv.visitExceptionType(); - return new RenameSignatureAdapter(sv); - } - - @Override - public void visitFormalTypeParameter(String name) { - mSv.visitFormalTypeParameter(name); - } - - @Override - public SignatureVisitor visitInterface() { - SignatureVisitor sv = mSv.visitInterface(); - return new RenameSignatureAdapter(sv); - } - - @Override - public SignatureVisitor visitInterfaceBound() { - SignatureVisitor sv = mSv.visitInterfaceBound(); - return new RenameSignatureAdapter(sv); - } - - @Override - public SignatureVisitor visitParameterType() { - SignatureVisitor sv = mSv.visitParameterType(); - return new RenameSignatureAdapter(sv); - } - - @Override - public SignatureVisitor visitReturnType() { - SignatureVisitor sv = mSv.visitReturnType(); - return new RenameSignatureAdapter(sv); - } - - @Override - public SignatureVisitor visitSuperclass() { - SignatureVisitor sv = mSv.visitSuperclass(); - return new RenameSignatureAdapter(sv); - } - - @Override - public void visitTypeArgument() { - mSv.visitTypeArgument(); - } - - @Override - public SignatureVisitor visitTypeArgument(char wildcard) { - SignatureVisitor sv = mSv.visitTypeArgument(wildcard); - return new RenameSignatureAdapter(sv); - } - - @Override - public void visitTypeVariable(String name) { - mSv.visitTypeVariable(name); - } - - } } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java new file mode 100644 index 000000000000..ed2c128e1900 --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.java; + +/** + * Defines the same interface as the java.lang.AutoCloseable which was added in + * Java 7. This hack makes it possible to run the Android code which uses Java 7 + * features (API 18 and beyond) to run on Java 6. + * <p/> + * Extracted from API level 18, file: + * platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java + */ +public interface AutoCloseable { + /** + * Closes the object and release any system resources it holds. + */ + void close() throws Exception; } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java new file mode 100644 index 000000000000..f73b06b5ffba --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.java; + +import java.nio.CharBuffer; +import java.nio.charset.Charset; + +/** + * Defines the same class as the java.nio.charset.Charsets which was added in + * Dalvik VM. This hack, provides a replacement for that class which can't be + * loaded in the standard JVM since it's in the java package and standard JVM + * doesn't have it. An implementation of the native methods in the original + * class has been added. + * <p/> + * Extracted from API level 18, file: + * platform/libcore/luni/src/main/java/java/nio/charset/Charsets + */ +public final class Charsets { + /** + * A cheap and type-safe constant for the ISO-8859-1 Charset. + */ + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + + /** + * A cheap and type-safe constant for the US-ASCII Charset. + */ + public static final Charset US_ASCII = Charset.forName("US-ASCII"); + + /** + * A cheap and type-safe constant for the UTF-8 Charset. + */ + public static final Charset UTF_8 = Charset.forName("UTF-8"); + + /** + * Returns a new byte array containing the bytes corresponding to the given characters, + * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'. + */ + public static byte[] toAsciiBytes(char[] chars, int offset, int length) { + CharBuffer cb = CharBuffer.allocate(length); + cb.put(chars, offset, length); + return US_ASCII.encode(cb).array(); + } + + /** + * Returns a new byte array containing the bytes corresponding to the given characters, + * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'. + */ + public static byte[] toIsoLatin1Bytes(char[] chars, int offset, int length) { + CharBuffer cb = CharBuffer.allocate(length); + cb.put(chars, offset, length); + return ISO_8859_1.encode(cb).array(); + } + + /** + * Returns a new byte array containing the bytes corresponding to the given characters, + * encoded in UTF-8. All characters are representable in UTF-8. + */ + public static byte[] toUtf8Bytes(char[] chars, int offset, int length) { + CharBuffer cb = CharBuffer.allocate(length); + cb.put(chars, offset, length); + return UTF_8.encode(cb).array(); + } + + /** + * Returns a new byte array containing the bytes corresponding to the given characters, + * encoded in UTF-16BE. All characters are representable in UTF-16BE. + */ + public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) { + byte[] result = new byte[length * 2]; + int end = offset + length; + int resultIndex = 0; + for (int i = offset; i < end; ++i) { + char ch = chars[i]; + result[resultIndex++] = (byte) (ch >> 8); + result[resultIndex++] = (byte) ch; + } + return result; + } + + /** + * Decodes the given US-ASCII bytes into the given char[]. Equivalent to but faster than: + * + * for (int i = 0; i < count; ++i) { + * char ch = (char) (data[start++] & 0xff); + * value[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR; + * } + */ + public static void asciiBytesToChars(byte[] bytes, int offset, int length, char[] chars) { + if (bytes == null || chars == null) { + return; + } + final char REPLACEMENT_CHAR = (char)0xffd; + int start = offset; + for (int i = 0; i < length; ++i) { + char ch = (char) (bytes[start++] & 0xff); + chars[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR; + } + } + + /** + * Decodes the given ISO-8859-1 bytes into the given char[]. Equivalent to but faster than: + * + * for (int i = 0; i < count; ++i) { + * value[i] = (char) (data[start++] & 0xff); + * } + */ + public static void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars) { + if (bytes == null || chars == null) { + return; + } + int start = offset; + for (int i = 0; i < length; ++i) { + chars[i] = (char) (bytes[start++] & 0xff); + } + } + + private Charsets() { + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java new file mode 100644 index 000000000000..e6dd00a76f52 --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.java; + +/** + * Defines the same class as the java.lang.IntegralToString which was added in + * Dalvik VM. This hack, provides a replacement for that class which can't be + * loaded in the standard JVM since it's in the java package and standard JVM + * doesn't have it. Since it's no longer in java.lang, access to package + * private methods and classes has been replaced by the closes matching public + * implementation. + * <p/> + * Extracted from API level 18, file: + * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java + */ +public final class IntegralToString { + /** + * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid + * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder + * because it's almost as expensive to work out the exact length of the result as it is to + * do the formatting. We could try being conservative and "delete"-ing the unused space + * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share + * the code.) + */ + private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() { + @Override protected char[] initialValue() { + return new char[20]; // Maximum length of a base-10 long. + } + }; + + /** + * These tables are used to special-case toString computation for + * small values. This serves three purposes: it reduces memory usage; + * it increases performance for small values; and it decreases the + * number of comparisons required to do the length computation. + * Elements of this table are lazily initialized on first use. + * No locking is necessary, i.e., we use the non-volatile, racy + * single-check idiom. + */ + private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100]; + private static final String[] SMALL_NEGATIVE_VALUES = new String[100]; + + /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */ + private static final char[] TENS = { + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', + '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', + '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', + '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', + '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', + '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', + '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', + '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', + '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', + '9', '9', '9', '9', '9', '9', '9', '9', '9', '9' + }; + + /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */ + private static final char[] ONES = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + }; + + /** + * Table for MOD / DIV 10 computation described in Section 10-21 + * of Hank Warren's "Hacker's Delight" online addendum. + * http://www.hackersdelight.org/divcMore.pdf + */ + private static final char[] MOD_10_TABLE = { + 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0 + }; + + /** + * The digits for every supported radix. + */ + private static final char[] DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z' + }; + + private static final char[] UPPER_CASE_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z' + }; + + private IntegralToString() { + } + + /** + * Equivalent to Integer.toString(i, radix). + */ + public static String intToString(int i, int radix) { + if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { + radix = 10; + } + if (radix == 10) { + return intToString(i); + } + + /* + * If i is positive, negate it. This is the opposite of what one might + * expect. It is necessary because the range of the negative values is + * strictly larger than that of the positive values: there is no + * positive value corresponding to Integer.MIN_VALUE. + */ + boolean negative = false; + if (i < 0) { + negative = true; + } else { + i = -i; + } + + int bufLen = radix < 8 ? 33 : 12; // Max chars in result (conservative) + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + int q = i / radix; + buf[--cursor] = DIGITS[radix * q - i]; + i = q; + } while (i != 0); + + if (negative) { + buf[--cursor] = '-'; + } + + return new String(buf, cursor, bufLen - cursor); + } + + /** + * Equivalent to Integer.toString(i). + */ + public static String intToString(int i) { + return convertInt(null, i); + } + + /** + * Equivalent to sb.append(Integer.toString(i)). + */ + public static void appendInt(StringBuilder sb, int i) { + convertInt(sb, i); + } + + /** + * Returns the string representation of i and leaves sb alone if sb is null. + * Returns null and appends the string representation of i to sb if sb is non-null. + */ + private static String convertInt(StringBuilder sb, int i) { + boolean negative = false; + String quickResult = null; + if (i < 0) { + negative = true; + i = -i; + if (i < 100) { + if (i < 0) { + // If -n is still negative, n is Integer.MIN_VALUE + quickResult = "-2147483648"; + } else { + quickResult = SMALL_NEGATIVE_VALUES[i]; + if (quickResult == null) { + SMALL_NEGATIVE_VALUES[i] = quickResult = + i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]); + } + } + } + } else { + if (i < 100) { + quickResult = SMALL_NONNEGATIVE_VALUES[i]; + if (quickResult == null) { + SMALL_NONNEGATIVE_VALUES[i] = quickResult = + i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]); + } + } + } + if (quickResult != null) { + if (sb != null) { + sb.append(quickResult); + return null; + } + return quickResult; + } + + int bufLen = 11; // Max number of chars in result + char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; + int cursor = bufLen; + + // Calculate digits two-at-a-time till remaining digits fit in 16 bits + while (i >= (1 << 16)) { + // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8 + int q = (int) ((0x51EB851FL * i) >>> 37); + int r = i - 100*q; + buf[--cursor] = ONES[r]; + buf[--cursor] = TENS[r]; + i = q; + } + + // Calculate remaining digits one-at-a-time for performance + while (i != 0) { + // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8 + int q = (0xCCCD * i) >>> 19; + int r = i - 10*q; + buf[--cursor] = DIGITS[r]; + i = q; + } + + if (negative) { + buf[--cursor] = '-'; + } + + if (sb != null) { + sb.append(buf, cursor, bufLen - cursor); + return null; + } else { + return new String(buf, cursor, bufLen - cursor); + } + } + + /** + * Equivalent to Long.toString(v, radix). + */ + public static String longToString(long v, int radix) { + int i = (int) v; + if (i == v) { + return intToString(i, radix); + } + + if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { + radix = 10; + } + if (radix == 10) { + return longToString(v); + } + + /* + * If v is positive, negate it. This is the opposite of what one might + * expect. It is necessary because the range of the negative values is + * strictly larger than that of the positive values: there is no + * positive value corresponding to Integer.MIN_VALUE. + */ + boolean negative = false; + if (v < 0) { + negative = true; + } else { + v = -v; + } + + int bufLen = radix < 8 ? 65 : 23; // Max chars in result (conservative) + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + long q = v / radix; + buf[--cursor] = DIGITS[(int) (radix * q - v)]; + v = q; + } while (v != 0); + + if (negative) { + buf[--cursor] = '-'; + } + + return new String(buf, cursor, bufLen - cursor); + } + + /** + * Equivalent to Long.toString(l). + */ + public static String longToString(long l) { + return convertLong(null, l); + } + + /** + * Equivalent to sb.append(Long.toString(l)). + */ + public static void appendLong(StringBuilder sb, long l) { + convertLong(sb, l); + } + + /** + * Returns the string representation of n and leaves sb alone if sb is null. + * Returns null and appends the string representation of n to sb if sb is non-null. + */ + private static String convertLong(StringBuilder sb, long n) { + int i = (int) n; + if (i == n) { + return convertInt(sb, i); + } + + boolean negative = (n < 0); + if (negative) { + n = -n; + if (n < 0) { + // If -n is still negative, n is Long.MIN_VALUE + String quickResult = "-9223372036854775808"; + if (sb != null) { + sb.append(quickResult); + return null; + } + return quickResult; + } + } + + int bufLen = 20; // Maximum number of chars in result + char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; + + int low = (int) (n % 1000000000); // Extract low-order 9 digits + int cursor = intIntoCharArray(buf, bufLen, low); + + // Zero-pad Low order part to 9 digits + while (cursor != (bufLen - 9)) { + buf[--cursor] = '0'; + } + + /* + * The remaining digits are (n - low) / 1,000,000,000. This + * "exact division" is done as per the online addendum to Hank Warren's + * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf + */ + n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL; + + /* + * If the remaining digits fit in an int, emit them using a + * single call to intIntoCharArray. Otherwise, strip off the + * low-order digit, put it in buf, and then call intIntoCharArray + * on the remaining digits (which now fit in an int). + */ + if ((n & (-1L << 32)) == 0) { + cursor = intIntoCharArray(buf, cursor, (int) n); + } else { + /* + * Set midDigit to n % 10 + */ + int lo32 = (int) n; + int hi32 = (int) (n >>> 32); + + // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21 + int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28]; + + // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2) + midDigit -= hi32 << 2; // 1L << 32 == -4 MOD 10 + if (midDigit < 0) { + midDigit += 10; + } + buf[--cursor] = DIGITS[midDigit]; + + // Exact division as per Warren 10-20 + int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD; + cursor = intIntoCharArray(buf, cursor, rest); + } + + if (negative) { + buf[--cursor] = '-'; + } + if (sb != null) { + sb.append(buf, cursor, bufLen - cursor); + return null; + } else { + return new String(buf, cursor, bufLen - cursor); + } + } + + /** + * Inserts the unsigned decimal integer represented by n into the specified + * character array starting at position cursor. Returns the index after + * the last character inserted (i.e., the value to pass in as cursor the + * next time this method is called). Note that n is interpreted as a large + * positive integer (not a negative integer) if its sign bit is set. + */ + private static int intIntoCharArray(char[] buf, int cursor, int n) { + // Calculate digits two-at-a-time till remaining digits fit in 16 bits + while ((n & 0xffff0000) != 0) { + /* + * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8. + * This computation is slightly different from the corresponding + * computation in intToString: the shifts before and after + * multiply can't be combined, as that would yield the wrong result + * if n's sign bit were set. + */ + int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35); + int r = n - 100*q; + buf[--cursor] = ONES[r]; + buf[--cursor] = TENS[r]; + n = q; + } + + // Calculate remaining digits one-at-a-time for performance + while (n != 0) { + // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8 + int q = (0xCCCD * n) >>> 19; + int r = n - 10*q; + buf[--cursor] = DIGITS[r]; + n = q; + } + return cursor; + } + + public static String intToBinaryString(int i) { + int bufLen = 32; // Max number of binary digits in an int + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[i & 1]; + } while ((i >>>= 1) != 0); + + return new String(buf, cursor, bufLen - cursor); + } + + public static String longToBinaryString(long v) { + int i = (int) v; + if (v >= 0 && i == v) { + return intToBinaryString(i); + } + + int bufLen = 64; // Max number of binary digits in a long + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[((int) v) & 1]; + } while ((v >>>= 1) != 0); + + return new String(buf, cursor, bufLen - cursor); + } + + public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; + sb.append(digits[(b >> 4) & 0xf]); + sb.append(digits[b & 0xf]); + return sb; + } + + public static String byteToHexString(byte b, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; + char[] buf = new char[2]; // We always want two digits. + buf[0] = digits[(b >> 4) & 0xf]; + buf[1] = digits[b & 0xf]; + return new String(buf, 0, 2); + } + + public static String bytesToHexString(byte[] bytes, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; + char[] buf = new char[bytes.length * 2]; + int c = 0; + for (byte b : bytes) { + buf[c++] = digits[(b >> 4) & 0xf]; + buf[c++] = digits[b & 0xf]; + } + return new String(buf); + } + + public static String intToHexString(int i, boolean upperCase, int minWidth) { + int bufLen = 8; // Max number of hex digits in an int + char[] buf = new char[bufLen]; + int cursor = bufLen; + + char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; + do { + buf[--cursor] = digits[i & 0xf]; + } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth)); + + return new String(buf, cursor, bufLen - cursor); + } + + public static String longToHexString(long v) { + int i = (int) v; + if (v >= 0 && i == v) { + return intToHexString(i, false, 0); + } + + int bufLen = 16; // Max number of hex digits in a long + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[((int) v) & 0xF]; + } while ((v >>>= 4) != 0); + + return new String(buf, cursor, bufLen - cursor); + } + + public static String intToOctalString(int i) { + int bufLen = 11; // Max number of octal digits in an int + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[i & 7]; + } while ((i >>>= 3) != 0); + + return new String(buf, cursor, bufLen - cursor); + } + + public static String longToOctalString(long v) { + int i = (int) v; + if (v >= 0 && i == v) { + return intToOctalString(i); + } + int bufLen = 22; // Max number of octal digits in a long + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[((int) v) & 7]; + } while ((v >>>= 3) != 0); + + return new String(buf, cursor, bufLen - cursor); + } + + private static String stringOf(char... args) { + return new String(args, 0, args.length); + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java new file mode 100644 index 000000000000..0e09080c5111 --- /dev/null +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.layoutlib.java; + +import java.nio.charset.Charset; + +/** + * Defines the same class as the java.lang.UnsafeByteSequence which was added in + * Dalvik VM. This hack, provides a replacement for that class which can't be + * loaded in the standard JVM since it's in the java package and standard JVM + * doesn't have it. + * <p/> + * Extracted from API level 18, file: + * platform/libcore/luni/src/main/java/java/lang/UnsafeByteSequence.java + */ +public class UnsafeByteSequence { + private byte[] bytes; + private int count; + + public UnsafeByteSequence(int initialCapacity) { + this.bytes = new byte[initialCapacity]; + } + + public int size() { + return count; + } + + /** + * Moves the write pointer back to the beginning of the sequence, + * but without resizing or reallocating the buffer. + */ + public void rewind() { + count = 0; + } + + public void write(byte[] buffer, int offset, int length) { + if (count + length >= bytes.length) { + byte[] newBytes = new byte[(count + length) * 2]; + System.arraycopy(bytes, 0, newBytes, 0, count); + bytes = newBytes; + } + System.arraycopy(buffer, offset, bytes, count, length); + count += length; + } + + public void write(int b) { + if (count == bytes.length) { + byte[] newBytes = new byte[count * 2]; + System.arraycopy(bytes, 0, newBytes, 0, count); + bytes = newBytes; + } + bytes[count++] = (byte) b; + } + + public byte[] toByteArray() { + if (count == bytes.length) { + return bytes; + } + byte[] result = new byte[count]; + System.arraycopy(bytes, 0, result, 0, count); + return result; + } + + public String toString(Charset cs) { + return new String(bytes, 0, count, cs); + } +} diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java index d6dba6a9fb34..005fc9dadab4 100644 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java +++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java @@ -31,7 +31,9 @@ import org.objectweb.asm.ClassReader; import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.TreeMap; /** @@ -51,8 +53,10 @@ public class AsmAnalyzerTest { mOsJarPath = new ArrayList<String>(); mOsJarPath.add(url.getFile()); + Set<String> excludeClasses = new HashSet<String>(1); + excludeClasses.add("java.lang.JavaClass"); mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, - null /* deriveFrom */, null /* includeGlobs */ ); + null /* deriveFrom */, null /* includeGlobs */, excludeClasses); } @After @@ -64,6 +68,7 @@ public class AsmAnalyzerTest { Map<String, ClassReader> map = mAa.parseZip(mOsJarPath); assertArrayEquals(new String[] { + "java.lang.JavaClass", "mock_android.dummy.InnerTest", "mock_android.dummy.InnerTest$DerivingClass", "mock_android.dummy.InnerTest$MyGenerics1", @@ -221,7 +226,11 @@ public class AsmAnalyzerTest { for (ClassReader cr2 : in_deps.values()) { cr2.accept(visitor, 0 /* flags */); } + keep.putAll(new_keep); assertArrayEquals(new String[] { }, out_deps.keySet().toArray()); + assertArrayEquals(new String[] { + "mock_android.widget.TableLayout", + }, keep.keySet().toArray()); } } diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java index 7b76a5b2f914..8a27173181a3 100644 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java +++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java @@ -19,16 +19,29 @@ package com.android.tools.layoutlib.create; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /** * Unit tests for some methods of {@link AsmGenerator}. @@ -40,6 +53,9 @@ public class AsmGeneratorTest { private String mOsDestJar; private File mTempFile; + // ASM internal name for the the class in java package that should be refactored. + private static final String JAVA_CLASS_NAME = "java/lang/JavaClass"; + @Before public void setUp() throws Exception { mLog = new MockLog(); @@ -48,7 +64,7 @@ public class AsmGeneratorTest { mOsJarPath = new ArrayList<String>(); mOsJarPath.add(url.getFile()); - mTempFile = File.createTempFile("mock", "jar"); + mTempFile = File.createTempFile("mock", ".jar"); mOsDestJar = mTempFile.getAbsolutePath(); mTempFile.deleteOnExit(); } @@ -97,6 +113,11 @@ public class AsmGeneratorTest { } @Override + public String[] getJavaPkgClasses() { + return new String[0]; + } + + @Override public String[] getDeleteReturns() { // methods deleted from their return type. return new String[0]; @@ -109,11 +130,201 @@ public class AsmGeneratorTest { null, // derived from new String[] { // include classes "**" - }); + }, + new HashSet<String>(0) /* excluded classes */); aa.analyze(); agen.generate(); Set<String> notRenamed = agen.getClassesNotRenamed(); assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray()); + + } + + @Test + public void testClassRefactoring() throws IOException, LogAbortException { + ICreateInfo ci = new ICreateInfo() { + @Override + public Class<?>[] getInjectedClasses() { + // classes to inject in the final JAR + return new Class<?>[] { + com.android.tools.layoutlib.create.dataclass.JavaClass.class + }; + } + + @Override + public String[] getDelegateMethods() { + return new String[0]; + } + + @Override + public String[] getDelegateClassNatives() { + return new String[0]; + } + + @Override + public String[] getOverriddenMethods() { + // methods to force override + return new String[0]; + } + + @Override + public String[] getRenamedClasses() { + // classes to rename (so that we can replace them) + return new String[0]; + } + + @Override + public String[] getJavaPkgClasses() { + // classes to refactor (so that we can replace them) + return new String[] { + "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass", + }; + } + + @Override + public String[] getDeleteReturns() { + // methods deleted from their return type. + return new String[0]; + } + }; + + AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci); + + AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen, + null, // derived from + new String[] { // include classes + "**" + }, + new HashSet<String>(1)); + aa.analyze(); + agen.generate(); + Map<String, ClassReader> output = parseZip(mOsDestJar); + boolean injectedClassFound = false; + for (ClassReader cr: output.values()) { + TestClassVisitor cv = new TestClassVisitor(); + cr.accept(cv, 0); + injectedClassFound |= cv.mInjectedClassFound; + } + assertTrue(injectedClassFound); + } + + private Map<String,ClassReader> parseZip(String jarPath) throws IOException { + TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>(); + + ZipFile zip = new ZipFile(jarPath); + Enumeration<? extends ZipEntry> entries = zip.entries(); + ZipEntry entry; + while (entries.hasMoreElements()) { + entry = entries.nextElement(); + if (entry.getName().endsWith(".class")) { + ClassReader cr = new ClassReader(zip.getInputStream(entry)); + String className = classReaderToClassName(cr); + classes.put(className, cr); + } + } + + return classes; + } + + private String classReaderToClassName(ClassReader classReader) { + if (classReader == null) { + return null; + } else { + return classReader.getClassName().replace('/', '.'); + } + } + + private class TestClassVisitor extends ClassVisitor { + + boolean mInjectedClassFound = false; + + TestClassVisitor() { + super(Opcodes.ASM4); + } + + @Override + public void visit(int version, int access, String name, String signature, + String superName, String[] interfaces) { + assertTrue(!getBase(name).equals(JAVA_CLASS_NAME)); + if (name.equals("com/android/tools/layoutlib/create/dataclass/JavaClass")) { + mInjectedClassFound = true; + } + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, + String signature, Object value) { + assertTrue(testType(Type.getType(desc))); + return super.visitField(access, name, desc, signature, value); + } + + @SuppressWarnings("hiding") + @Override + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); + return new MethodVisitor(Opcodes.ASM4, mv) { + + @Override + public void visitFieldInsn(int opcode, String owner, String name, + String desc) { + assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME)); + assertTrue(testType(Type.getType(desc))); + super.visitFieldInsn(opcode, owner, name, desc); + } + + @Override + public void visitLdcInsn(Object cst) { + if (cst instanceof Type) { + assertTrue(testType((Type)cst)); + } + super.visitLdcInsn(cst); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + assertTrue(!getBase(type).equals(JAVA_CLASS_NAME)); + super.visitTypeInsn(opcode, type); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, + String desc) { + assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME)); + assertTrue(testType(Type.getType(desc))); + super.visitMethodInsn(opcode, owner, name, desc); + } + + }; + } + + private boolean testType(Type type) { + int sort = type.getSort(); + if (sort == Type.OBJECT) { + assertTrue(!getBase(type.getInternalName()).equals(JAVA_CLASS_NAME)); + } else if (sort == Type.ARRAY) { + assertTrue(!getBase(type.getElementType().getInternalName()) + .equals(JAVA_CLASS_NAME)); + } else if (sort == Type.METHOD) { + boolean r = true; + for (Type t : type.getArgumentTypes()) { + r &= testType(t); + } + return r & testType(type.getReturnType()); + } + return true; + } + + private String getBase(String className) { + if (className == null) { + return null; + } + int pos = className.indexOf('$'); + if (pos > 0) { + return className.substring(0, pos); + } + return className; + } } } diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java index 90c6a9c9ac7c..6211e73417e4 100644 --- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java +++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java @@ -24,7 +24,7 @@ import org.junit.Before; import org.junit.Test; /** - * + * */ public class RenameClassAdapterTest { @@ -36,10 +36,10 @@ public class RenameClassAdapterTest { mOuter = new RenameClassAdapter(null, // cv "com.pack.Old", "org.blah.New"); - + mInner = new RenameClassAdapter(null, // cv "com.pack.Old$Inner", - "org.blah.New$Inner"); + "org.blah.New$Inner"); } @After @@ -72,7 +72,7 @@ public class RenameClassAdapterTest { // arrays assertEquals("[Lorg.blah.New;", mOuter.renameTypeDesc("[Lcom.pack.Old;")); assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;")); - + assertEquals("[Lorg.blah.New;", mInner.renameTypeDesc("[Lcom.pack.Old;")); assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;")); } @@ -93,10 +93,6 @@ public class RenameClassAdapterTest { */ @Test public void testRenameInternalType() { - // a descriptor is not left untouched - assertEquals("Lorg.blah.New;", mOuter.renameInternalType("Lcom.pack.Old;")); - assertEquals("Lorg.blah.New$Inner;", mOuter.renameInternalType("Lcom.pack.Old$Inner;")); - // an actual FQCN assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old")); assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner")); @@ -115,6 +111,6 @@ public class RenameClassAdapterTest { mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;")); } - + } diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java new file mode 100644 index 000000000000..9b5a91886b84 --- /dev/null +++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.tools.layoutlib.create.dataclass; + +public final class JavaClass { + + public static final String test = "test"; +} diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar Binary files differindex a7ea74f4adf2..60d8efb1bb99 100644 --- a/tools/layoutlib/create/tests/data/mock_android.jar +++ b/tools/layoutlib/create/tests/data/mock_android.jar diff --git a/tools/layoutlib/create/tests/data/mock_android.jardesc b/tools/layoutlib/create/tests/data/mock_android.jardesc deleted file mode 100644 index 95f7591d7046..000000000000 --- a/tools/layoutlib/create/tests/data/mock_android.jardesc +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?> -<jardesc> - <jar path="C:/ralf/google/src/raphael-lapdroid/device/tools/layoutlib/create/tests/data/mock_android.jar"/> - <options buildIfNeeded="true" compress="true" descriptionLocation="/layoutlib_create/tests/data/mock_android.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/> - <storedRefactorings deprecationInfo="true" structuralOnly="false"/> - <selectedProjects/> - <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true"> - <sealing sealJar="false"> - <packagesToSeal/> - <packagesToUnSeal/> - </sealing> - </manifest> - <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false"> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.widget"/> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.view"/> - <javaElement handleIdentifier="=layoutlib_create/tests<mock_android.dummy"/> - </selectedElements> -</jardesc> diff --git a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java new file mode 100644 index 000000000000..59612e95d354 --- /dev/null +++ b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 java.lang; + +public class JavaClass { + + public static String test = "test"; +} diff --git a/tools/layoutlib/create/tests/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java index e355ead16a7d..d3a1d05b98fd 100644 --- a/tools/layoutlib/create/tests/mock_android/dummy/InnerTest.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java @@ -19,6 +19,7 @@ package mock_android.dummy; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.List; public class InnerTest { @@ -66,13 +67,13 @@ public class InnerTest { } } - public <X> void genericMethod1(X a, X[] a) { + public <X> void genericMethod1(X a, X[] b) { } public <X, Y> void genericMethod2(X a, List<Y> b) { } - public <X, Y> void genericMethod3(X a, List<Y extends InnerTest> b) { + public <X, Y extends InnerTest> void genericMethod3(X a, List<Y> b) { } public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) { @@ -85,6 +86,6 @@ public class InnerTest { mInnerInstance = m; mTheIntEnum = null; mGeneric1 = new MyGenerics1(); - genericMethod(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>()); + genericMethod4(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>()); } } diff --git a/tools/layoutlib/create/tests/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java index a80a98daf1d4..84ec8a9d9094 100644 --- a/tools/layoutlib/create/tests/mock_android/view/View.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java @@ -16,6 +16,10 @@ package mock_android.view; +import java.lang.JavaClass; + public class View { + String x = JavaClass.test; + } diff --git a/tools/layoutlib/create/tests/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java index 466470fc1537..466470fc1537 100644 --- a/tools/layoutlib/create/tests/mock_android/view/ViewGroup.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java diff --git a/tools/layoutlib/create/tests/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java index 3870a63d9782..3870a63d9782 100644 --- a/tools/layoutlib/create/tests/mock_android/widget/LinearLayout.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java diff --git a/tools/layoutlib/create/tests/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java index e455e7d61fd3..e455e7d61fd3 100644 --- a/tools/layoutlib/create/tests/mock_android/widget/TableLayout.java +++ b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java |