From 62bcd64f30a82147fe3cea6ef440c57b9535acd8 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 17 Jan 2023 22:59:35 +0000 Subject: [PATCH 1/4] Revert "Remove samples for deprecated Android Beam API" Revert submission 20750504-nfc-beam-cleanup Reason for revert: Droidfood blocking bug: 265628639 Reverted changes: /q/submissionid:20750504-nfc-beam-cleanup Change-Id: I52227544aa152471ab3186eb21dd3a3f0e7cc193 (cherry picked from commit 8de7b4b1663791704a17020d21c04bb21e5d785c) Merged-In: I52227544aa152471ab3186eb21dd3a3f0e7cc193 --- samples/AndroidBeamDemo/Android.bp | 13 + samples/AndroidBeamDemo/AndroidManifest.xml | 42 ++++ samples/AndroidBeamDemo/_index.html | 3 + .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 5365 bytes .../res/drawable-hdpi/ic_menu_preferences.png | Bin 0 -> 1851 bytes .../res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2475 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2470 bytes .../res/drawable-mdpi/ic_menu_preferences.png | Bin 0 -> 1142 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 5506 bytes .../drawable-xhdpi/ic_menu_preferences.png | Bin 0 -> 2507 bytes samples/AndroidBeamDemo/res/layout/main.xml | 27 ++ samples/AndroidBeamDemo/res/menu/options.xml | 7 + .../AndroidBeamDemo/res/values/strings.xml | 9 + .../src/com/example/android/beam/Beam.java | 163 ++++++++++++ samples/ApiDemos/AndroidManifest.xml | 7 + .../android/apis/nfc/ForegroundNdefPush.java | 55 ++++ .../BeamLargeFiles/AndroidManifest.xml | 55 ++++ samples/browseable/BeamLargeFiles/_index.jd | 17 ++ .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4199 bytes .../res/drawable-hdpi/tile.9.png | Bin 0 -> 196 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2535 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 6022 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 11040 bytes .../res/layout-sw600dp-land/activity_main.xml | 42 ++++ .../res/layout-sw600dp/activity_main.xml | 40 +++ .../res/layout/activity_main.xml | 43 ++++ .../BeamLargeFiles/res/menu/main.xml | 18 ++ .../res/values-sw600dp/template-dimens.xml | 24 ++ .../res/values-sw600dp/template-styles.xml | 25 ++ .../res/values-v11/template-styles.xml | 22 ++ .../res/values-v21/base-colors.xml | 21 ++ .../res/values-v21/base-template-styles.xml | 24 ++ .../res/values/base-strings.xml | 36 +++ .../res/values/template-dimens.xml | 32 +++ .../res/values/template-styles.xml | 54 ++++ .../BeamLargeFilesFragment.java | 98 ++++++++ .../MainActivity.java | 83 ++++++ .../activities/SampleActivityBase.java | 52 ++++ .../assetprovider/AssetProvider.java | 140 +++++++++++ .../logger/Log.java | 236 ++++++++++++++++++ .../logger/LogFragment.java | 109 ++++++++ .../logger/LogNode.java | 39 +++ .../logger/LogView.java | 145 +++++++++++ .../logger/LogWrapper.java | 75 ++++++ .../logger/MessageOnlyLogFilter.java | 60 +++++ 45 files changed, 1816 insertions(+) create mode 100644 samples/AndroidBeamDemo/Android.bp create mode 100644 samples/AndroidBeamDemo/AndroidManifest.xml create mode 100755 samples/AndroidBeamDemo/_index.html create mode 100644 samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-hdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-xhdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/layout/main.xml create mode 100644 samples/AndroidBeamDemo/res/menu/options.xml create mode 100644 samples/AndroidBeamDemo/res/values/strings.xml create mode 100644 samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java create mode 100644 samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java create mode 100644 samples/browseable/BeamLargeFiles/AndroidManifest.xml create mode 100644 samples/browseable/BeamLargeFiles/_index.jd create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-mdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-xhdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/layout/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/menu/main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v21/base-colors.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v21/base-template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/base-strings.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/template-dimens.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java diff --git a/samples/AndroidBeamDemo/Android.bp b/samples/AndroidBeamDemo/Android.bp new file mode 100644 index 000000000..fdc2748b0 --- /dev/null +++ b/samples/AndroidBeamDemo/Android.bp @@ -0,0 +1,13 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test { + name: "AndroidBeamDemo", + // Only compile source java files in this apk. + srcs: ["src/**/*.java"], + sdk_version: "current", + dex_preopt: { + enabled: false, + }, +} diff --git a/samples/AndroidBeamDemo/AndroidManifest.xml b/samples/AndroidBeamDemo/AndroidManifest.xml new file mode 100644 index 000000000..f4c06d936 --- /dev/null +++ b/samples/AndroidBeamDemo/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/samples/AndroidBeamDemo/_index.html b/samples/AndroidBeamDemo/_index.html new file mode 100755 index 000000000..9fe80b08a --- /dev/null +++ b/samples/AndroidBeamDemo/_index.html @@ -0,0 +1,3 @@ +

Android Beam Demo shows how to use the Android Beam feature introduced in API level 14. This +application beams a simple message from one device to another when they are in close enough proximity. This +application must be installed on two devices that have NFC capabilities, running Android 4.0 or later.

diff --git a/samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c96fa9e05ff294e321cceacfa0446862152300b5 GIT binary patch literal 5365 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 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ab4d45e7870f4ab304dcd91fe8586aa01c199310 GIT binary patch literal 2475 zcmbVOc{r478z1{lQIXJVoFvQ4yknW=m@qS@;e=_ZqtY^FUJPb2Gj_*1Dsd7mlCMHJ z9i?<~ND`9DT#76uku}mHOIecT8fgKF|F;_wRS_*Y&2*+_z|`>Z`(F zFbx+fnJ!&{rB_)|`V~e+eUvV1Mb6$LPoAGBoFRZ}FXYeW65yk^s^I{eMS%Zm>xOdU zlb`@LHA(<^M!9=2qk@|{(5^x|91Bl=RbA|W_0{javUbTxw0g z^25`~lyA1A5&<3{67lg!WO#TuBHS9m6Zj)R91gd{fkshVGGqjUj|34YB!{yU*B5P}hz|Y7 zjUQ?Yy(0M#k`4)Zp#r9~9)2dvU}^6D+0c@r)Em5qfGsTwBbdx%hH@aT$c0RROK%V? zHVcmeu_zG4*q|_IlpPiXu^5noB@&&SD9$!mv@L0w<40H=$v3>r;Y#=3BYA_kWUE!$;F?S8`&{}GEP2_S}uC-CC&f|omh7QhqngaJH0 zK=QN&+!#zYcS&9<&(~2&AKNav)y~22<#CAv<|RJTLk+ZtHQ#V6hVU zAmm`ZhwbsCAuUHoVM$)Wfr?3zhU&@MRo1PKPRwpOIcOdjRJs$@zALrhB=`7pp0-}T zgvH!ov2~@46IMZMlC03D=@HvC8Tp>@QeE>sWZ$XQbbIteOm)wz5A!i`_L+D4;`OFy zKKjlbsM|8sI@;GM-yZ&`;6A1DCR6F`jcG(`*7$Ku?flHgv5+)hM~v=pL0(S;?L)@q zm)Qo_*v~5}9`Ev5bptXz(xCl!w;nA>u0PbI7}u%sH-C@c@K}$@HVv|E zt=x{FXv~LRN*$XJTZ#L57PNceBfljD#Re;7%Gx(5A6>a=A*gQsExAnn#j7eZ-DnwJ zPJ%G3CQcQVap+lE%@Dh0)#dA^0y88JN%nn%XUYBA`ZGV9ylm?&>vzvhJ)k!#ms5L6_a&&uPb8*Ieq8kTigg*E z&Z{IA?QY7Ng8Oiv0;t>+D(sBUI&22Zk~S6VYVG&^^$dR41- zcR@qFjePzU&c>-xf91^iC_&zPIE^+#D<|kh4drlJsSuqRK>4mRt|43%a5RM{xLJ$w2(n`(aQvl$7kZ|YffY#eWzmpKq` zOdLzPXp~2daS8YK&J(qmA!dg0{3l6(OSh##!lg^98@sBi4!3j_Z+Uer_imG6msNUv z4XDj7=0wPp=(Ve9uOBFqD=3(B4fWjlK&vG_h+w2%{!2vIX##I=X^ZZH&d~YJ35x|R z`;Iq7BUF#D7I5W^EaqaUNot<-HO)#H0c=EwHqY{|BSUeYmZH5x_WHdmPm3A#h7n|y zi)I2|U+wBShVS?%=Myc3+}GGt6-n+SnYfLwUX!VrT*$uTieIf*jqgq?xXZ;*UMmk|l{6pH3`e&GS_%HxW6RWaxd8?r^1ZmD<6zwL z5!d(O>vvTB9JsC9zY!m(hs3g2eV|OX$&E%d z$x@M=yWk*sEZJ+0(A!#lL@*ca{^GU5D7il6F`~qb6QiK=Da%49ur4vB4V$Ae7-`;l z?_T)MPUhfv(CzpB)G zyZULz@5@hQKMaq8_Gp#7)gC(e+5UEY?Nn^CoLtJE`+_r}4Nk+Gwl+x8KBX;ULuPIK zXZBPHT08g^=^d>*z4HrCooQUx)!Jy$p%K=!W5KRFWKzrX_1?hJ43AyE(+?}vdYtbo zDpk`>eai=^>E*GyxTxUao~kv?`c}2Zpt`|L_~-1M({Eo`4|9moWf>c3hG;HuwHYx}t7MW^>Fs24|chf4_;3a?fd z_rA%tuJ4a-{_v&?kzM)rNKNh3okGdS-hRu9-*@*vh?7-^IWJ5&1yZMEmVTdHoZZP+ IiTe}(4YN-YS^xk5 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..20796846713ab7c4b6efe08f108986969bc0c05c GIT binary patch literal 2470 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 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png b/samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc50e66ee7e9812e4117d18150ad3cd575cb48d GIT binary patch literal 1142 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~H|ou`Xqh{y4#A+b4=LnZ3&eXfmvd8^knnmajp zwXv%2Nuv!d=N4S^G~w2`$g{&h$54r-*Ui`9qDv3cL<{4K6^-{K_8PR!R#iK^Q({G) z!L*$(I9wux6IVwr+;R5S)vb5G&z(1&d$+v8g_m5ZK1x5#bzk0^`0urxR$=whB zJz=ekXUqn_WlG66Kc_ZlMs8td7HiyS_vg#>cTp#OSPTSxCD*Rpx41*}?Exi&Q?Iwx zJzQt%yQ#C|%_LQ(tesQm94ZOqHk-jzX|gXOTwgaaxufsNc6BeKNXA1Vla8`@FjZ!3 zS$4C*mBnSHec!<~Mai2!JUPd-!QGhEm(ORn|OR!_DA53IQaBy*Ck zHMh%i%C6iIUzqqvvW-)t?NF?hLc`6M2D4WkersyYvN=gBhP`A}+LNh_krBFu(V0y7 zLJ{io?Y9_5-CnfUtT_MA6r~^qhTe$xuBrPc9E*8*wAz8Gi}7J-|GTW5@@o%_D-&!A zg{Dh?oAYg_4yT&)p6Qk4cQkz+{+Onf9-OmX;Y6Fv^pLc}z6<%jt63dh8*I-v#dX55 zS)M6Vxo0V~{;B&NXMf^g+s3u~(mD3OEVkF%d1W5=&cp4m=Lr_xGyQy(^*>_5St74T0_kJ8tFr&%XGiqQ|YE)tI62z%KW^o02v$uiTecDSymlii)+dg!8ETLU-W43EUJizgCZoUfJ3ntc80yOi&i=_zSVd+u!7 z{jeih)o$whBkR70@~ZkYi?D`DwRkhE(s1PN4!Qg)e{w*4aJha}3-@h#4%xLgJOsC< z7X8S%nYpA+U8(z^^XF;8HsbnL3>iEOXREfp&nkBPapRSlVVCU7bBT{d9%XU_&G1(~ zrmMhEcHTRk*-rQte^$WW9AOKK-w!?BRsTQw;{NSo=}bctffTlSmZ;nl)h`_%@2E1m zcK7Y8Q!&1d7w?{ASYVmBQ2AeD+0uP=H_t!1+1X#c*3WX$r>;+~Ct116Odijfw!_~< zVKtj!+w53|Jyql51QubpI~&@49t?MC9V-ADTyViR>?)F zK#IZ0z|c_Fz);u7BE-nZ%Ea8t)L7TR!pgv4iC@u46b-rgDVb@NxHViAK2-|TAPKS| sI6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ84Nwt-r>mdKI;Vst0F6rPu>b%7 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ab62d1789bf57d4d0a8884060baae96258ceffdf GIT binary patch literal 5506 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 PIRr2@vP9Jz;Nt!U*I|wz literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/layout/main.xml b/samples/AndroidBeamDemo/res/layout/main.xml new file mode 100644 index 000000000..eacb68e9f --- /dev/null +++ b/samples/AndroidBeamDemo/res/layout/main.xml @@ -0,0 +1,27 @@ + + + diff --git a/samples/AndroidBeamDemo/res/menu/options.xml b/samples/AndroidBeamDemo/res/menu/options.xml new file mode 100644 index 000000000..8012d8e62 --- /dev/null +++ b/samples/AndroidBeamDemo/res/menu/options.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/samples/AndroidBeamDemo/res/values/strings.xml b/samples/AndroidBeamDemo/res/values/strings.xml new file mode 100644 index 000000000..68ed73f19 --- /dev/null +++ b/samples/AndroidBeamDemo/res/values/strings.xml @@ -0,0 +1,9 @@ + + + Beam + Ensure that Android Beam is enabled by turning it on in + the system Settings (select the setting icon above), then place this device up + against another Android device that supports Android Beam to send a + message. + Android Beam settings + diff --git a/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java b/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java new file mode 100644 index 000000000..79019abfd --- /dev/null +++ b/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011 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.example.android.beam; + +import android.app.Activity; +import android.content.Intent; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.nfc.NfcAdapter.CreateNdefMessageCallback; +import android.nfc.NfcAdapter.OnNdefPushCompleteCallback; +import android.nfc.NfcEvent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Parcelable; +import android.provider.Settings; +import android.text.format.Time; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.TextView; +import android.widget.Toast; + +import java.nio.charset.Charset; + + +public class Beam extends Activity implements CreateNdefMessageCallback, + OnNdefPushCompleteCallback { + NfcAdapter mNfcAdapter; + TextView mInfoText; + private static final int MESSAGE_SENT = 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mInfoText = (TextView) findViewById(R.id.textView); + // Check for available NFC Adapter + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (mNfcAdapter == null) { + mInfoText = (TextView) findViewById(R.id.textView); + mInfoText.setText("NFC is not available on this device."); + } else { + // Register callback to set NDEF message + mNfcAdapter.setNdefPushMessageCallback(this, this); + // Register callback to listen for message-sent success + mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + } + } + + + /** + * Implementation for the CreateNdefMessageCallback interface + */ + @Override + public NdefMessage createNdefMessage(NfcEvent event) { + Time time = new Time(); + time.setToNow(); + String text = ("Beam me up!\n\n" + + "Beam Time: " + time.format("%H:%M:%S")); + NdefMessage msg = new NdefMessage(NdefRecord.createMime( + "application/com.example.android.beam", text.getBytes()) + /** + * The Android Application Record (AAR) is commented out. When a device + * receives a push with an AAR in it, the application specified in the AAR + * is guaranteed to run. The AAR overrides the tag dispatch system. + * You can add it back in to guarantee that this + * activity starts when receiving a beamed message. For now, this code + * uses the tag dispatch system. + */ + //,NdefRecord.createApplicationRecord("com.example.android.beam") + ); + return msg; + } + + /** + * Implementation for the OnNdefPushCompleteCallback interface + */ + @Override + public void onNdefPushComplete(NfcEvent arg0) { + // A handler is needed to send messages to the activity when this + // callback occurs, because it happens from a binder thread + mHandler.obtainMessage(MESSAGE_SENT).sendToTarget(); + } + + /** This handler receives a message from onNdefPushComplete */ + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_SENT: + Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show(); + break; + } + } + }; + + @Override + public void onResume() { + super.onResume(); + // Check to see that the Activity started due to an Android Beam + if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { + processIntent(getIntent()); + } + } + + @Override + public void onNewIntent(Intent intent) { + // onResume gets called after this to handle the intent + setIntent(intent); + } + + /** + * Parses the NDEF Message from the intent and prints to the TextView + */ + void processIntent(Intent intent) { + Parcelable[] rawMsgs = intent.getParcelableArrayExtra( + NfcAdapter.EXTRA_NDEF_MESSAGES); + // only one message sent during the beam + NdefMessage msg = (NdefMessage) rawMsgs[0]; + // record 0 contains the MIME type, record 1 is the AAR, if present + mInfoText.setText(new String(msg.getRecords()[0].getPayload())); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // If NFC is not available, we won't be needing this menu + if (mNfcAdapter == null) { + return super.onCreateOptionsMenu(menu); + } + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_settings: + Intent intent = new Intent(Settings.ACTION_NFCSHARING_SETTINGS); + startActivity(intent); + return true; + default: + return super.onOptionsItemSelected(item); + } + } +} diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 2a362e962..159437c13 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -3274,6 +3274,13 @@ /> + + + + + + + diff --git a/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java new file mode 100644 index 000000000..08eb83984 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 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.example.android.apis.nfc; + +import com.example.android.apis.R; + +import android.app.Activity; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.os.Bundle; +import android.widget.TextView; + +/** + * An example of how to use the NFC foreground NDEF push APIs. + */ +public class ForegroundNdefPush extends Activity { + private NfcAdapter mAdapter; + private TextView mText; + private NdefMessage mMessage; + + @Override + public void onCreate(Bundle savedState) { + super.onCreate(savedState); + + mAdapter = NfcAdapter.getDefaultAdapter(this); + + // Create an NDEF message a URL + mMessage = new NdefMessage(NdefRecord.createUri("http://www.android.com")); + + setContentView(R.layout.foreground_dispatch); + mText = (TextView) findViewById(R.id.text); + + if (mAdapter != null) { + mAdapter.setNdefPushMessage(mMessage, this); + mText.setText("Tap another Android phone with NFC to push a URL"); + } else { + mText.setText("This phone is not NFC enabled."); + } + } +} diff --git a/samples/browseable/BeamLargeFiles/AndroidManifest.xml b/samples/browseable/BeamLargeFiles/AndroidManifest.xml new file mode 100644 index 000000000..b0842535f --- /dev/null +++ b/samples/browseable/BeamLargeFiles/AndroidManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/_index.jd b/samples/browseable/BeamLargeFiles/_index.jd new file mode 100644 index 000000000..cfb07f413 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/_index.jd @@ -0,0 +1,17 @@ + +page.tags="BeamLargeFiles" +sample.group=Connectivity +@jd:body + +

+ + This sample demonstrates how to transfer large files via Android Beam. After the initial + handshake over NFC, file transfer will take place over a secondary high-speed + communication channel such as Bluetooth or WiFi Direct. + + \n\nThis feature requires Android 4.1 (Jelly Bean) or above. Unlike traditional Beam, + your application will not receive an Intent on the receiving device. Instead, the system + will save the file to disk and display a notification that the user can select to open + the file using a standard ACTION_VIEW Intent. + +

diff --git a/samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png b/samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b1efaf4b23929755615dc16fa196c5f8496bbf9a GIT binary patch literal 4199 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 literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png b/samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png new file mode 100644 index 0000000000000000000000000000000000000000..135862883e26eddce2b19db021adf62e10357ad0 GIT binary patch literal 196 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 ABme*a literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef21e1f4dfe8eeec63fde13a453812511646c83 GIT binary patch literal 11040 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 WRh@=GnE09b3XqXd5U&x{5BMKGuL(l{ literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml new file mode 100644 index 000000000..8fed5f746 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml @@ -0,0 +1,42 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml new file mode 100644 index 000000000..f811ef7dc --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml @@ -0,0 +1,40 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml new file mode 100644 index 000000000..d17095875 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml @@ -0,0 +1,43 @@ + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/menu/main.xml b/samples/browseable/BeamLargeFiles/res/menu/main.xml new file mode 100644 index 000000000..8de3baa57 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/menu/main.xml @@ -0,0 +1,18 @@ + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml new file mode 100644 index 000000000..22074a2bd --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml @@ -0,0 +1,24 @@ + + + + + + + @dimen/margin_huge + @dimen/margin_medium + + diff --git a/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml new file mode 100644 index 000000000..03d197418 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml new file mode 100644 index 000000000..8c1ea66f2 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values/base-strings.xml b/samples/browseable/BeamLargeFiles/res/values/base-strings.xml new file mode 100644 index 000000000..dd897b6d6 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/base-strings.xml @@ -0,0 +1,36 @@ + + + + + BeamLargeFiles + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml b/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml new file mode 100644 index 000000000..39e710b5c --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml @@ -0,0 +1,32 @@ + + + + + + + 4dp + 8dp + 16dp + 32dp + 64dp + + + + @dimen/margin_medium + @dimen/margin_medium + + diff --git a/samples/browseable/BeamLargeFiles/res/values/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values/template-styles.xml new file mode 100644 index 000000000..cfffcbd1b --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/template-styles.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java new file mode 100644 index 000000000..6dd50fe43 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java @@ -0,0 +1,98 @@ +/* +* 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.example.android.beamlargefiles; + +import android.app.Activity; +import android.net.Uri; +import android.nfc.NfcAdapter; +import android.nfc.NfcEvent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; + +/** + * This class demonstrates how to use Beam to send files too large to transfer reliably via NFC. + * + *

While any type of data can be placed into a normal NDEF messages, NFC is not considered + * "high-speed" communication channel. Large images can easily take > 30 seconds to transfer. + * Because NFC requires devices to be in extremely close proximity, this is not ideal. + * + *

Instead, Android 4.2+ devices can use NFC to perform an initial handshake, before handing + * off to a faster communication channel, such as Bluetooth, for file transfer. + * + *

The tradeoff is that this application will not be invoked on the receiving device. Instead, + * the transfer will be handled by the OS. The user will be shown a notification when the transfer + * is complete. Selecting the notification will open the file in the default viewer for its MIME- + * type. (If it's important that your application be used to open the file, you'll need to register + * an intent-filter to watch for the appropriate MIME-type.) + */ +public class BeamLargeFilesFragment extends Fragment implements NfcAdapter.CreateBeamUrisCallback { + + private static final String TAG = "BeamLargeFilesFragment"; + /** Filename that is to be sent for this activity. Relative to /assets. */ + private static final String FILENAME = "stargazer_droid.jpg"; + /** Content provider URI. */ + private static final String CONTENT_BASE_URI = + "content://com.example.android.beamlargefiles.files/"; + + /** + * Standard lifecycle event. Registers a callback for large-file transfer, by calling + * NfcAdapter.setBeamPushUrisCallback(). + * + * Note: Like sending NDEF messages over standard Android Beam, there is also a non-callback + * API available. See: NfcAdapter.setBeamPushUris(). + * + * @param savedInstanceState Saved instance state. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + Activity a = getActivity(); + + // Setup Beam to transfer a large file. Note the call to setBeamPushUrisCallback(). + // BEGIN_INCLUDE(setBeamPushUrisCallback) + NfcAdapter nfc = NfcAdapter.getDefaultAdapter(a); + if (nfc != null) { + Log.w(TAG, "NFC available. Setting Beam Push URI callback"); + nfc.setBeamPushUrisCallback(this, a); + } else { + Log.w(TAG, "NFC is not available"); + } + // END_INCLUDE(setBeamPushUrisCallback) + } + + /** + * Callback for Beam events (large file version). The return value here should be an array of + * content:// or file:// URIs to send. + * + * Note that the system must have read access to whatever URIs are provided here. + * + * @param nfcEvent NFC event which triggered callback + * @return URIs to be sent to remote device + */ + // BEGIN_INCLUDE(createBeamUris) + @Override + public Uri[] createBeamUris(NfcEvent nfcEvent) { + Log.i(TAG, "Beam event in progress; createBeamUris() called."); + // Images are served using a content:// URI. See AssetProvider for implementation. + Uri photoUri = Uri.parse(CONTENT_BASE_URI + FILENAME); + Log.i(TAG, "Sending URI: " + photoUri); + return new Uri[] {photoUri}; + } + // END_INCLUDE(createBeamUris) +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java new file mode 100644 index 000000000..814367833 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java @@ -0,0 +1,83 @@ +/* +* Copyright 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.example.android.beamlargefiles; + +import android.graphics.Color; +import android.os.Bundle; +import android.support.v4.app.FragmentTransaction; +import android.text.Html; +import android.widget.TextView; +import android.view.Menu; + +import com.example.android.common.activities.SampleActivityBase; +import com.example.android.common.logger.Log; +import com.example.android.common.logger.LogFragment; +import com.example.android.common.logger.LogWrapper; +import com.example.android.common.logger.MessageOnlyLogFilter; + +/** + * A simple launcher activity containing a summary sample description + * and a few action bar buttons. + */ +public class MainActivity extends SampleActivityBase { + + public static final String TAG = "MainActivity"; + + public static final String FRAGTAG = "BeamLargeFilesFragment"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + TextView sampleOutput = (TextView) findViewById(R.id.sample_output); + sampleOutput.setText(Html.fromHtml(getString(R.string.intro_message))); + + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + BeamLargeFilesFragment fragment = new BeamLargeFilesFragment(); + transaction.add(fragment, FRAGTAG); + transaction.commit(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + /** Create a chain of targets that will receive log data */ + @Override + public void initializeLogging() { + // Wraps Android's native log framework. + LogWrapper logWrapper = new LogWrapper(); + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + Log.setLogNode(logWrapper); + + // Filter strips out everything except the message text. + MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter(); + logWrapper.setNext(msgFilter); + + // On screen logging via a fragment with a TextView. + LogFragment logFragment = (LogFragment) getSupportFragmentManager() + .findFragmentById(R.id.log_fragment); + msgFilter.setNext(logFragment.getLogView()); + logFragment.getLogView().setTextAppearance(this, R.style.Log); + logFragment.getLogView().setBackgroundColor(Color.WHITE); + + Log.i(TAG, "Ready"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java new file mode 100644 index 000000000..3228927b7 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java @@ -0,0 +1,52 @@ +/* +* Copyright 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.example.android.common.activities; + +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; + +import com.example.android.common.logger.Log; +import com.example.android.common.logger.LogWrapper; + +/** + * Base launcher activity, to handle most of the common plumbing for samples. + */ +public class SampleActivityBase extends FragmentActivity { + + public static final String TAG = "SampleActivityBase"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + protected void onStart() { + super.onStart(); + initializeLogging(); + } + + /** Set up targets to receive log data */ + public void initializeLogging() { + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + // Wraps Android's native log framework + LogWrapper logWrapper = new LogWrapper(); + Log.setLogNode(logWrapper); + + Log.i(TAG, "Ready"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java new file mode 100644 index 000000000..f6c0f6139 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java @@ -0,0 +1,140 @@ +/* +* 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.example.android.common.assetprovider; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; +import android.database.Cursor; +import android.net.Uri; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import static java.net.URLConnection.guessContentTypeFromName; + +/** + * Generic content provider, which makes any files available in this app's "assets" directory + * available publicly. + * + *

To use, add the following to your AndroidManifest.xml: + * + *

+ * 
+ * 
+ */ +public class AssetProvider extends ContentProvider { + AssetManager mAssets; + + @Override + public boolean onCreate() { + Context ctx = getContext(); + if (ctx == null) { + // Context not available. Give up. + return false; + } + mAssets = ctx.getAssets(); + return true; + } + + @Override + public String getType(Uri uri){ + // Returns the MIME type for the selected URI, in conformance with the ContentProvider + // interface. Looks up the file indicated by /res/assets/{uri.path}, and returns the MIME + // type for that file as guessed by the URLConnection class. + + // Setup + String path = uri.getPath(); + + // Check if file exists + if (!fileExists(path)) { + return null; + } + + // Determine MIME-type based on filename + return guessContentTypeFromName(uri.toString()); + } + + + @Override + public AssetFileDescriptor openAssetFile (Uri uri, String mode) + throws FileNotFoundException, SecurityException { + // ContentProvider interface for opening a file descriptor by URI. This content provider + // maps all URIs to the contents of the APK's assets folder, so a file handle to + // /res/assets/{uri.path} will be returned. + + // Security check. This content provider only supports read-only access. (Also, the contents + // of an APKs assets folder are immutable, so read-write access doesn't make sense here.) + if (!"r".equals(mode)) { + throw new SecurityException("Only read-only access is supported, mode must be [r]"); + } + + // Open asset from within APK and return file descriptor + String path = uri.getPath(); + try { + return mAssets.openFd(path); + } catch (IOException e) { + throw new FileNotFoundException(); + } + } + + /** + * Check if file exists inside APK assets. + * + * @param path Fully qualified path to file. + * @return true if exists, false otherwise. + */ + private boolean fileExists(String path) { + try { + // Check to see if file can be opened. If so, file exists. + mAssets.openFd(path).close(); + return true; + } catch (IOException e) { + // Unable to open file descriptor for specified path; file doesn't exist. + return false; + } + } + + // Required/unused ContentProvider methods below. + @Override + public Cursor query(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + // Note: It might be worth implementing support for querying + // android.provider.OpenableColumns here in the future. + throw new RuntimeException("Operation not supported"); + } + + @Override + public Uri insert(Uri uri, ContentValues contentValues) { + throw new RuntimeException("Operation not supported"); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new RuntimeException("Operation not supported"); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new RuntimeException("Operation not supported"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java new file mode 100644 index 000000000..17503c568 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java @@ -0,0 +1,236 @@ +/* + * 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.example.android.common.logger; + +/** + * Helper class for a list (or tree) of LoggerNodes. + * + *

When this is set as the head of the list, + * an instance of it can function as a drop-in replacement for {@link android.util.Log}. + * Most of the methods in this class server only to map a method call in Log to its equivalent + * in LogNode.

+ */ +public class Log { + // Grabbing the native values from Android's native logging facilities, + // to make for easy migration and interop. + public static final int NONE = -1; + public static final int VERBOSE = android.util.Log.VERBOSE; + public static final int DEBUG = android.util.Log.DEBUG; + public static final int INFO = android.util.Log.INFO; + public static final int WARN = android.util.Log.WARN; + public static final int ERROR = android.util.Log.ERROR; + public static final int ASSERT = android.util.Log.ASSERT; + + // Stores the beginning of the LogNode topology. + private static LogNode mLogNode; + + /** + * Returns the next LogNode in the linked list. + */ + public static LogNode getLogNode() { + return mLogNode; + } + + /** + * Sets the LogNode data will be sent to. + */ + public static void setLogNode(LogNode node) { + mLogNode = node; + } + + /** + * Instructs the LogNode to print the log data provided. Other LogNodes can + * be chained to the end of the LogNode as desired. + * + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void println(int priority, String tag, String msg, Throwable tr) { + if (mLogNode != null) { + mLogNode.println(priority, tag, msg, tr); + } + } + + /** + * Instructs the LogNode to print the log data provided. Other LogNodes can + * be chained to the end of the LogNode as desired. + * + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + */ + public static void println(int priority, String tag, String msg) { + println(priority, tag, msg, null); + } + + /** + * Prints a message at VERBOSE priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void v(String tag, String msg, Throwable tr) { + println(VERBOSE, tag, msg, tr); + } + + /** + * Prints a message at VERBOSE priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void v(String tag, String msg) { + v(tag, msg, null); + } + + + /** + * Prints a message at DEBUG priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void d(String tag, String msg, Throwable tr) { + println(DEBUG, tag, msg, tr); + } + + /** + * Prints a message at DEBUG priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void d(String tag, String msg) { + d(tag, msg, null); + } + + /** + * Prints a message at INFO priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void i(String tag, String msg, Throwable tr) { + println(INFO, tag, msg, tr); + } + + /** + * Prints a message at INFO priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void i(String tag, String msg) { + i(tag, msg, null); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void w(String tag, String msg, Throwable tr) { + println(WARN, tag, msg, tr); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void w(String tag, String msg) { + w(tag, msg, null); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void w(String tag, Throwable tr) { + w(tag, null, tr); + } + + /** + * Prints a message at ERROR priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void e(String tag, String msg, Throwable tr) { + println(ERROR, tag, msg, tr); + } + + /** + * Prints a message at ERROR priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void e(String tag, String msg) { + e(tag, msg, null); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void wtf(String tag, String msg, Throwable tr) { + println(ASSERT, tag, msg, tr); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void wtf(String tag, String msg) { + wtf(tag, msg, null); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void wtf(String tag, Throwable tr) { + wtf(tag, null, tr); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java new file mode 100644 index 000000000..b302acd4b --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java @@ -0,0 +1,109 @@ +/* +* Copyright 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. +*/ +/* + * Copyright 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.example.android.common.logger; + +import android.graphics.Typeface; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ScrollView; + +/** + * Simple fraggment which contains a LogView and uses is to output log data it receives + * through the LogNode interface. + */ +public class LogFragment extends Fragment { + + private LogView mLogView; + private ScrollView mScrollView; + + public LogFragment() {} + + public View inflateViews() { + mScrollView = new ScrollView(getActivity()); + ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + mScrollView.setLayoutParams(scrollParams); + + mLogView = new LogView(getActivity()); + ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams); + logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + mLogView.setLayoutParams(logParams); + mLogView.setClickable(true); + mLogView.setFocusable(true); + mLogView.setTypeface(Typeface.MONOSPACE); + + // Want to set padding as 16 dips, setPadding takes pixels. Hooray math! + int paddingDips = 16; + double scale = getResources().getDisplayMetrics().density; + int paddingPixels = (int) ((paddingDips * (scale)) + .5); + mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels); + mLogView.setCompoundDrawablePadding(paddingPixels); + + mLogView.setGravity(Gravity.BOTTOM); + mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium); + + mScrollView.addView(mLogView); + return mScrollView; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View result = inflateViews(); + + mLogView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mScrollView.fullScroll(ScrollView.FOCUS_DOWN); + } + }); + return result; + } + + public LogView getLogView() { + return mLogView; + } +} \ No newline at end of file diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java new file mode 100644 index 000000000..bc37cabc0 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 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.example.android.common.logger; + +/** + * Basic interface for a logging system that can output to one or more targets. + * Note that in addition to classes that will output these logs in some format, + * one can also implement this interface over a filter and insert that in the chain, + * such that no targets further down see certain data, or see manipulated forms of the data. + * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data + * it received to HTML and sent it along to the next node in the chain, without printing it + * anywhere. + */ +public interface LogNode { + + /** + * Instructs first LogNode in the list to print the log data provided. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public void println(int priority, String tag, String msg, Throwable tr); + +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java new file mode 100644 index 000000000..c01542b91 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java @@ -0,0 +1,145 @@ +/* + * 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.example.android.common.logger; + +import android.app.Activity; +import android.content.Context; +import android.util.*; +import android.widget.TextView; + +/** Simple TextView which is used to output log data received through the LogNode interface. +*/ +public class LogView extends TextView implements LogNode { + + public LogView(Context context) { + super(context); + } + + public LogView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public LogView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /** + * Formats the log data and prints it out to the LogView. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + + + String priorityStr = null; + + // For the purposes of this View, we want to print the priority as readable text. + switch(priority) { + case android.util.Log.VERBOSE: + priorityStr = "VERBOSE"; + break; + case android.util.Log.DEBUG: + priorityStr = "DEBUG"; + break; + case android.util.Log.INFO: + priorityStr = "INFO"; + break; + case android.util.Log.WARN: + priorityStr = "WARN"; + break; + case android.util.Log.ERROR: + priorityStr = "ERROR"; + break; + case android.util.Log.ASSERT: + priorityStr = "ASSERT"; + break; + default: + break; + } + + // Handily, the Log class has a facility for converting a stack trace into a usable string. + String exceptionStr = null; + if (tr != null) { + exceptionStr = android.util.Log.getStackTraceString(tr); + } + + // Take the priority, tag, message, and exception, and concatenate as necessary + // into one usable line of text. + final StringBuilder outputBuilder = new StringBuilder(); + + String delimiter = "\t"; + appendIfNotNull(outputBuilder, priorityStr, delimiter); + appendIfNotNull(outputBuilder, tag, delimiter); + appendIfNotNull(outputBuilder, msg, delimiter); + appendIfNotNull(outputBuilder, exceptionStr, delimiter); + + // In case this was originally called from an AsyncTask or some other off-UI thread, + // make sure the update occurs within the UI thread. + ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() { + @Override + public void run() { + // Display the text we just generated within the LogView. + appendToLog(outputBuilder.toString()); + } + }))); + + if (mNext != null) { + mNext.println(priority, tag, msg, tr); + } + } + + public LogNode getNext() { + return mNext; + } + + public void setNext(LogNode node) { + mNext = node; + } + + /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since + * the logger takes so many arguments that might be null, this method helps cut out some of the + * agonizing tedium of writing the same 3 lines over and over. + * @param source StringBuilder containing the text to append to. + * @param addStr The String to append + * @param delimiter The String to separate the source and appended strings. A tab or comma, + * for instance. + * @return The fully concatenated String as a StringBuilder + */ + private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) { + if (addStr != null) { + if (addStr.length() == 0) { + delimiter = ""; + } + + return source.append(addStr).append(delimiter); + } + return source; + } + + // The next LogNode in the chain. + LogNode mNext; + + /** Outputs the string as a new line of log data in the LogView. */ + public void appendToLog(String s) { + append("\n" + s); + } + + +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java new file mode 100644 index 000000000..16a9e7ba2 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 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.example.android.common.logger; + +import android.util.Log; + +/** + * Helper class which wraps Android's native Log utility in the Logger interface. This way + * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously. + */ +public class LogWrapper implements LogNode { + + // For piping: The next node to receive Log data after this one has done its work. + private LogNode mNext; + + /** + * Returns the next LogNode in the linked list. + */ + public LogNode getNext() { + return mNext; + } + + /** + * Sets the LogNode data will be sent to.. + */ + public void setNext(LogNode node) { + mNext = node; + } + + /** + * Prints data out to the console using Android's native log mechanism. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + // There actually are log methods that don't take a msg parameter. For now, + // if that's the case, just convert null to the empty string and move on. + String useMsg = msg; + if (useMsg == null) { + useMsg = ""; + } + + // If an exeption was provided, convert that exception to a usable string and attach + // it to the end of the msg method. + if (tr != null) { + msg += "\n" + Log.getStackTraceString(tr); + } + + // This is functionally identical to Log.x(tag, useMsg); + // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg) + Log.println(priority, tag, useMsg); + + // If this isn't the last node in the chain, move things along. + if (mNext != null) { + mNext.println(priority, tag, msg, tr); + } + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java new file mode 100644 index 000000000..19967dcd4 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java @@ -0,0 +1,60 @@ +/* + * 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.example.android.common.logger; + +/** + * Simple {@link LogNode} filter, removes everything except the message. + * Useful for situations like on-screen log output where you don't want a lot of metadata displayed, + * just easy-to-read message updates as they're happening. + */ +public class MessageOnlyLogFilter implements LogNode { + + LogNode mNext; + + /** + * Takes the "next" LogNode as a parameter, to simplify chaining. + * + * @param next The next LogNode in the pipeline. + */ + public MessageOnlyLogFilter(LogNode next) { + mNext = next; + } + + public MessageOnlyLogFilter() { + } + + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + if (mNext != null) { + getNext().println(Log.NONE, null, msg, null); + } + } + + /** + * Returns the next LogNode in the chain. + */ + public LogNode getNext() { + return mNext; + } + + /** + * Sets the LogNode data will be sent to.. + */ + public void setNext(LogNode node) { + mNext = node; + } + +} From d2f61bc4f15efbd9e6a257044a31d3a032c6cd31 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 17 Jan 2023 22:59:35 +0000 Subject: [PATCH 2/4] Revert "Remove samples for deprecated Android Beam API" Revert submission 20750504-nfc-beam-cleanup Reason for revert: Droidfood blocking bug: 265628639 Reverted changes: /q/submissionid:20750504-nfc-beam-cleanup Change-Id: I52227544aa152471ab3186eb21dd3a3f0e7cc193 (cherry picked from commit 8de7b4b1663791704a17020d21c04bb21e5d785c) Merged-In: I52227544aa152471ab3186eb21dd3a3f0e7cc193 --- samples/AndroidBeamDemo/Android.bp | 13 + samples/AndroidBeamDemo/AndroidManifest.xml | 42 ++++ samples/AndroidBeamDemo/_index.html | 3 + .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 5365 bytes .../res/drawable-hdpi/ic_menu_preferences.png | Bin 0 -> 1851 bytes .../res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2475 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2470 bytes .../res/drawable-mdpi/ic_menu_preferences.png | Bin 0 -> 1142 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 5506 bytes .../drawable-xhdpi/ic_menu_preferences.png | Bin 0 -> 2507 bytes samples/AndroidBeamDemo/res/layout/main.xml | 27 ++ samples/AndroidBeamDemo/res/menu/options.xml | 7 + .../AndroidBeamDemo/res/values/strings.xml | 9 + .../src/com/example/android/beam/Beam.java | 163 ++++++++++++ samples/ApiDemos/AndroidManifest.xml | 7 + .../android/apis/nfc/ForegroundNdefPush.java | 55 ++++ .../BeamLargeFiles/AndroidManifest.xml | 55 ++++ samples/browseable/BeamLargeFiles/_index.jd | 17 ++ .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4199 bytes .../res/drawable-hdpi/tile.9.png | Bin 0 -> 196 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2535 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 6022 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 11040 bytes .../res/layout-sw600dp-land/activity_main.xml | 42 ++++ .../res/layout-sw600dp/activity_main.xml | 40 +++ .../res/layout/activity_main.xml | 43 ++++ .../BeamLargeFiles/res/menu/main.xml | 18 ++ .../res/values-sw600dp/template-dimens.xml | 24 ++ .../res/values-sw600dp/template-styles.xml | 25 ++ .../res/values-v11/template-styles.xml | 22 ++ .../res/values-v21/base-colors.xml | 21 ++ .../res/values-v21/base-template-styles.xml | 24 ++ .../res/values/base-strings.xml | 36 +++ .../res/values/template-dimens.xml | 32 +++ .../res/values/template-styles.xml | 54 ++++ .../BeamLargeFilesFragment.java | 98 ++++++++ .../MainActivity.java | 83 ++++++ .../activities/SampleActivityBase.java | 52 ++++ .../assetprovider/AssetProvider.java | 140 +++++++++++ .../logger/Log.java | 236 ++++++++++++++++++ .../logger/LogFragment.java | 109 ++++++++ .../logger/LogNode.java | 39 +++ .../logger/LogView.java | 145 +++++++++++ .../logger/LogWrapper.java | 75 ++++++ .../logger/MessageOnlyLogFilter.java | 60 +++++ 45 files changed, 1816 insertions(+) create mode 100644 samples/AndroidBeamDemo/Android.bp create mode 100644 samples/AndroidBeamDemo/AndroidManifest.xml create mode 100755 samples/AndroidBeamDemo/_index.html create mode 100644 samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-hdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png create mode 100644 samples/AndroidBeamDemo/res/drawable-xhdpi/ic_menu_preferences.png create mode 100644 samples/AndroidBeamDemo/res/layout/main.xml create mode 100644 samples/AndroidBeamDemo/res/menu/options.xml create mode 100644 samples/AndroidBeamDemo/res/values/strings.xml create mode 100644 samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java create mode 100644 samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java create mode 100644 samples/browseable/BeamLargeFiles/AndroidManifest.xml create mode 100644 samples/browseable/BeamLargeFiles/_index.jd create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-mdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-xhdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png create mode 100644 samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/layout/activity_main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/menu/main.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v21/base-colors.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values-v21/base-template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/base-strings.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/template-dimens.xml create mode 100644 samples/browseable/BeamLargeFiles/res/values/template-styles.xml create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java create mode 100644 samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java diff --git a/samples/AndroidBeamDemo/Android.bp b/samples/AndroidBeamDemo/Android.bp new file mode 100644 index 000000000..fdc2748b0 --- /dev/null +++ b/samples/AndroidBeamDemo/Android.bp @@ -0,0 +1,13 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test { + name: "AndroidBeamDemo", + // Only compile source java files in this apk. + srcs: ["src/**/*.java"], + sdk_version: "current", + dex_preopt: { + enabled: false, + }, +} diff --git a/samples/AndroidBeamDemo/AndroidManifest.xml b/samples/AndroidBeamDemo/AndroidManifest.xml new file mode 100644 index 000000000..f4c06d936 --- /dev/null +++ b/samples/AndroidBeamDemo/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/samples/AndroidBeamDemo/_index.html b/samples/AndroidBeamDemo/_index.html new file mode 100755 index 000000000..9fe80b08a --- /dev/null +++ b/samples/AndroidBeamDemo/_index.html @@ -0,0 +1,3 @@ +

Android Beam Demo shows how to use the Android Beam feature introduced in API level 14. This +application beams a simple message from one device to another when they are in close enough proximity. This +application must be installed on two devices that have NFC capabilities, running Android 4.0 or later.

diff --git a/samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c96fa9e05ff294e321cceacfa0446862152300b5 GIT binary patch literal 5365 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 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ab4d45e7870f4ab304dcd91fe8586aa01c199310 GIT binary patch literal 2475 zcmbVOc{r478z1{lQIXJVoFvQ4yknW=m@qS@;e=_ZqtY^FUJPb2Gj_*1Dsd7mlCMHJ z9i?<~ND`9DT#76uku}mHOIecT8fgKF|F;_wRS_*Y&2*+_z|`>Z`(F zFbx+fnJ!&{rB_)|`V~e+eUvV1Mb6$LPoAGBoFRZ}FXYeW65yk^s^I{eMS%Zm>xOdU zlb`@LHA(<^M!9=2qk@|{(5^x|91Bl=RbA|W_0{javUbTxw0g z^25`~lyA1A5&<3{67lg!WO#TuBHS9m6Zj)R91gd{fkshVGGqjUj|34YB!{yU*B5P}hz|Y7 zjUQ?Yy(0M#k`4)Zp#r9~9)2dvU}^6D+0c@r)Em5qfGsTwBbdx%hH@aT$c0RROK%V? zHVcmeu_zG4*q|_IlpPiXu^5noB@&&SD9$!mv@L0w<40H=$v3>r;Y#=3BYA_kWUE!$;F?S8`&{}GEP2_S}uC-CC&f|omh7QhqngaJH0 zK=QN&+!#zYcS&9<&(~2&AKNav)y~22<#CAv<|RJTLk+ZtHQ#V6hVU zAmm`ZhwbsCAuUHoVM$)Wfr?3zhU&@MRo1PKPRwpOIcOdjRJs$@zALrhB=`7pp0-}T zgvH!ov2~@46IMZMlC03D=@HvC8Tp>@QeE>sWZ$XQbbIteOm)wz5A!i`_L+D4;`OFy zKKjlbsM|8sI@;GM-yZ&`;6A1DCR6F`jcG(`*7$Ku?flHgv5+)hM~v=pL0(S;?L)@q zm)Qo_*v~5}9`Ev5bptXz(xCl!w;nA>u0PbI7}u%sH-C@c@K}$@HVv|E zt=x{FXv~LRN*$XJTZ#L57PNceBfljD#Re;7%Gx(5A6>a=A*gQsExAnn#j7eZ-DnwJ zPJ%G3CQcQVap+lE%@Dh0)#dA^0y88JN%nn%XUYBA`ZGV9ylm?&>vzvhJ)k!#ms5L6_a&&uPb8*Ieq8kTigg*E z&Z{IA?QY7Ng8Oiv0;t>+D(sBUI&22Zk~S6VYVG&^^$dR41- zcR@qFjePzU&c>-xf91^iC_&zPIE^+#D<|kh4drlJsSuqRK>4mRt|43%a5RM{xLJ$w2(n`(aQvl$7kZ|YffY#eWzmpKq` zOdLzPXp~2daS8YK&J(qmA!dg0{3l6(OSh##!lg^98@sBi4!3j_Z+Uer_imG6msNUv z4XDj7=0wPp=(Ve9uOBFqD=3(B4fWjlK&vG_h+w2%{!2vIX##I=X^ZZH&d~YJ35x|R z`;Iq7BUF#D7I5W^EaqaUNot<-HO)#H0c=EwHqY{|BSUeYmZH5x_WHdmPm3A#h7n|y zi)I2|U+wBShVS?%=Myc3+}GGt6-n+SnYfLwUX!VrT*$uTieIf*jqgq?xXZ;*UMmk|l{6pH3`e&GS_%HxW6RWaxd8?r^1ZmD<6zwL z5!d(O>vvTB9JsC9zY!m(hs3g2eV|OX$&E%d z$x@M=yWk*sEZJ+0(A!#lL@*ca{^GU5D7il6F`~qb6QiK=Da%49ur4vB4V$Ae7-`;l z?_T)MPUhfv(CzpB)G zyZULz@5@hQKMaq8_Gp#7)gC(e+5UEY?Nn^CoLtJE`+_r}4Nk+Gwl+x8KBX;ULuPIK zXZBPHT08g^=^d>*z4HrCooQUx)!Jy$p%K=!W5KRFWKzrX_1?hJ43AyE(+?}vdYtbo zDpk`>eai=^>E*GyxTxUao~kv?`c}2Zpt`|L_~-1M({Eo`4|9moWf>c3hG;HuwHYx}t7MW^>Fs24|chf4_;3a?fd z_rA%tuJ4a-{_v&?kzM)rNKNh3okGdS-hRu9-*@*vh?7-^IWJ5&1yZMEmVTdHoZZP+ IiTe}(4YN-YS^xk5 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..20796846713ab7c4b6efe08f108986969bc0c05c GIT binary patch literal 2470 zcmV;X30d}uP)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RW3Jw(&2d#cP@&Et{I7vi7RA}DS z*?o{z^?3*I&$;*R-UXIj7M69DmkL4AfEYs~3ISqFG{j(})cBILr8p_oF*bFkYFfj@ zFlHu`nfhAMOiW^JOdFk)*3h8!9fENM0}&QMAS^B{ySywc`+n~|r+=KgSs)86>?Ka0 znKN_F`Tfp0&-eHIo|o@)f+&jof0h(%-MUpvON&l~ACe*oMERpXN*CwPgD8s3n>Ww0 zWy{=DZ2GO0?!}PPRU#RXIYpxe=*mA+9GrM=M`+DAn|!M#bolocFnF-32~(aq*K!OS z$Vz4-Qo*S|ch@eySk8>nlTMvAENSGlUH-CX(S)c>xL}~lZ|mZQ9dw-HK3vz%|8#I( zx_|SF1CvqIYXRhXx7BION77tBjBo7b!O?Vw?99-Zp()GIBx8!GN>S1C<%q?Ne0L;O zMg99u7`sXdGO1&>@POsU3fe<%+QF_It8?Uz1sX7|h<`kbnsz=pm}|;U%jKjB7Dm!I zhs~RK?hwDs9zFb>`$;9a>mIh3Fzqjx@j(^@OS*O4TBG67n?RS>ywNg#mg_T z;WwmGTznC?EaI{EnbFM6!#@NIJg|qC*YngPj2N+##AB}d3>RL=+_|KS*}tFpf5zUu zys&~nCH!hNPd!a{cl@6F_n&$Q9Hj#Uh(H#MEaUapziG`{)~)BzAzpcvwzl5){d@Bt6F@c9OL(}PvO(0<@#0H-^n%-r z9$QA@%LL=%LpQm_h7WI*NU(bsue|n$uY5Pdns$D)pDh_~sfcq+!F^yu2Rj>ia51xI zGGQWDUd7dO_{P16-innDe=e7)ajJ27OI{Lk9LoTi7u?}9! za?@U3I$U52Jad4r?4uN!&2%0!e(l_V#Mg+n5zg1u#gcC`b0$H=l#7^k1(#gH2Ok{$ zY+sS|+f7_i8dtgl2Jm7_tbByN7G~5aX3e~o;5?#rYB!Ng@%(ZsD|zunCQV}LqkQ#m z3HuRsR_6HM!+fr6fLmx&C-e85IN#j2n6s+q<(KnqPkf(kTS+E(=BF(B8~$Y}PyUGU zr%*yXyl;R$us_R!dRk8~=jy9i@K*??BGldWtT*2xlO>&I!$uCZuy6sZ-(>5y{sUN% z<;}L!1Q12sR!_}I%)RM7cI}=wg;`rz1b<;{I;ZiBqsZV}?7M`uBm) z&q*0k`PsbH_WJK%#P_?q`{%6vATpjhaP+F56u`Ikur=y0fGA#lG&R2L*S{`&_u}WR z?C9<%fSNX*=;+^z&#GeT)Y$~pM77@e%?~v;6&}F)Fy`JT1&|53XHWl2^x3nhK6_zI z&7yTyt~@jSqoEkoA0Oz7Xg`7WGm|}=CC`O#KrlJptGN}{tv@pWE>3cOx*q^alRS1# z-(wFAV{uh4S+5+y^vgd+Fo|e~hK8rTRWop9`)V(JeFP&?{q%v459Y}c49;KwNx;Ju z+)>4$BU%mDeUY=Or^Zn^e8!GC4jdRbfGbnnIXDJ#eh}+2Z`jeK=cIXH;Rrrm%7GlC zi+X!EyEDCWzVHPEH|MWjuy$=>wo60Ev(+rhGV+LCQh2I~?A$cx9&@id?;q9G%$Po$ z;A1#Qw86%Wg#l0(awz2dk~6>uddxWQIw~tKCm2rnitfw-8wv!V670f{f?Tq3m0{ovu6mvzAWc`f=~P@64xR_w9#+h?X7zXAt%d2rw!mhj<0-)bb1uQ zM8eg=Xp3e4RXF9-`AArB04+JzXPG+(!8Ir&+Nhy{<;x2P;CmHu$GhMFwstY`8m62l zR$hqbtbHdYEQOE-X>PAPq27t#0|*^m7Mx5zKA0abh-sqW&xv*sy=v8}!YKcxV!l6y z;5dJJl7X-%9VGINWep+kb)J~i{Cz9$b;XN5cs5)};!>h|nQY;rPebm+;|H_HB(iiw zZOFnbRdrlm!qw$WDB^<*OZM^3Fs4*7zm^9U_H@sN#T85RocekNsegL95X%m6eMN89 z?+)Y6#EQebcWfzHV$^u(#Q>;>Zx<92u8)N!;n?KI&n*;J)|>)Y9Jfa;$|7qh!$K}7{%K7{Ry0g727l_Z_-^>1XY8!dB zHvUO|b_o}s6N5-6h}s!GI1brSL{XAN&|6WbAeoRn$hwu=JwLkKv|K1D5cR+g0@@BR z{~E)BK#DSgnS|eq$^YBh(B2n`svJV?9@;a#Su+UYM(xgnl%yD1%=A%|rYR|o=XGXy zV|zR{Wz^Ay@axapEYVVfj|~VIl?{V~41CsNlZw?!+X)r{nAqJsx)o)_W8i z^zpNNRegL6MBZvV>ar>St?ZFoC`1c3VS67XMx;w-=MJd}<1ArnrSS1CTKCk~Td{eI kN5npsbmk=+$8H(;KUh0Py*Qt%LjV8(07*qoM6N<$f?a3QQ~&?~ literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png b/samples/AndroidBeamDemo/res/drawable-mdpi/ic_menu_preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc50e66ee7e9812e4117d18150ad3cd575cb48d GIT binary patch literal 1142 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~H|ou`Xqh{y4#A+b4=LnZ3&eXfmvd8^knnmajp zwXv%2Nuv!d=N4S^G~w2`$g{&h$54r-*Ui`9qDv3cL<{4K6^-{K_8PR!R#iK^Q({G) z!L*$(I9wux6IVwr+;R5S)vb5G&z(1&d$+v8g_m5ZK1x5#bzk0^`0urxR$=whB zJz=ekXUqn_WlG66Kc_ZlMs8td7HiyS_vg#>cTp#OSPTSxCD*Rpx41*}?Exi&Q?Iwx zJzQt%yQ#C|%_LQ(tesQm94ZOqHk-jzX|gXOTwgaaxufsNc6BeKNXA1Vla8`@FjZ!3 zS$4C*mBnSHec!<~Mai2!JUPd-!QGhEm(ORn|OR!_DA53IQaBy*Ck zHMh%i%C6iIUzqqvvW-)t?NF?hLc`6M2D4WkersyYvN=gBhP`A}+LNh_krBFu(V0y7 zLJ{io?Y9_5-CnfUtT_MA6r~^qhTe$xuBrPc9E*8*wAz8Gi}7J-|GTW5@@o%_D-&!A zg{Dh?oAYg_4yT&)p6Qk4cQkz+{+Onf9-OmX;Y6Fv^pLc}z6<%jt63dh8*I-v#dX55 zS)M6Vxo0V~{;B&NXMf^g+s3u~(mD3OEVkF%d1W5=&cp4m=Lr_xGyQy(^*>_5St74T0_kJ8tFr&%XGiqQ|YE)tI62z%KW^o02v$uiTecDSymlii)+dg!8ETLU-W43EUJizgCZoUfJ3ntc80yOi&i=_zSVd+u!7 z{jeih)o$whBkR70@~ZkYi?D`DwRkhE(s1PN4!Qg)e{w*4aJha}3-@h#4%xLgJOsC< z7X8S%nYpA+U8(z^^XF;8HsbnL3>iEOXREfp&nkBPapRSlVVCU7bBT{d9%XU_&G1(~ zrmMhEcHTRk*-rQte^$WW9AOKK-w!?BRsTQw;{NSo=}bctffTlSmZ;nl)h`_%@2E1m zcK7Y8Q!&1d7w?{ASYVmBQ2AeD+0uP=H_t!1+1X#c*3WX$r>;+~Ct116Odijfw!_~< zVKtj!+w53|Jyql51QubpI~&@49t?MC9V-ADTyViR>?)F zK#IZ0z|c_Fz);u7BE-nZ%Ea8t)L7TR!pgv4iC@u46b-rgDVb@NxHViAK2-|TAPKS| sI6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ84Nwt-r>mdKI;Vst0F6rPu>b%7 literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png b/samples/AndroidBeamDemo/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ab62d1789bf57d4d0a8884060baae96258ceffdf GIT binary patch literal 5506 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 PIRr2@vP9Jz;Nt!U*I|wz literal 0 HcmV?d00001 diff --git a/samples/AndroidBeamDemo/res/layout/main.xml b/samples/AndroidBeamDemo/res/layout/main.xml new file mode 100644 index 000000000..eacb68e9f --- /dev/null +++ b/samples/AndroidBeamDemo/res/layout/main.xml @@ -0,0 +1,27 @@ + + + diff --git a/samples/AndroidBeamDemo/res/menu/options.xml b/samples/AndroidBeamDemo/res/menu/options.xml new file mode 100644 index 000000000..8012d8e62 --- /dev/null +++ b/samples/AndroidBeamDemo/res/menu/options.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/samples/AndroidBeamDemo/res/values/strings.xml b/samples/AndroidBeamDemo/res/values/strings.xml new file mode 100644 index 000000000..68ed73f19 --- /dev/null +++ b/samples/AndroidBeamDemo/res/values/strings.xml @@ -0,0 +1,9 @@ + + + Beam + Ensure that Android Beam is enabled by turning it on in + the system Settings (select the setting icon above), then place this device up + against another Android device that supports Android Beam to send a + message. + Android Beam settings + diff --git a/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java b/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java new file mode 100644 index 000000000..79019abfd --- /dev/null +++ b/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011 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.example.android.beam; + +import android.app.Activity; +import android.content.Intent; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.nfc.NfcAdapter.CreateNdefMessageCallback; +import android.nfc.NfcAdapter.OnNdefPushCompleteCallback; +import android.nfc.NfcEvent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Parcelable; +import android.provider.Settings; +import android.text.format.Time; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.TextView; +import android.widget.Toast; + +import java.nio.charset.Charset; + + +public class Beam extends Activity implements CreateNdefMessageCallback, + OnNdefPushCompleteCallback { + NfcAdapter mNfcAdapter; + TextView mInfoText; + private static final int MESSAGE_SENT = 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mInfoText = (TextView) findViewById(R.id.textView); + // Check for available NFC Adapter + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (mNfcAdapter == null) { + mInfoText = (TextView) findViewById(R.id.textView); + mInfoText.setText("NFC is not available on this device."); + } else { + // Register callback to set NDEF message + mNfcAdapter.setNdefPushMessageCallback(this, this); + // Register callback to listen for message-sent success + mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + } + } + + + /** + * Implementation for the CreateNdefMessageCallback interface + */ + @Override + public NdefMessage createNdefMessage(NfcEvent event) { + Time time = new Time(); + time.setToNow(); + String text = ("Beam me up!\n\n" + + "Beam Time: " + time.format("%H:%M:%S")); + NdefMessage msg = new NdefMessage(NdefRecord.createMime( + "application/com.example.android.beam", text.getBytes()) + /** + * The Android Application Record (AAR) is commented out. When a device + * receives a push with an AAR in it, the application specified in the AAR + * is guaranteed to run. The AAR overrides the tag dispatch system. + * You can add it back in to guarantee that this + * activity starts when receiving a beamed message. For now, this code + * uses the tag dispatch system. + */ + //,NdefRecord.createApplicationRecord("com.example.android.beam") + ); + return msg; + } + + /** + * Implementation for the OnNdefPushCompleteCallback interface + */ + @Override + public void onNdefPushComplete(NfcEvent arg0) { + // A handler is needed to send messages to the activity when this + // callback occurs, because it happens from a binder thread + mHandler.obtainMessage(MESSAGE_SENT).sendToTarget(); + } + + /** This handler receives a message from onNdefPushComplete */ + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_SENT: + Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show(); + break; + } + } + }; + + @Override + public void onResume() { + super.onResume(); + // Check to see that the Activity started due to an Android Beam + if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { + processIntent(getIntent()); + } + } + + @Override + public void onNewIntent(Intent intent) { + // onResume gets called after this to handle the intent + setIntent(intent); + } + + /** + * Parses the NDEF Message from the intent and prints to the TextView + */ + void processIntent(Intent intent) { + Parcelable[] rawMsgs = intent.getParcelableArrayExtra( + NfcAdapter.EXTRA_NDEF_MESSAGES); + // only one message sent during the beam + NdefMessage msg = (NdefMessage) rawMsgs[0]; + // record 0 contains the MIME type, record 1 is the AAR, if present + mInfoText.setText(new String(msg.getRecords()[0].getPayload())); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // If NFC is not available, we won't be needing this menu + if (mNfcAdapter == null) { + return super.onCreateOptionsMenu(menu); + } + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_settings: + Intent intent = new Intent(Settings.ACTION_NFCSHARING_SETTINGS); + startActivity(intent); + return true; + default: + return super.onOptionsItemSelected(item); + } + } +} diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 2a362e962..159437c13 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -3274,6 +3274,13 @@ /> + + + + + + + diff --git a/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java new file mode 100644 index 000000000..08eb83984 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 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.example.android.apis.nfc; + +import com.example.android.apis.R; + +import android.app.Activity; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.os.Bundle; +import android.widget.TextView; + +/** + * An example of how to use the NFC foreground NDEF push APIs. + */ +public class ForegroundNdefPush extends Activity { + private NfcAdapter mAdapter; + private TextView mText; + private NdefMessage mMessage; + + @Override + public void onCreate(Bundle savedState) { + super.onCreate(savedState); + + mAdapter = NfcAdapter.getDefaultAdapter(this); + + // Create an NDEF message a URL + mMessage = new NdefMessage(NdefRecord.createUri("http://www.android.com")); + + setContentView(R.layout.foreground_dispatch); + mText = (TextView) findViewById(R.id.text); + + if (mAdapter != null) { + mAdapter.setNdefPushMessage(mMessage, this); + mText.setText("Tap another Android phone with NFC to push a URL"); + } else { + mText.setText("This phone is not NFC enabled."); + } + } +} diff --git a/samples/browseable/BeamLargeFiles/AndroidManifest.xml b/samples/browseable/BeamLargeFiles/AndroidManifest.xml new file mode 100644 index 000000000..b0842535f --- /dev/null +++ b/samples/browseable/BeamLargeFiles/AndroidManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/_index.jd b/samples/browseable/BeamLargeFiles/_index.jd new file mode 100644 index 000000000..cfb07f413 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/_index.jd @@ -0,0 +1,17 @@ + +page.tags="BeamLargeFiles" +sample.group=Connectivity +@jd:body + +

+ + This sample demonstrates how to transfer large files via Android Beam. After the initial + handshake over NFC, file transfer will take place over a secondary high-speed + communication channel such as Bluetooth or WiFi Direct. + + \n\nThis feature requires Android 4.1 (Jelly Bean) or above. Unlike traditional Beam, + your application will not receive an Intent on the receiving device. Instead, the system + will save the file to disk and display a notification that the user can select to open + the file using a standard ACTION_VIEW Intent. + +

diff --git a/samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png b/samples/browseable/BeamLargeFiles/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b1efaf4b23929755615dc16fa196c5f8496bbf9a GIT binary patch literal 4199 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 literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png b/samples/browseable/BeamLargeFiles/res/drawable-hdpi/tile.9.png new file mode 100644 index 0000000000000000000000000000000000000000..135862883e26eddce2b19db021adf62e10357ad0 GIT binary patch literal 196 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 ABme*a literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/BeamLargeFiles/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef21e1f4dfe8eeec63fde13a453812511646c83 GIT binary patch literal 11040 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
AE|R-G`Xvw7m2t-P}}o#z;}I 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 WRh@=GnE09b3XqXd5U&x{5BMKGuL(l{ literal 0 HcmV?d00001 diff --git a/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml new file mode 100644 index 000000000..8fed5f746 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout-sw600dp-land/activity_main.xml @@ -0,0 +1,42 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml new file mode 100644 index 000000000..f811ef7dc --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout-sw600dp/activity_main.xml @@ -0,0 +1,40 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml b/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml new file mode 100644 index 000000000..d17095875 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/layout/activity_main.xml @@ -0,0 +1,43 @@ + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/menu/main.xml b/samples/browseable/BeamLargeFiles/res/menu/main.xml new file mode 100644 index 000000000..8de3baa57 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/menu/main.xml @@ -0,0 +1,18 @@ + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml new file mode 100644 index 000000000..22074a2bd --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-dimens.xml @@ -0,0 +1,24 @@ + + + + + + + @dimen/margin_huge + @dimen/margin_medium + + diff --git a/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml new file mode 100644 index 000000000..03d197418 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-sw600dp/template-styles.xml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml new file mode 100644 index 000000000..8c1ea66f2 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values-v11/template-styles.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values/base-strings.xml b/samples/browseable/BeamLargeFiles/res/values/base-strings.xml new file mode 100644 index 000000000..dd897b6d6 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/base-strings.xml @@ -0,0 +1,36 @@ + + + + + BeamLargeFiles + + + + diff --git a/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml b/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml new file mode 100644 index 000000000..39e710b5c --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/template-dimens.xml @@ -0,0 +1,32 @@ + + + + + + + 4dp + 8dp + 16dp + 32dp + 64dp + + + + @dimen/margin_medium + @dimen/margin_medium + + diff --git a/samples/browseable/BeamLargeFiles/res/values/template-styles.xml b/samples/browseable/BeamLargeFiles/res/values/template-styles.xml new file mode 100644 index 000000000..cfffcbd1b --- /dev/null +++ b/samples/browseable/BeamLargeFiles/res/values/template-styles.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java new file mode 100644 index 000000000..6dd50fe43 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/BeamLargeFilesFragment.java @@ -0,0 +1,98 @@ +/* +* 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.example.android.beamlargefiles; + +import android.app.Activity; +import android.net.Uri; +import android.nfc.NfcAdapter; +import android.nfc.NfcEvent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; + +/** + * This class demonstrates how to use Beam to send files too large to transfer reliably via NFC. + * + *

While any type of data can be placed into a normal NDEF messages, NFC is not considered + * "high-speed" communication channel. Large images can easily take > 30 seconds to transfer. + * Because NFC requires devices to be in extremely close proximity, this is not ideal. + * + *

Instead, Android 4.2+ devices can use NFC to perform an initial handshake, before handing + * off to a faster communication channel, such as Bluetooth, for file transfer. + * + *

The tradeoff is that this application will not be invoked on the receiving device. Instead, + * the transfer will be handled by the OS. The user will be shown a notification when the transfer + * is complete. Selecting the notification will open the file in the default viewer for its MIME- + * type. (If it's important that your application be used to open the file, you'll need to register + * an intent-filter to watch for the appropriate MIME-type.) + */ +public class BeamLargeFilesFragment extends Fragment implements NfcAdapter.CreateBeamUrisCallback { + + private static final String TAG = "BeamLargeFilesFragment"; + /** Filename that is to be sent for this activity. Relative to /assets. */ + private static final String FILENAME = "stargazer_droid.jpg"; + /** Content provider URI. */ + private static final String CONTENT_BASE_URI = + "content://com.example.android.beamlargefiles.files/"; + + /** + * Standard lifecycle event. Registers a callback for large-file transfer, by calling + * NfcAdapter.setBeamPushUrisCallback(). + * + * Note: Like sending NDEF messages over standard Android Beam, there is also a non-callback + * API available. See: NfcAdapter.setBeamPushUris(). + * + * @param savedInstanceState Saved instance state. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + Activity a = getActivity(); + + // Setup Beam to transfer a large file. Note the call to setBeamPushUrisCallback(). + // BEGIN_INCLUDE(setBeamPushUrisCallback) + NfcAdapter nfc = NfcAdapter.getDefaultAdapter(a); + if (nfc != null) { + Log.w(TAG, "NFC available. Setting Beam Push URI callback"); + nfc.setBeamPushUrisCallback(this, a); + } else { + Log.w(TAG, "NFC is not available"); + } + // END_INCLUDE(setBeamPushUrisCallback) + } + + /** + * Callback for Beam events (large file version). The return value here should be an array of + * content:// or file:// URIs to send. + * + * Note that the system must have read access to whatever URIs are provided here. + * + * @param nfcEvent NFC event which triggered callback + * @return URIs to be sent to remote device + */ + // BEGIN_INCLUDE(createBeamUris) + @Override + public Uri[] createBeamUris(NfcEvent nfcEvent) { + Log.i(TAG, "Beam event in progress; createBeamUris() called."); + // Images are served using a content:// URI. See AssetProvider for implementation. + Uri photoUri = Uri.parse(CONTENT_BASE_URI + FILENAME); + Log.i(TAG, "Sending URI: " + photoUri); + return new Uri[] {photoUri}; + } + // END_INCLUDE(createBeamUris) +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java new file mode 100644 index 000000000..814367833 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.beamlargefiles/MainActivity.java @@ -0,0 +1,83 @@ +/* +* Copyright 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.example.android.beamlargefiles; + +import android.graphics.Color; +import android.os.Bundle; +import android.support.v4.app.FragmentTransaction; +import android.text.Html; +import android.widget.TextView; +import android.view.Menu; + +import com.example.android.common.activities.SampleActivityBase; +import com.example.android.common.logger.Log; +import com.example.android.common.logger.LogFragment; +import com.example.android.common.logger.LogWrapper; +import com.example.android.common.logger.MessageOnlyLogFilter; + +/** + * A simple launcher activity containing a summary sample description + * and a few action bar buttons. + */ +public class MainActivity extends SampleActivityBase { + + public static final String TAG = "MainActivity"; + + public static final String FRAGTAG = "BeamLargeFilesFragment"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + TextView sampleOutput = (TextView) findViewById(R.id.sample_output); + sampleOutput.setText(Html.fromHtml(getString(R.string.intro_message))); + + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + BeamLargeFilesFragment fragment = new BeamLargeFilesFragment(); + transaction.add(fragment, FRAGTAG); + transaction.commit(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + /** Create a chain of targets that will receive log data */ + @Override + public void initializeLogging() { + // Wraps Android's native log framework. + LogWrapper logWrapper = new LogWrapper(); + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + Log.setLogNode(logWrapper); + + // Filter strips out everything except the message text. + MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter(); + logWrapper.setNext(msgFilter); + + // On screen logging via a fragment with a TextView. + LogFragment logFragment = (LogFragment) getSupportFragmentManager() + .findFragmentById(R.id.log_fragment); + msgFilter.setNext(logFragment.getLogView()); + logFragment.getLogView().setTextAppearance(this, R.style.Log); + logFragment.getLogView().setBackgroundColor(Color.WHITE); + + Log.i(TAG, "Ready"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java new file mode 100644 index 000000000..3228927b7 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/activities/SampleActivityBase.java @@ -0,0 +1,52 @@ +/* +* Copyright 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.example.android.common.activities; + +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; + +import com.example.android.common.logger.Log; +import com.example.android.common.logger.LogWrapper; + +/** + * Base launcher activity, to handle most of the common plumbing for samples. + */ +public class SampleActivityBase extends FragmentActivity { + + public static final String TAG = "SampleActivityBase"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + protected void onStart() { + super.onStart(); + initializeLogging(); + } + + /** Set up targets to receive log data */ + public void initializeLogging() { + // Using Log, front-end to the logging chain, emulates android.util.log method signatures. + // Wraps Android's native log framework + LogWrapper logWrapper = new LogWrapper(); + Log.setLogNode(logWrapper); + + Log.i(TAG, "Ready"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java new file mode 100644 index 000000000..f6c0f6139 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/assetprovider/AssetProvider.java @@ -0,0 +1,140 @@ +/* +* 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.example.android.common.assetprovider; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; +import android.database.Cursor; +import android.net.Uri; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import static java.net.URLConnection.guessContentTypeFromName; + +/** + * Generic content provider, which makes any files available in this app's "assets" directory + * available publicly. + * + *

To use, add the following to your AndroidManifest.xml: + * + *

+ * 
+ * 
+ */ +public class AssetProvider extends ContentProvider { + AssetManager mAssets; + + @Override + public boolean onCreate() { + Context ctx = getContext(); + if (ctx == null) { + // Context not available. Give up. + return false; + } + mAssets = ctx.getAssets(); + return true; + } + + @Override + public String getType(Uri uri){ + // Returns the MIME type for the selected URI, in conformance with the ContentProvider + // interface. Looks up the file indicated by /res/assets/{uri.path}, and returns the MIME + // type for that file as guessed by the URLConnection class. + + // Setup + String path = uri.getPath(); + + // Check if file exists + if (!fileExists(path)) { + return null; + } + + // Determine MIME-type based on filename + return guessContentTypeFromName(uri.toString()); + } + + + @Override + public AssetFileDescriptor openAssetFile (Uri uri, String mode) + throws FileNotFoundException, SecurityException { + // ContentProvider interface for opening a file descriptor by URI. This content provider + // maps all URIs to the contents of the APK's assets folder, so a file handle to + // /res/assets/{uri.path} will be returned. + + // Security check. This content provider only supports read-only access. (Also, the contents + // of an APKs assets folder are immutable, so read-write access doesn't make sense here.) + if (!"r".equals(mode)) { + throw new SecurityException("Only read-only access is supported, mode must be [r]"); + } + + // Open asset from within APK and return file descriptor + String path = uri.getPath(); + try { + return mAssets.openFd(path); + } catch (IOException e) { + throw new FileNotFoundException(); + } + } + + /** + * Check if file exists inside APK assets. + * + * @param path Fully qualified path to file. + * @return true if exists, false otherwise. + */ + private boolean fileExists(String path) { + try { + // Check to see if file can be opened. If so, file exists. + mAssets.openFd(path).close(); + return true; + } catch (IOException e) { + // Unable to open file descriptor for specified path; file doesn't exist. + return false; + } + } + + // Required/unused ContentProvider methods below. + @Override + public Cursor query(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + // Note: It might be worth implementing support for querying + // android.provider.OpenableColumns here in the future. + throw new RuntimeException("Operation not supported"); + } + + @Override + public Uri insert(Uri uri, ContentValues contentValues) { + throw new RuntimeException("Operation not supported"); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new RuntimeException("Operation not supported"); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new RuntimeException("Operation not supported"); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java new file mode 100644 index 000000000..17503c568 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/Log.java @@ -0,0 +1,236 @@ +/* + * 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.example.android.common.logger; + +/** + * Helper class for a list (or tree) of LoggerNodes. + * + *

When this is set as the head of the list, + * an instance of it can function as a drop-in replacement for {@link android.util.Log}. + * Most of the methods in this class server only to map a method call in Log to its equivalent + * in LogNode.

+ */ +public class Log { + // Grabbing the native values from Android's native logging facilities, + // to make for easy migration and interop. + public static final int NONE = -1; + public static final int VERBOSE = android.util.Log.VERBOSE; + public static final int DEBUG = android.util.Log.DEBUG; + public static final int INFO = android.util.Log.INFO; + public static final int WARN = android.util.Log.WARN; + public static final int ERROR = android.util.Log.ERROR; + public static final int ASSERT = android.util.Log.ASSERT; + + // Stores the beginning of the LogNode topology. + private static LogNode mLogNode; + + /** + * Returns the next LogNode in the linked list. + */ + public static LogNode getLogNode() { + return mLogNode; + } + + /** + * Sets the LogNode data will be sent to. + */ + public static void setLogNode(LogNode node) { + mLogNode = node; + } + + /** + * Instructs the LogNode to print the log data provided. Other LogNodes can + * be chained to the end of the LogNode as desired. + * + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void println(int priority, String tag, String msg, Throwable tr) { + if (mLogNode != null) { + mLogNode.println(priority, tag, msg, tr); + } + } + + /** + * Instructs the LogNode to print the log data provided. Other LogNodes can + * be chained to the end of the LogNode as desired. + * + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + */ + public static void println(int priority, String tag, String msg) { + println(priority, tag, msg, null); + } + + /** + * Prints a message at VERBOSE priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void v(String tag, String msg, Throwable tr) { + println(VERBOSE, tag, msg, tr); + } + + /** + * Prints a message at VERBOSE priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void v(String tag, String msg) { + v(tag, msg, null); + } + + + /** + * Prints a message at DEBUG priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void d(String tag, String msg, Throwable tr) { + println(DEBUG, tag, msg, tr); + } + + /** + * Prints a message at DEBUG priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void d(String tag, String msg) { + d(tag, msg, null); + } + + /** + * Prints a message at INFO priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void i(String tag, String msg, Throwable tr) { + println(INFO, tag, msg, tr); + } + + /** + * Prints a message at INFO priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void i(String tag, String msg) { + i(tag, msg, null); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void w(String tag, String msg, Throwable tr) { + println(WARN, tag, msg, tr); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void w(String tag, String msg) { + w(tag, msg, null); + } + + /** + * Prints a message at WARN priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void w(String tag, Throwable tr) { + w(tag, null, tr); + } + + /** + * Prints a message at ERROR priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void e(String tag, String msg, Throwable tr) { + println(ERROR, tag, msg, tr); + } + + /** + * Prints a message at ERROR priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void e(String tag, String msg) { + e(tag, msg, null); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void wtf(String tag, String msg, Throwable tr) { + println(ASSERT, tag, msg, tr); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. + */ + public static void wtf(String tag, String msg) { + wtf(tag, msg, null); + } + + /** + * Prints a message at ASSERT priority. + * + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public static void wtf(String tag, Throwable tr) { + wtf(tag, null, tr); + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java new file mode 100644 index 000000000..b302acd4b --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogFragment.java @@ -0,0 +1,109 @@ +/* +* Copyright 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. +*/ +/* + * Copyright 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.example.android.common.logger; + +import android.graphics.Typeface; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ScrollView; + +/** + * Simple fraggment which contains a LogView and uses is to output log data it receives + * through the LogNode interface. + */ +public class LogFragment extends Fragment { + + private LogView mLogView; + private ScrollView mScrollView; + + public LogFragment() {} + + public View inflateViews() { + mScrollView = new ScrollView(getActivity()); + ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + mScrollView.setLayoutParams(scrollParams); + + mLogView = new LogView(getActivity()); + ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams); + logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + mLogView.setLayoutParams(logParams); + mLogView.setClickable(true); + mLogView.setFocusable(true); + mLogView.setTypeface(Typeface.MONOSPACE); + + // Want to set padding as 16 dips, setPadding takes pixels. Hooray math! + int paddingDips = 16; + double scale = getResources().getDisplayMetrics().density; + int paddingPixels = (int) ((paddingDips * (scale)) + .5); + mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels); + mLogView.setCompoundDrawablePadding(paddingPixels); + + mLogView.setGravity(Gravity.BOTTOM); + mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium); + + mScrollView.addView(mLogView); + return mScrollView; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View result = inflateViews(); + + mLogView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mScrollView.fullScroll(ScrollView.FOCUS_DOWN); + } + }); + return result; + } + + public LogView getLogView() { + return mLogView; + } +} \ No newline at end of file diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java new file mode 100644 index 000000000..bc37cabc0 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 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.example.android.common.logger; + +/** + * Basic interface for a logging system that can output to one or more targets. + * Note that in addition to classes that will output these logs in some format, + * one can also implement this interface over a filter and insert that in the chain, + * such that no targets further down see certain data, or see manipulated forms of the data. + * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data + * it received to HTML and sent it along to the next node in the chain, without printing it + * anywhere. + */ +public interface LogNode { + + /** + * Instructs first LogNode in the list to print the log data provided. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + public void println(int priority, String tag, String msg, Throwable tr); + +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java new file mode 100644 index 000000000..c01542b91 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogView.java @@ -0,0 +1,145 @@ +/* + * 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.example.android.common.logger; + +import android.app.Activity; +import android.content.Context; +import android.util.*; +import android.widget.TextView; + +/** Simple TextView which is used to output log data received through the LogNode interface. +*/ +public class LogView extends TextView implements LogNode { + + public LogView(Context context) { + super(context); + } + + public LogView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public LogView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /** + * Formats the log data and prints it out to the LogView. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + + + String priorityStr = null; + + // For the purposes of this View, we want to print the priority as readable text. + switch(priority) { + case android.util.Log.VERBOSE: + priorityStr = "VERBOSE"; + break; + case android.util.Log.DEBUG: + priorityStr = "DEBUG"; + break; + case android.util.Log.INFO: + priorityStr = "INFO"; + break; + case android.util.Log.WARN: + priorityStr = "WARN"; + break; + case android.util.Log.ERROR: + priorityStr = "ERROR"; + break; + case android.util.Log.ASSERT: + priorityStr = "ASSERT"; + break; + default: + break; + } + + // Handily, the Log class has a facility for converting a stack trace into a usable string. + String exceptionStr = null; + if (tr != null) { + exceptionStr = android.util.Log.getStackTraceString(tr); + } + + // Take the priority, tag, message, and exception, and concatenate as necessary + // into one usable line of text. + final StringBuilder outputBuilder = new StringBuilder(); + + String delimiter = "\t"; + appendIfNotNull(outputBuilder, priorityStr, delimiter); + appendIfNotNull(outputBuilder, tag, delimiter); + appendIfNotNull(outputBuilder, msg, delimiter); + appendIfNotNull(outputBuilder, exceptionStr, delimiter); + + // In case this was originally called from an AsyncTask or some other off-UI thread, + // make sure the update occurs within the UI thread. + ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() { + @Override + public void run() { + // Display the text we just generated within the LogView. + appendToLog(outputBuilder.toString()); + } + }))); + + if (mNext != null) { + mNext.println(priority, tag, msg, tr); + } + } + + public LogNode getNext() { + return mNext; + } + + public void setNext(LogNode node) { + mNext = node; + } + + /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since + * the logger takes so many arguments that might be null, this method helps cut out some of the + * agonizing tedium of writing the same 3 lines over and over. + * @param source StringBuilder containing the text to append to. + * @param addStr The String to append + * @param delimiter The String to separate the source and appended strings. A tab or comma, + * for instance. + * @return The fully concatenated String as a StringBuilder + */ + private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) { + if (addStr != null) { + if (addStr.length() == 0) { + delimiter = ""; + } + + return source.append(addStr).append(delimiter); + } + return source; + } + + // The next LogNode in the chain. + LogNode mNext; + + /** Outputs the string as a new line of log data in the LogView. */ + public void appendToLog(String s) { + append("\n" + s); + } + + +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java new file mode 100644 index 000000000..16a9e7ba2 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/LogWrapper.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 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.example.android.common.logger; + +import android.util.Log; + +/** + * Helper class which wraps Android's native Log utility in the Logger interface. This way + * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously. + */ +public class LogWrapper implements LogNode { + + // For piping: The next node to receive Log data after this one has done its work. + private LogNode mNext; + + /** + * Returns the next LogNode in the linked list. + */ + public LogNode getNext() { + return mNext; + } + + /** + * Sets the LogNode data will be sent to.. + */ + public void setNext(LogNode node) { + mNext = node; + } + + /** + * Prints data out to the console using Android's native log mechanism. + * @param priority Log level of the data being logged. Verbose, Error, etc. + * @param tag Tag for for the log data. Can be used to organize log statements. + * @param msg The actual message to be logged. The actual message to be logged. + * @param tr If an exception was thrown, this can be sent along for the logging facilities + * to extract and print useful information. + */ + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + // There actually are log methods that don't take a msg parameter. For now, + // if that's the case, just convert null to the empty string and move on. + String useMsg = msg; + if (useMsg == null) { + useMsg = ""; + } + + // If an exeption was provided, convert that exception to a usable string and attach + // it to the end of the msg method. + if (tr != null) { + msg += "\n" + Log.getStackTraceString(tr); + } + + // This is functionally identical to Log.x(tag, useMsg); + // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg) + Log.println(priority, tag, useMsg); + + // If this isn't the last node in the chain, move things along. + if (mNext != null) { + mNext.println(priority, tag, msg, tr); + } + } +} diff --git a/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java new file mode 100644 index 000000000..19967dcd4 --- /dev/null +++ b/samples/browseable/BeamLargeFiles/src/com.example.android.common/logger/MessageOnlyLogFilter.java @@ -0,0 +1,60 @@ +/* + * 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.example.android.common.logger; + +/** + * Simple {@link LogNode} filter, removes everything except the message. + * Useful for situations like on-screen log output where you don't want a lot of metadata displayed, + * just easy-to-read message updates as they're happening. + */ +public class MessageOnlyLogFilter implements LogNode { + + LogNode mNext; + + /** + * Takes the "next" LogNode as a parameter, to simplify chaining. + * + * @param next The next LogNode in the pipeline. + */ + public MessageOnlyLogFilter(LogNode next) { + mNext = next; + } + + public MessageOnlyLogFilter() { + } + + @Override + public void println(int priority, String tag, String msg, Throwable tr) { + if (mNext != null) { + getNext().println(Log.NONE, null, msg, null); + } + } + + /** + * Returns the next LogNode in the chain. + */ + public LogNode getNext() { + return mNext; + } + + /** + * Sets the LogNode data will be sent to.. + */ + public void setNext(LogNode node) { + mNext = node; + } + +} From 6e4eecf513044bf5b623277f76a55ed54bb1a245 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Thu, 2 Mar 2023 08:36:12 +0000 Subject: [PATCH 3/4] Revert "Update clang version to clang-r487747" Revert submission 2462733-fix-clang-tools-r487747 Rollback compiler update Reverted changes: /q/submissionid:2462733-fix-clang-tools-r487747 Change-Id: I728d075c70c1a9938475069643c62a2cdf2a968f (cherry picked from commit 78eb9e45d8eb8405c1a2f9f508ff4a88633d510a) Merged-In: I728d075c70c1a9938475069643c62a2cdf2a968f --- vndk/tools/header-checker/android/envsetup.sh | 4 ++-- .../header-checker/src/linker/header_abi_linker.cpp | 2 +- .../src/repr/symbol/version_script_parser.cpp | 4 ++-- .../header-checker/src/utils/api_level_test.cpp | 8 ++++---- .../header-checker/src/utils/string_utils_test.cpp | 12 ++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/vndk/tools/header-checker/android/envsetup.sh b/vndk/tools/header-checker/android/envsetup.sh index 44eaa1c33..49096b6c0 100644 --- a/vndk/tools/header-checker/android/envsetup.sh +++ b/vndk/tools/header-checker/android/envsetup.sh @@ -15,5 +15,5 @@ # limitations under the License. export LLVM_BUILD_HOST_TOOLS=true -export LLVM_PREBUILTS_VERSION=clang-r487747 -export LLVM_RELEASE_VERSION=17 +export LLVM_PREBUILTS_VERSION=clang-r475365b +export LLVM_RELEASE_VERSION=16.0.2 diff --git a/vndk/tools/header-checker/src/linker/header_abi_linker.cpp b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp index ef4186a5c..e877150b5 100644 --- a/vndk/tools/header-checker/src/linker/header_abi_linker.cpp +++ b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp @@ -432,7 +432,7 @@ bool HeaderAbiLinker::ReadExportedSymbolsFromVersionScript() { repr::VersionScriptParser parser; parser.SetArch(arch_); - parser.SetApiLevel(api_level.value()); + parser.SetApiLevel(api_level.getValue()); for (auto &&version : excluded_symbol_versions_) { parser.AddExcludedSymbolVersion(version); } diff --git a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp index 9d962d6a5..274ecd4e7 100644 --- a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp @@ -103,7 +103,7 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( } else { if (!has_introduced_arch_tags) { result.has_introduced_tags_ = true; - result.introduced_ = intro.value(); + result.introduced_ = intro.getValue(); } } continue; @@ -117,7 +117,7 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( } else { has_introduced_arch_tags = true; result.has_introduced_tags_ = true; - result.introduced_ = intro.value(); + result.introduced_ = intro.getValue(); } continue; } diff --git a/vndk/tools/header-checker/src/utils/api_level_test.cpp b/vndk/tools/header-checker/src/utils/api_level_test.cpp index 74f06675b..c1de948aa 100644 --- a/vndk/tools/header-checker/src/utils/api_level_test.cpp +++ b/vndk/tools/header-checker/src/utils/api_level_test.cpp @@ -25,11 +25,11 @@ TEST(ApiLevelTest, ParseApiLevel) { EXPECT_FALSE(ParseApiLevel("")); EXPECT_FALSE(ParseApiLevel("A")); - EXPECT_TRUE(ParseApiLevel("current").has_value()); - EXPECT_EQ(FUTURE_API_LEVEL, ParseApiLevel("current").value()); + EXPECT_TRUE(ParseApiLevel("current").hasValue()); + EXPECT_EQ(FUTURE_API_LEVEL, ParseApiLevel("current").getValue()); - EXPECT_TRUE(ParseApiLevel("16").has_value()); - EXPECT_EQ(16l, ParseApiLevel("16").value()); + EXPECT_TRUE(ParseApiLevel("16").hasValue()); + EXPECT_EQ(16l, ParseApiLevel("16").getValue()); } diff --git a/vndk/tools/header-checker/src/utils/string_utils_test.cpp b/vndk/tools/header-checker/src/utils/string_utils_test.cpp index 4ad007440..98f25ca4c 100644 --- a/vndk/tools/header-checker/src/utils/string_utils_test.cpp +++ b/vndk/tools/header-checker/src/utils/string_utils_test.cpp @@ -83,14 +83,14 @@ TEST(StringUtilsTest, ParseInt) { EXPECT_FALSE(ParseInt("0xa")); EXPECT_FALSE(ParseInt("16h")); - EXPECT_TRUE(ParseInt("0").has_value()); - EXPECT_EQ(0, ParseInt("0").value()); + EXPECT_TRUE(ParseInt("0").hasValue()); + EXPECT_EQ(0, ParseInt("0").getValue()); - EXPECT_TRUE(ParseInt("16").has_value()); - EXPECT_EQ(16, ParseInt("16").value()); + EXPECT_TRUE(ParseInt("16").hasValue()); + EXPECT_EQ(16, ParseInt("16").getValue()); - EXPECT_TRUE(ParseInt("-16").has_value()); - EXPECT_EQ(-16, ParseInt("-16").value()); + EXPECT_TRUE(ParseInt("-16").hasValue()); + EXPECT_EQ(-16, ParseInt("-16").getValue()); } From edab64ee477a76961d362c58ec72c5ba6ceaacf1 Mon Sep 17 00:00:00 2001 From: Neha Jain Date: Thu, 29 Jun 2023 07:48:10 +0000 Subject: [PATCH 4/4] Update API 34 release config and emulator files for UDC Beta4 Bug: 289293448 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9772721883a3bc1f254c78841278b3478f94605f) Merged-In: Iccd86693424572eaf003fda9600ba7293b08a8f4 Change-Id: Iccd86693424572eaf003fda9600ba7293b08a8f4 --- sdk/plat_tools_source.prop_template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template index 257b9543a..779c92505 100644 --- a/sdk/plat_tools_source.prop_template +++ b/sdk/plat_tools_source.prop_template @@ -1,2 +1,2 @@ Pkg.UserSrc=false -Pkg.Revision=34.0.3 +Pkg.Revision=34.0.4