-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tv-casting-app/android: Open commissioning window through JNI in a ne…
…w fragment (#17655)
- Loading branch information
1 parent
3d19ea8
commit 5596357
Showing
15 changed files
with
618 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
...app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.chip.casting.app; | ||
|
||
import android.content.Context; | ||
import android.net.nsd.NsdManager; | ||
import android.net.wifi.WifiManager; | ||
import android.os.Bundle; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.Button; | ||
import androidx.annotation.Nullable; | ||
import androidx.fragment.app.Fragment; | ||
import com.chip.casting.dnssd.CommissionerDiscoveryListener; | ||
import com.chip.casting.util.GlobalCastingConstants; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** A {@link Fragment} to discover commissioners on the network */ | ||
public class CommissionerDiscoveryFragment extends Fragment { | ||
|
||
public CommissionerDiscoveryFragment() {} | ||
|
||
/** | ||
* Use this factory method to create a new instance of this fragment using the provided | ||
* parameters. | ||
* | ||
* @return A new instance of fragment CommissionerDiscoveryFragment. | ||
*/ | ||
public static CommissionerDiscoveryFragment newInstance() { | ||
return new CommissionerDiscoveryFragment(); | ||
} | ||
|
||
@Override | ||
public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
startCommissionerDiscovery(); | ||
} | ||
|
||
@Override | ||
public View onCreateView( | ||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
// Inflate the layout for this fragment | ||
return inflater.inflate(R.layout.fragment_commissioner_discovery, container, false); | ||
} | ||
|
||
@Override | ||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
super.onViewCreated(view, savedInstanceState); | ||
Button manualCommissioningButton = getView().findViewById(R.id.manualCommissioningButton); | ||
Callback callback = (Callback) this.getActivity(); | ||
manualCommissioningButton.setOnClickListener( | ||
new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
callback.handleManualCommissioningButtonClicked(); | ||
} | ||
}); | ||
} | ||
|
||
private void startCommissionerDiscovery() { | ||
WifiManager wifi = (WifiManager) this.getContext().getSystemService(Context.WIFI_SERVICE); | ||
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); | ||
multicastLock.setReferenceCounted(true); | ||
multicastLock.acquire(); | ||
|
||
CastingContext castingContext = new CastingContext(this.getActivity()); | ||
NsdManager.DiscoveryListener commissionerDiscoveryListener = | ||
new CommissionerDiscoveryListener(castingContext); | ||
|
||
NsdManager nsdManager = castingContext.getNsdManager(); | ||
nsdManager.discoverServices( | ||
GlobalCastingConstants.CommissionerServiceType, | ||
NsdManager.PROTOCOL_DNS_SD, | ||
commissionerDiscoveryListener); | ||
|
||
// Stop discovery after specified timeout | ||
Executors.newSingleThreadScheduledExecutor() | ||
.schedule( | ||
new Runnable() { | ||
@Override | ||
public void run() { | ||
nsdManager.stopServiceDiscovery(commissionerDiscoveryListener); | ||
multicastLock.release(); | ||
} | ||
}, | ||
10, | ||
TimeUnit.SECONDS); | ||
} | ||
|
||
/** Interface for notifying the host. */ | ||
interface Callback { | ||
/** Notifies listener of Skip to manual Commissioning Button click. */ | ||
void handleManualCommissioningButtonClicked(); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
...casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissioningFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.chip.casting.app; | ||
|
||
import android.os.Bundle; | ||
import android.util.Log; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.TextView; | ||
import androidx.annotation.Nullable; | ||
import androidx.fragment.app.Fragment; | ||
import com.chip.casting.TvCastingApp; | ||
import com.chip.casting.dnssd.CommissionerDiscoveryListener; | ||
import com.chip.casting.util.GlobalCastingConstants; | ||
|
||
/** A {@link Fragment} to get the TV Casting App commissioned. */ | ||
public class CommissioningFragment extends Fragment { | ||
private static final String TAG = CommissionerDiscoveryListener.class.getSimpleName(); | ||
|
||
private final TvCastingApp tvCastingApp; | ||
|
||
public CommissioningFragment(TvCastingApp tvCastingApp) { | ||
this.tvCastingApp = tvCastingApp; | ||
} | ||
|
||
/** | ||
* Use this factory method to create a new instance of this fragment using the provided | ||
* parameters. | ||
* | ||
* @param tvCastingApp TV Casting App (JNI) | ||
* @return A new instance of fragment CommissioningFragment. | ||
*/ | ||
// TODO: Rename and change types and number of parameters | ||
public static CommissioningFragment newInstance(TvCastingApp tvCastingApp) { | ||
return new CommissioningFragment(tvCastingApp); | ||
} | ||
|
||
@Override | ||
public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
} | ||
|
||
@Override | ||
public View onCreateView( | ||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
// Inflate the layout for this fragment | ||
return inflater.inflate(R.layout.fragment_commissioning, container, false); | ||
} | ||
|
||
@Override | ||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||
super.onViewCreated(view, savedInstanceState); | ||
boolean status = | ||
tvCastingApp.openBasicCommissioningWindow( | ||
GlobalCastingConstants.CommissioningWindowDurationSecs); | ||
Log.d( | ||
TAG, | ||
"CommissioningFragment.onViewCreated tvCastingApp.openBasicCommissioningWindow returned " | ||
+ status); | ||
TextView commissioningWindowStatusView = getView().findViewById(R.id.commissioningWindowStatus); | ||
TextView onboardingPayloadView = getView().findViewById(R.id.onboardingPayload); | ||
if (status == true) { | ||
commissioningWindowStatusView.setText("Commissioning window opened!"); | ||
onboardingPayloadView.setText("Onboarding Pin: " + GlobalCastingConstants.SetupPasscode); | ||
} else { | ||
commissioningWindowStatusView.setText("Commissioning window could not be opened!"); | ||
} | ||
} | ||
} |
105 changes: 64 additions & 41 deletions
105
examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,84 @@ | ||
package com.chip.casting.app; | ||
|
||
import android.content.Context; | ||
import android.net.nsd.NsdManager; | ||
import android.net.wifi.WifiManager; | ||
import android.os.Bundle; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
import androidx.fragment.app.Fragment; | ||
import androidx.fragment.app.FragmentTransaction; | ||
import chip.appserver.ChipAppServer; | ||
import chip.platform.AndroidBleManager; | ||
import chip.platform.AndroidChipPlatform; | ||
import chip.platform.ChipMdnsCallbackImpl; | ||
import chip.platform.DiagnosticDataProviderImpl; | ||
import chip.platform.NsdManagerServiceResolver; | ||
import chip.platform.PreferencesConfigurationManager; | ||
import chip.platform.PreferencesKeyValueStoreManager; | ||
import com.chip.casting.DACProviderStub; | ||
import com.chip.casting.TvCastingApp; | ||
import com.chip.casting.dnssd.CommissionerDiscoveryListener; | ||
import com.chip.casting.util.GlobalCastingConstants; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
public class MainActivity extends AppCompatActivity { | ||
public class MainActivity extends AppCompatActivity | ||
implements CommissionerDiscoveryFragment.Callback { | ||
|
||
private ChipAppServer chipAppServer; | ||
private TvCastingApp tvCastingApp; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_main); | ||
startCommissionerDiscovery(); | ||
|
||
testJni(); | ||
initJni(); | ||
|
||
Fragment fragment = CommissionerDiscoveryFragment.newInstance(); | ||
getSupportFragmentManager() | ||
.beginTransaction() | ||
.add(R.id.main_fragment_container, fragment, fragment.getClass().getSimpleName()) | ||
.commit(); | ||
} | ||
|
||
@Override | ||
public void handleManualCommissioningButtonClicked() { | ||
showFragment(CommissioningFragment.newInstance(tvCastingApp)); | ||
} | ||
|
||
private void startCommissionerDiscovery() { | ||
WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); | ||
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); | ||
multicastLock.setReferenceCounted(true); | ||
multicastLock.acquire(); | ||
|
||
CastingContext castingContext = new CastingContext(this); | ||
NsdManager.DiscoveryListener commissionerDiscoveryListener = | ||
new CommissionerDiscoveryListener(castingContext); | ||
|
||
NsdManager nsdManager = castingContext.getNsdManager(); | ||
nsdManager.discoverServices( | ||
GlobalCastingConstants.CommissionerServiceType, | ||
NsdManager.PROTOCOL_DNS_SD, | ||
commissionerDiscoveryListener); | ||
|
||
// Stop discovery after specified timeout | ||
Executors.newSingleThreadScheduledExecutor() | ||
.schedule( | ||
new Runnable() { | ||
@Override | ||
public void run() { | ||
nsdManager.stopServiceDiscovery(commissionerDiscoveryListener); | ||
multicastLock.release(); | ||
} | ||
}, | ||
10, | ||
TimeUnit.SECONDS); | ||
private void initJni() { | ||
tvCastingApp = | ||
new TvCastingApp((app, clusterId, duration) -> app.openBasicCommissioningWindow(duration)); | ||
|
||
tvCastingApp.setDACProvider(new DACProviderStub()); | ||
Context applicationContext = this.getApplicationContext(); | ||
AndroidChipPlatform chipPlatform = | ||
new AndroidChipPlatform( | ||
new AndroidBleManager(), | ||
new PreferencesKeyValueStoreManager(applicationContext), | ||
new PreferencesConfigurationManager(applicationContext), | ||
new NsdManagerServiceResolver(applicationContext), | ||
new ChipMdnsCallbackImpl(), | ||
new DiagnosticDataProviderImpl(applicationContext)); | ||
|
||
chipPlatform.updateCommissionableDataProviderData( | ||
null, null, 0, GlobalCastingConstants.SetupPasscode, GlobalCastingConstants.Discriminator); | ||
|
||
chipAppServer = new ChipAppServer(); | ||
chipAppServer.startApp(); | ||
} | ||
|
||
private void showFragment(Fragment fragment, boolean showOnBack) { | ||
System.out.println( | ||
"showFragment called with " + fragment.getClass().getSimpleName() + " and " + showOnBack); | ||
FragmentTransaction fragmentTransaction = | ||
getSupportFragmentManager() | ||
.beginTransaction() | ||
.replace(R.id.main_fragment_container, fragment, fragment.getClass().getSimpleName()); | ||
if (showOnBack) { | ||
fragmentTransaction.addToBackStack(null); | ||
} | ||
|
||
fragmentTransaction.commit(); | ||
} | ||
|
||
/** TBD: Temp dummy function for testing */ | ||
private void testJni() { | ||
TvCastingApp tvCastingApp = | ||
new TvCastingApp((app, clusterId, endpoint) -> app.doSomethingInCpp(endpoint)); | ||
tvCastingApp.doSomethingInCpp(0); | ||
private void showFragment(Fragment fragment) { | ||
showFragment(fragment, true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/DACProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* 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.chip.casting; | ||
|
||
public interface DACProvider { | ||
byte[] GetCertificationDeclaration(); | ||
|
||
byte[] GetFirmwareInformation(); | ||
|
||
byte[] GetDeviceAttestationCert(); | ||
|
||
byte[] GetProductAttestationIntermediateCert(); | ||
|
||
byte[] GetDeviceAttestationCertPrivateKey(); | ||
|
||
byte[] GetDeviceAttestationCertPublicKeyKey(); | ||
} |
57 changes: 57 additions & 0 deletions
57
examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/DACProviderStub.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.chip.casting; | ||
|
||
import android.util.Base64; | ||
|
||
public class DACProviderStub implements DACProvider { | ||
|
||
private String kDevelopmentDAC_Cert_FFF1_8001 = | ||
"MIIB5zCCAY6gAwIBAgIIac3xDenlTtEwCgYIKoZIzj0EAwIwPTElMCMGA1UEAwwcTWF0dGVyIERldiBQQUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwIBcNMjIwMjA1MDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMFMxJTAjBgNVBAMMHE1hdHRlciBEZXYgREFDIDB4RkZGMS8weDgwMDExFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGConwCAgwEODAwMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEY6xpNCkQoOVYj8b/Vrtj5i7M7LFI99TrA+5VJgFBV2fRalxmP3k+SRIyYLgpenzX58/HsxaznZjpDSk3dzjoKjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSI3eezADgpMs/3NMBGJIEPRBaKbzAfBgNVHSMEGDAWgBRjVA5H9kscONE4hKRi0WwZXY/7PDAKBggqhkjOPQQDAgNHADBEAiABJ6J7S0RhDuL83E0reIVWNmC8D3bxchntagjfsrPBzQIga1ngr0Xz6yqFuRnTVzFSjGAoxBUjlUXhCOTlTnCXE1M="; | ||
|
||
private String kDevelopmentDAC_PrivateKey_FFF1_8001 = | ||
"qrYAroroqrfXNifCF7fCBHCcppRq9fL3UwgzpStE+/8="; | ||
|
||
private String kDevelopmentDAC_PublicKey_FFF1_8001 = | ||
"BEY6xpNCkQoOVYj8b/Vrtj5i7M7LFI99TrA+5VJgFBV2fRalxmP3k+SRIyYLgpenzX58/HsxaznZjpDSk3dzjoI="; | ||
|
||
private String KPAI_FFF1_8000_Cert_Array = | ||
"MIIByzCCAXGgAwIBAgIIVq2CIq2UW2QwCgYIKoZIzj0EAwIwMDEYMBYGA1UEAwwPTWF0dGVyIFRlc3QgUEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTAgFw0yMjAyMDUwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowPTElMCMGA1UEAwwcTWF0dGVyIERldiBQQUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARBmpMVwhc+DIyHbQPM/JRIUmR/f+xeUIL0BZko7KiUxZQVEwmsYx5MsDOSr2hLC6+35ls7gWLC9Sv5MbjneqqCo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUY1QOR/ZLHDjROISkYtFsGV2P+zwwHwYDVR0jBBgwFoAUav0idx9RH+y/FkGXZxDc3DGhcX4wCgYIKoZIzj0EAwIDSAAwRQIhALLvJ/Sa6bUPuR7qyUxNC9u415KcbLiPrOUpNo0SBUwMAiBlXckrhr2QmIKmxiF3uCXX0F7b58Ivn+pxIg5+pwP4kQ=="; | ||
|
||
/** | ||
* format_version = 1 vendor_id = 0xFFF1 product_id_array = [ 0x8000,0x8001...0x8063] | ||
* device_type_id = 0x1234 certificate_id = "ZIG20141ZB330001-24" security_level = 0 | ||
* security_information = 0 version_number = 0x2694 certification_type = 0 dac_origin_vendor_id is | ||
* not present dac_origin_product_id is not present | ||
*/ | ||
private String kCertificationDeclaration = | ||
"MIICGQYJKoZIhvcNAQcCoIICCjCCAgYCAQMxDTALBglghkgBZQMEAgEwggFxBgkqhkiG9w0BBwGgggFiBIIBXhUkAAElAfH/NgIFAIAFAYAFAoAFA4AFBIAFBYAFBoAFB4AFCIAFCYAFCoAFC4AFDIAFDYAFDoAFD4AFEIAFEYAFEoAFE4AFFIAFFYAFFoAFF4AFGIAFGYAFGoAFG4AFHIAFHYAFHoAFH4AFIIAFIYAFIoAFI4AFJIAFJYAFJoAFJ4AFKIAFKYAFKoAFK4AFLIAFLYAFLoAFL4AFMIAFMYAFMoAFM4AFNIAFNYAFNoAFN4AFOIAFOYAFOoAFO4AFPIAFPYAFPoAFP4AFQIAFQYAFQoAFQ4AFRIAFRYAFRoAFR4AFSIAFSYAFSoAFS4AFTIAFTYAFToAFT4AFUIAFUYAFUoAFU4AFVIAFVYAFVoAFV4AFWIAFWYAFWoAFW4AFXIAFXYAFXoAFX4AFYIAFYYAFYoAFY4AYJAMWLAQTWklHMjAxNDJaQjMzMDAwMy0yNCQFACQGACUHlCYkCAAYMX0wewIBA4AUYvqCM1ms+qmWPhz6FArd9QTzcWAwCwYJYIZIAWUDBAIBMAoGCCqGSM49BAMCBEcwRQIgJOXR9Hp9ew0gaibvaZt8l1e3LUaQid4xkuZ4x0Xn9gwCIQD4qi+nEfy3m5fjl87aZnuuRk4r0//fw8zteqjKX0wafA=="; | ||
|
||
@Override | ||
public byte[] GetCertificationDeclaration() { | ||
return Base64.decode(kCertificationDeclaration, Base64.DEFAULT); | ||
} | ||
|
||
@Override | ||
public byte[] GetFirmwareInformation() { | ||
return new byte[0]; | ||
} | ||
|
||
@Override | ||
public byte[] GetDeviceAttestationCert() { | ||
return Base64.decode(kDevelopmentDAC_Cert_FFF1_8001, Base64.DEFAULT); | ||
} | ||
|
||
@Override | ||
public byte[] GetProductAttestationIntermediateCert() { | ||
return Base64.decode(KPAI_FFF1_8000_Cert_Array, Base64.DEFAULT); | ||
} | ||
|
||
@Override | ||
public byte[] GetDeviceAttestationCertPrivateKey() { | ||
return Base64.decode(kDevelopmentDAC_PrivateKey_FFF1_8001, Base64.DEFAULT); | ||
} | ||
|
||
@Override | ||
public byte[] GetDeviceAttestationCertPublicKeyKey() { | ||
return Base64.decode(kDevelopmentDAC_PublicKey_FFF1_8001, Base64.DEFAULT); | ||
} | ||
} |
Oops, something went wrong.