├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── laifeng │ │ └── sopcastdemo │ │ ├── LandscapeActivity.java │ │ ├── MainActivity.java │ │ ├── PartActivity.java │ │ ├── PortraitActivity.java │ │ ├── ScreenActivity.java │ │ └── ui │ │ ├── Gusterpolator.java │ │ ├── MultiToggleImageButton.java │ │ └── TopRightWeightedLayout.java │ └── res │ ├── drawable │ ├── blue_tile.xml │ ├── button_background_pressed_dark.xml │ ├── green_tile.xml │ ├── ic_flash_off.xml │ ├── ic_flash_on.xml │ ├── ic_focus_off.xml │ ├── ic_focus_on.xml │ ├── ic_mic_off.xml │ ├── ic_mic_on.xml │ ├── ic_render_off.xml │ ├── ic_render_on.xml │ ├── ic_switch_camera_back.xml │ ├── ic_switch_camera_front.xml │ ├── purple_tile.xml │ ├── red_tile.xml │ ├── tag_background.xml │ └── yellow_tile.xml │ ├── layout │ ├── activity_landscape.xml │ ├── activity_main.xml │ ├── activity_part.xml │ ├── activity_portrait.xml │ ├── activity_screen.xml │ ├── address_dialog.xml │ └── grid_item.xml │ ├── mipmap-hdpi │ ├── ic_flash_auto_disabled.png │ ├── ic_flash_auto_normal.png │ ├── ic_flash_off_disabled.png │ ├── ic_flash_off_normal.png │ ├── ic_flash_on_disabled.png │ ├── ic_flash_on_normal.png │ ├── ic_focus_off_normal.png │ ├── ic_focus_on_normal.png │ ├── ic_launcher.png │ ├── ic_mic_off_normal.png │ ├── ic_mic_on_normal.png │ ├── ic_record_start.png │ ├── ic_record_stop.png │ ├── ic_render_off_normal.png │ ├── ic_render_on_normal.png │ ├── ic_switch_camera_back_disabled.png │ ├── ic_switch_camera_back_normal.png │ ├── ic_switch_camera_front_disabled.png │ ├── ic_switch_camera_front_normal.png │ └── watermark.png │ ├── values-w820dp │ └── dimens.xml │ ├── values-zh │ └── strings.xml │ └── values │ ├── arrays.xml │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── document └── en │ ├── README.md │ └── sopcast.jpg ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── sopcast-sdk ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── gray │ │ ├── fragmentshader.glsl │ │ └── vertexshader.glsl │ └── null │ │ ├── fragmentshader.glsl │ │ └── vertexshader.glsl │ ├── java │ └── com │ │ └── laifeng │ │ └── sopcastsdk │ │ ├── audio │ │ ├── AudioEncoder.java │ │ ├── AudioProcessor.java │ │ ├── AudioUtils.java │ │ └── OnAudioEncodeListener.java │ │ ├── blacklist │ │ └── BlackListHelper.java │ │ ├── camera │ │ ├── CameraData.java │ │ ├── CameraHolder.java │ │ ├── CameraListener.java │ │ ├── CameraUtils.java │ │ ├── CameraZoomListener.java │ │ ├── exception │ │ │ ├── CameraDisabledException.java │ │ │ ├── CameraHardwareException.java │ │ │ ├── CameraNotSupportException.java │ │ │ └── NoCameraException.java │ │ └── focus │ │ │ ├── FocusManager.java │ │ │ └── FocusPieView.java │ │ ├── configuration │ │ ├── AudioConfiguration.java │ │ ├── CameraConfiguration.java │ │ └── VideoConfiguration.java │ │ ├── constant │ │ └── SopCastConstant.java │ │ ├── controller │ │ ├── StreamController.java │ │ ├── audio │ │ │ ├── IAudioController.java │ │ │ └── NormalAudioController.java │ │ └── video │ │ │ ├── CameraVideoController.java │ │ │ ├── IVideoController.java │ │ │ └── ScreenVideoController.java │ │ ├── entity │ │ ├── Frame.java │ │ ├── Watermark.java │ │ └── WatermarkPosition.java │ │ ├── mediacodec │ │ ├── AudioMediaCodec.java │ │ ├── MediaCodecHelper.java │ │ └── VideoMediaCodec.java │ │ ├── screen │ │ ├── ScreenRecordActivity.java │ │ └── ScreenRecordEncoder.java │ │ ├── stream │ │ ├── amf │ │ │ ├── AmfArray.java │ │ │ ├── AmfBoolean.java │ │ │ ├── AmfData.java │ │ │ ├── AmfDecoder.java │ │ │ ├── AmfMap.java │ │ │ ├── AmfNull.java │ │ │ ├── AmfNumber.java │ │ │ ├── AmfObject.java │ │ │ ├── AmfString.java │ │ │ ├── AmfType.java │ │ │ ├── AmfUndefined.java │ │ │ └── Util.java │ │ ├── packer │ │ │ ├── AnnexbHelper.java │ │ │ ├── Packer.java │ │ │ ├── flv │ │ │ │ ├── FlvPacker.java │ │ │ │ └── FlvPackerHelper.java │ │ │ └── rtmp │ │ │ │ └── RtmpPacker.java │ │ └── sender │ │ │ ├── Sender.java │ │ │ ├── local │ │ │ └── LocalSender.java │ │ │ ├── rtmp │ │ │ ├── Crypto.java │ │ │ ├── RtmpSender.java │ │ │ ├── Util.java │ │ │ ├── io │ │ │ │ ├── OnReadListener.java │ │ │ │ ├── OnWriteListener.java │ │ │ │ ├── ReadThread.java │ │ │ │ ├── RtmpConnectListener.java │ │ │ │ ├── RtmpConnection.java │ │ │ │ ├── RtmpDecoder.java │ │ │ │ ├── SessionInfo.java │ │ │ │ ├── StoreChunk.java │ │ │ │ └── WriteThread.java │ │ │ └── packets │ │ │ │ ├── Abort.java │ │ │ │ ├── Acknowledgement.java │ │ │ │ ├── Audio.java │ │ │ │ ├── Chunk.java │ │ │ │ ├── ChunkHeader.java │ │ │ │ ├── ChunkType.java │ │ │ │ ├── Command.java │ │ │ │ ├── ContentData.java │ │ │ │ ├── Data.java │ │ │ │ ├── Handshake.java │ │ │ │ ├── MessageType.java │ │ │ │ ├── SetChunkSize.java │ │ │ │ ├── SetPeerBandwidth.java │ │ │ │ ├── UserControl.java │ │ │ │ ├── VariableBodyRtmpPacket.java │ │ │ │ ├── Video.java │ │ │ │ └── WindowAckSize.java │ │ │ └── sendqueue │ │ │ ├── ISendQueue.java │ │ │ ├── NormalSendQueue.java │ │ │ └── SendQueueListener.java │ │ ├── ui │ │ ├── CameraLivingView.java │ │ ├── CameraView.java │ │ └── RenderSurfaceView.java │ │ ├── utils │ │ ├── SopCastLog.java │ │ ├── SopCastUtils.java │ │ └── WeakHandler.java │ │ └── video │ │ ├── GLSLFileUtils.java │ │ ├── GlUtil.java │ │ ├── InputSurface.java │ │ ├── MyRecorder.java │ │ ├── MyRenderer.java │ │ ├── OnVideoEncodeListener.java │ │ ├── RenderScreen.java │ │ ├── RenderSrfTex.java │ │ └── effect │ │ ├── Effect.java │ │ ├── GrayEffect.java │ │ └── NullEffect.java │ └── res │ ├── drawable │ ├── camera_focus_ring_fail.png │ └── camera_focus_ring_success.png │ ├── layout │ └── layout_camera_view.xml │ └── values │ ├── attr.xml │ └── strings.xml └── sopcast.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | SopCastComponent 3 | 4 | Copyright (c) 2017, QJoy 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the docume 11 | ntation and/or other materials provided with the distribution. 12 | - Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this 13 | software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUD 16 | ING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN N 17 | O EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR C 18 | ONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P 19 | ROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 20 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBI 21 | LITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /src/androidTest 3 | /src/test 4 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.laifeng.sopcastdemo" 9 | minSdkVersion 14 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | sourceSets { 21 | main() { 22 | jniLibs.srcDirs = ['libs'] 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | compile fileTree(dir: 'libs', include: ['*.jar']) 29 | compile 'com.android.support:appcompat-v7:23.4.0' 30 | compile project(':sopcast-sdk') 31 | } 32 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/jim_Feng/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 23 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/laifeng/sopcastdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.laifeng.sopcastdemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.GridView; 10 | import android.widget.RelativeLayout; 11 | import android.widget.TextView; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | 15 | @Override 16 | public void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | GridView grid = (GridView) findViewById(R.id.grid); 20 | grid.setAdapter(new HoloTilesAdapter()); 21 | } 22 | 23 | 24 | public class HoloTilesAdapter extends BaseAdapter { 25 | 26 | private static final int TILES_COUNT = 4; 27 | 28 | private final int[] DRAWABLES = { 29 | R.drawable.blue_tile, 30 | R.drawable.green_tile, 31 | R.drawable.purple_tile, 32 | R.drawable.yellow_tile 33 | }; 34 | 35 | @Override 36 | public int getCount() { 37 | return TILES_COUNT; 38 | } 39 | 40 | @Override 41 | public Object getItem(int position) { 42 | return null; 43 | } 44 | 45 | @Override 46 | public long getItemId(int position) { 47 | return position; 48 | } 49 | 50 | @Override 51 | public View getView(int position, View convertView, ViewGroup parent) { 52 | 53 | RelativeLayout v; 54 | if (convertView == null) { 55 | v = (RelativeLayout) getLayoutInflater().inflate(R.layout.grid_item, parent, false); 56 | } else { 57 | v = (RelativeLayout) convertView; 58 | } 59 | v.setBackgroundResource(DRAWABLES[position % 5]); 60 | 61 | TextView textView1 = (TextView) v.findViewById(R.id.textView1); 62 | TextView textView2 = (TextView) v.findViewById(R.id.textView2); 63 | 64 | String string1 = "", string2 = ""; 65 | if(position == 0) { 66 | string1 = "Portrait"; 67 | string2 = "Flv + Local"; 68 | } else if(position == 1) { 69 | string1 = "Landscape"; 70 | string2 = "Rtmp"; 71 | } else if(position == 2) { 72 | string1 = "Portrait"; 73 | string2 = "Part"; 74 | } else if(position == 3) { 75 | string1 = "Portrait"; 76 | string2 = "Screen + Rtmp"; 77 | } 78 | textView1.setText(string1); 79 | textView2.setText(string2); 80 | 81 | final int currentPosition = position; 82 | v.setOnClickListener(new View.OnClickListener() { 83 | @Override 84 | public void onClick(View v) { 85 | if(currentPosition == 0) { 86 | goPortraitAndLocal(); 87 | } else if(currentPosition == 1) { 88 | goLandscapeAndRtmp(); 89 | } else if(currentPosition == 2) { 90 | goPart(); 91 | } else if(currentPosition == 3) { 92 | goScreen(); 93 | } 94 | } 95 | }); 96 | return v; 97 | } 98 | } 99 | 100 | private void goPortraitAndLocal() { 101 | Intent intent = new Intent(this, PortraitActivity.class); 102 | startActivity(intent); 103 | } 104 | 105 | private void goLandscapeAndRtmp() { 106 | Intent intent = new Intent(this, LandscapeActivity.class); 107 | startActivity(intent); 108 | } 109 | 110 | private void goPart() { 111 | Intent intent = new Intent(this, PartActivity.class); 112 | startActivity(intent); 113 | } 114 | 115 | private void goScreen() { 116 | Intent intent = new Intent(this, ScreenActivity.class); 117 | startActivity(intent); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/laifeng/sopcastdemo/PartActivity.java: -------------------------------------------------------------------------------- 1 | package com.laifeng.sopcastdemo; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import com.laifeng.sopcastsdk.ui.CameraLivingView; 6 | 7 | public class PartActivity extends Activity { 8 | private CameraLivingView mLFLiveView; 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_part); 14 | mLFLiveView = (CameraLivingView) findViewById(R.id.liveView); 15 | } 16 | 17 | @Override 18 | protected void onDestroy() { 19 | super.onDestroy(); 20 | mLFLiveView.release(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/laifeng/sopcastdemo/ui/Gusterpolator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.laifeng.sopcastdemo.ui; 18 | 19 | import android.animation.TimeInterpolator; 20 | 21 | /** 22 | * Interpolator that uses a Bezier derived S shaped curve. 23 | */ 24 | public class Gusterpolator implements TimeInterpolator { 25 | /** An instance of {@link Gusterpolator}. */ 26 | public static final Gusterpolator INSTANCE = new Gusterpolator(); 27 | 28 | /** 29 | * To avoid users of this class creating multiple copies needlessly, the constructor is 30 | * private. 31 | */ 32 | private Gusterpolator() {} 33 | 34 | /** 35 | * Lookup table values. 36 | * Generated using a Bezier curve from (0,0) to (1,1) with control points: 37 | * P0 (0,0) 38 | * P1 (0.4, 0) 39 | * P2 (0.2, 1.0) 40 | * P3 (1.0, 1.0) 41 | * 42 | * Values sampled with x at regular intervals between 0 and 1. 43 | */ 44 | private static final float[] VALUES = new float[] { 45 | 0.0f, 0.0002f, 0.0009f, 0.0019f, 0.0036f, 0.0059f, 0.0086f, 0.0119f, 0.0157f, 0.0209f, 46 | 0.0257f, 0.0321f, 0.0392f, 0.0469f, 0.0566f, 0.0656f, 0.0768f, 0.0887f, 0.1033f, 47 | 0.1186f, 0.1349f, 0.1519f, 0.1696f, 0.1928f, 0.2121f, 0.237f, 0.2627f, 0.2892f, 0.3109f, 48 | 0.3386f, 0.3667f, 0.3952f, 0.4241f, 0.4474f, 0.4766f, 0.5f, 0.5234f, 0.5468f, 0.5701f, 49 | 0.5933f, 0.6134f, 0.6333f, 0.6531f, 0.6698f, 0.6891f, 0.7054f, 0.7214f, 0.7346f, 50 | 0.7502f, 0.763f, 0.7756f, 0.7879f, 0.8f, 0.8107f, 0.8212f, 0.8326f, 0.8415f, 0.8503f, 51 | 0.8588f, 0.8672f, 0.8754f, 0.8833f, 0.8911f, 0.8977f, 0.9041f, 0.9113f, 0.9165f, 52 | 0.9232f, 0.9281f, 0.9328f, 0.9382f, 0.9434f, 0.9476f, 0.9518f, 0.9557f, 0.9596f, 53 | 0.9632f, 0.9662f, 0.9695f, 0.9722f, 0.9753f, 0.9777f, 0.9805f, 0.9826f, 0.9847f, 54 | 0.9866f, 0.9884f, 0.9901f, 0.9917f, 0.9931f, 0.9944f, 0.9955f, 0.9964f, 0.9973f, 55 | 0.9981f, 0.9986f, 0.9992f, 0.9995f, 0.9998f, 1.0f, 1.0f 56 | }; 57 | 58 | private static final float STEP_SIZE = 1.0f / (VALUES.length - 1); 59 | 60 | @Override 61 | public float getInterpolation(float input) { 62 | if (input >= 1.0f) { 63 | return 1.0f; 64 | } 65 | 66 | if (input <= 0f) { 67 | return 0f; 68 | } 69 | 70 | int position = Math.min( 71 | (int)(input * (VALUES.length - 1)), 72 | VALUES.length - 2); 73 | 74 | float quantized = position * STEP_SIZE; 75 | float difference = input - quantized; 76 | float weight = difference / STEP_SIZE; 77 | 78 | return VALUES[position] + weight * (VALUES[position + 1] - VALUES[position]); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/blue_tile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_background_pressed_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 22 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/green_tile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flash_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_focus_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_focus_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mic_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mic_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_render_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_render_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_switch_camera_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_switch_camera_front.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/purple_tile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/red_tile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 22 | 24 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/yellow_tile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_landscape.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 24 | 28 | 32 | 36 | 40 | 44 | 45 | 46 | 52 | 53 | 58 | 59 | 60 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_part.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 25 | 29 | 33 | 37 | 41 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_portrait.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 24 | 28 | 32 | 36 | 40 | 44 | 45 | 46 | 53 | 54 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 |