Procházet zdrojové kódy

android: bump minimum API level to 23

Android < 23 is currently less than 3% for us so let's try to lower the
maintenance burden. Users can still download an older version no problem.
j8
Saúl Ibarra Corretgé před 4 roky
rodič
revize
5cf9a76f9e

+ 2
- 10
android/app/src/main/java/org/jitsi/meet/MainActivity.java Zobrazit soubor

@@ -23,7 +23,6 @@ import android.content.IntentFilter;
23 23
 import android.content.RestrictionEntry;
24 24
 import android.content.RestrictionsManager;
25 25
 import android.net.Uri;
26
-import android.os.Build;
27 26
 import android.os.Bundle;
28 27
 import android.provider.Settings;
29 28
 import android.util.Log;
@@ -96,7 +95,7 @@ public class MainActivity extends JitsiMeetActivity {
96 95
         // In Debug builds React needs permission to write over other apps in
97 96
         // order to display the warning and error overlays.
98 97
         if (BuildConfig.DEBUG) {
99
-            if (canRequestOverlayPermission() && !Settings.canDrawOverlays(this)) {
98
+            if (!Settings.canDrawOverlays(this)) {
100 99
                 Intent intent
101 100
                     = new Intent(
102 101
                     Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
@@ -186,8 +185,7 @@ public class MainActivity extends JitsiMeetActivity {
186 185
 
187 186
     @Override
188 187
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
189
-        if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE
190
-                && canRequestOverlayPermission()) {
188
+        if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE) {
191 189
             if (Settings.canDrawOverlays(this)) {
192 190
                 initialize();
193 191
                 return;
@@ -232,10 +230,4 @@ public class MainActivity extends JitsiMeetActivity {
232 230
             return null;
233 231
         }
234 232
     }
235
-
236
-    private boolean canRequestOverlayPermission() {
237
-        return
238
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
239
-                && getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.M;
240
-    }
241 233
 }

+ 1
- 1
android/build.gradle Zobrazit soubor

@@ -144,7 +144,7 @@ allprojects {
144 144
 ext {
145 145
     buildToolsVersion = "29.0.3"
146 146
     compileSdkVersion = 29
147
-    minSdkVersion    = 21
147
+    minSdkVersion    = 23
148 148
     targetSdkVersion = 29
149 149
     supportLibVersion = "28.0.0"
150 150
 

+ 0
- 4
android/sdk/src/main/java/org/jitsi/meet/sdk/AudioDeviceHandlerGeneric.java Zobrazit soubor

@@ -16,11 +16,8 @@
16 16
 
17 17
 package org.jitsi.meet.sdk;
18 18
 
19
-import android.content.Context;
20 19
 import android.media.AudioDeviceInfo;
21 20
 import android.media.AudioManager;
22
-import android.os.Build;
23
-import androidx.annotation.RequiresApi;
24 21
 
25 22
 import java.util.HashSet;
26 23
 import java.util.Set;
@@ -34,7 +31,6 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
34 31
  * default it's only used on versions < O, since versions >= O use ConnectionService, but it
35 32
  * can be disabled.
36 33
  */
37
-@RequiresApi(Build.VERSION_CODES.M)
38 34
 class AudioDeviceHandlerGeneric implements
39 35
         AudioModeModule.AudioDeviceHandlerInterface,
40 36
         AudioManager.OnAudioFocusChangeListener {

+ 0
- 230
android/sdk/src/main/java/org/jitsi/meet/sdk/AudioDeviceHandlerLegacy.java Zobrazit soubor

@@ -1,230 +0,0 @@
1
-/*
2
- * Copyright @ 2017-present 8x8, Inc.
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 org.jitsi.meet.sdk;
18
-
19
-import android.content.BroadcastReceiver;
20
-import android.content.Context;
21
-import android.content.Intent;
22
-import android.content.IntentFilter;
23
-import android.content.pm.PackageManager;
24
-import android.media.AudioManager;
25
-
26
-import org.jitsi.meet.sdk.log.JitsiMeetLogger;
27
-
28
-
29
-/**
30
- * {@link AudioModeModule.AudioDeviceHandlerInterface} module implementing device handling for
31
- * legacy (pre-M) Android versions.
32
- */
33
-class AudioDeviceHandlerLegacy implements
34
-        AudioModeModule.AudioDeviceHandlerInterface,
35
-        AudioManager.OnAudioFocusChangeListener,
36
-        BluetoothHeadsetMonitor.Listener {
37
-
38
-    private final static String TAG = AudioDeviceHandlerLegacy.class.getSimpleName();
39
-
40
-    /**
41
-     * Reference to the main {@code AudioModeModule}.
42
-     */
43
-    private AudioModeModule module;
44
-
45
-    /**
46
-     * Indicator that we have lost audio focus.
47
-     */
48
-    private boolean audioFocusLost = false;
49
-
50
-    /**
51
-     * {@link AudioManager} instance used to interact with the Android audio
52
-     * subsystem.
53
-     */
54
-    private AudioManager audioManager;
55
-
56
-    /**
57
-     * {@link BluetoothHeadsetMonitor} for detecting Bluetooth device changes in
58
-     * old (< M) Android versions.
59
-     */
60
-    private BluetoothHeadsetMonitor bluetoothHeadsetMonitor;
61
-
62
-    public AudioDeviceHandlerLegacy(AudioManager audioManager) {
63
-        this.audioManager = audioManager;
64
-    }
65
-
66
-    /**
67
-     * Helper method to trigger an audio route update when Bluetooth devices are
68
-     * connected / disconnected.
69
-     */
70
-    @Override
71
-    public void onBluetoothDeviceChange(final boolean deviceAvailable) {
72
-        module.runInAudioThread(new Runnable() {
73
-            @Override
74
-            public void run() {
75
-                if (deviceAvailable) {
76
-                    module.addDevice(AudioModeModule.DEVICE_BLUETOOTH);
77
-                } else {
78
-                    module.removeDevice(AudioModeModule.DEVICE_BLUETOOTH);
79
-                }
80
-
81
-                module.updateAudioRoute();
82
-            }
83
-        });
84
-    }
85
-
86
-    /**
87
-     * Helper method to trigger an audio route update when a headset is plugged
88
-     * or unplugged.
89
-     */
90
-    private void onHeadsetDeviceChange() {
91
-        module.runInAudioThread(new Runnable() {
92
-            @Override
93
-            public void run() {
94
-                // XXX: isWiredHeadsetOn is not deprecated when used just for
95
-                // knowing if there is a wired headset connected, regardless of
96
-                // audio being routed to it.
97
-                //noinspection deprecation
98
-                if (audioManager.isWiredHeadsetOn()) {
99
-                    module.addDevice(AudioModeModule.DEVICE_HEADPHONES);
100
-                } else {
101
-                    module.removeDevice(AudioModeModule.DEVICE_HEADPHONES);
102
-                }
103
-
104
-                module.updateAudioRoute();
105
-            }
106
-        });
107
-    }
108
-
109
-    /**
110
-     * {@link AudioManager.OnAudioFocusChangeListener} interface method. Called
111
-     * when the audio focus of the system is updated.
112
-     *
113
-     * @param focusChange - The type of focus change.
114
-     */
115
-    @Override
116
-    public void onAudioFocusChange(final int focusChange) {
117
-        module.runInAudioThread(new Runnable() {
118
-            @Override
119
-            public void run() {
120
-                switch (focusChange) {
121
-                    case AudioManager.AUDIOFOCUS_GAIN: {
122
-                        JitsiMeetLogger.d(TAG + " Audio focus gained");
123
-                        // Some other application potentially stole our audio focus
124
-                        // temporarily. Restore our mode.
125
-                        if (audioFocusLost) {
126
-                            module.updateAudioRoute();
127
-                        }
128
-                        audioFocusLost = false;
129
-                        break;
130
-                    }
131
-                    case AudioManager.AUDIOFOCUS_LOSS:
132
-                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
133
-                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
134
-                        JitsiMeetLogger.d(TAG + " Audio focus lost");
135
-                        audioFocusLost = true;
136
-                        break;
137
-                    }
138
-                }
139
-            }
140
-        });
141
-    }
142
-
143
-    /**
144
-     * Helper method to set the output route to a Bluetooth device.
145
-     *
146
-     * @param enabled true if Bluetooth should use used, false otherwise.
147
-     */
148
-    private void setBluetoothAudioRoute(boolean enabled) {
149
-        if (enabled) {
150
-            audioManager.startBluetoothSco();
151
-            audioManager.setBluetoothScoOn(true);
152
-        } else {
153
-            audioManager.setBluetoothScoOn(false);
154
-            audioManager.stopBluetoothSco();
155
-        }
156
-    }
157
-
158
-    @Override
159
-    public void start(AudioModeModule audioModeModule) {
160
-        JitsiMeetLogger.i("Using " + TAG + " as the audio device handler");
161
-
162
-        module = audioModeModule;
163
-        Context context = module.getContext();
164
-
165
-        // Setup runtime device change detection.
166
-        //
167
-
168
-        // Detect changes in wired headset connections.
169
-        IntentFilter wiredHeadSetFilter = new IntentFilter(AudioManager.ACTION_HEADSET_PLUG);
170
-        BroadcastReceiver wiredHeadsetReceiver = new BroadcastReceiver() {
171
-            @Override
172
-            public void onReceive(Context context, Intent intent) {
173
-                JitsiMeetLogger.d(TAG + " Wired headset added / removed");
174
-                onHeadsetDeviceChange();
175
-            }
176
-        };
177
-        context.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
178
-
179
-        // Detect Bluetooth device changes.
180
-        bluetoothHeadsetMonitor = new BluetoothHeadsetMonitor(context, this);
181
-
182
-        // On Android < M, detect if we have an earpiece.
183
-        PackageManager pm = context.getPackageManager();
184
-        if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
185
-            module.addDevice(AudioModeModule.DEVICE_EARPIECE);
186
-        }
187
-
188
-        // Always assume there is a speaker.
189
-        module.addDevice(AudioModeModule.DEVICE_SPEAKER);
190
-    }
191
-
192
-    @Override
193
-    public void stop() {
194
-        bluetoothHeadsetMonitor.stop();
195
-        bluetoothHeadsetMonitor = null;
196
-    }
197
-
198
-    @Override
199
-    public void setAudioRoute(String device) {
200
-        // Turn speaker on / off
201
-        audioManager.setSpeakerphoneOn(device.equals(AudioModeModule.DEVICE_SPEAKER));
202
-
203
-        // Turn bluetooth on / off
204
-        setBluetoothAudioRoute(device.equals(AudioModeModule.DEVICE_BLUETOOTH));
205
-    }
206
-
207
-    @Override
208
-    public boolean setMode(int mode) {
209
-        if (mode == AudioModeModule.DEFAULT) {
210
-            audioFocusLost = false;
211
-            audioManager.setMode(AudioManager.MODE_NORMAL);
212
-            audioManager.abandonAudioFocus(this);
213
-            audioManager.setSpeakerphoneOn(false);
214
-            setBluetoothAudioRoute(false);
215
-
216
-            return true;
217
-        }
218
-
219
-        audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
220
-        audioManager.setMicrophoneMute(false);
221
-
222
-        if (audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN)
223
-                == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
224
-            JitsiMeetLogger.w(TAG + " Audio focus request failed");
225
-            return false;
226
-        }
227
-
228
-        return true;
229
-    }
230
-}

+ 1
- 12
android/sdk/src/main/java/org/jitsi/meet/sdk/AudioModeModule.java Zobrazit soubor

@@ -222,10 +222,8 @@ class AudioModeModule extends ReactContextBaseJavaModule {
222 222
 
223 223
         if (useConnectionService()) {
224 224
             audioDeviceHandler = new AudioDeviceHandlerConnectionService(audioManager);
225
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
226
-            audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
227 225
         } else {
228
-            audioDeviceHandler = new AudioDeviceHandlerLegacy(audioManager);
226
+            audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
229 227
         }
230 228
 
231 229
         audioDeviceHandler.start(this);
@@ -427,15 +425,6 @@ class AudioModeModule extends ReactContextBaseJavaModule {
427 425
         }
428 426
     }
429 427
 
430
-    /**
431
-     * Needed on the legacy handler...
432
-     *
433
-     * @return Context for the application.
434
-     */
435
-    Context getContext() {
436
-        return getReactApplicationContext();
437
-    }
438
-
439 428
     /**
440 429
      * Interface for the modules implementing the actual audio device management.
441 430
      */

+ 0
- 191
android/sdk/src/main/java/org/jitsi/meet/sdk/BluetoothHeadsetMonitor.java Zobrazit soubor

@@ -1,191 +0,0 @@
1
-/*
2
- * Copyright @ 2017-present 8x8, Inc.
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 org.jitsi.meet.sdk;
18
-
19
-import android.bluetooth.BluetoothAdapter;
20
-import android.bluetooth.BluetoothHeadset;
21
-import android.bluetooth.BluetoothProfile;
22
-import android.content.BroadcastReceiver;
23
-import android.content.Context;
24
-import android.content.Intent;
25
-import android.content.IntentFilter;
26
-import android.media.AudioManager;
27
-
28
-import org.jitsi.meet.sdk.log.JitsiMeetLogger;
29
-
30
-/**
31
- * Helper class to detect and handle Bluetooth device changes.  It monitors
32
- * Bluetooth headsets being connected / disconnected and notifies the module
33
- * about device changes when this occurs.
34
- */
35
-class BluetoothHeadsetMonitor {
36
-    private final static String TAG = BluetoothHeadsetMonitor.class.getSimpleName();
37
-
38
-    /**
39
-     * The {@link Context} in which this module executes.
40
-     */
41
-    private final Context context;
42
-
43
-    /**
44
-     * Reference to the {@link BluetoothAdapter} object, used to access Bluetooth functionality.
45
-     */
46
-    private BluetoothAdapter adapter;
47
-
48
-    /**
49
-     * Reference to a proxy object which allows us to query connected devices.
50
-     */
51
-    private BluetoothHeadset headset;
52
-
53
-    /**
54
-     * receiver registered for receiving Bluetooth connection state changes.
55
-     */
56
-    private BroadcastReceiver receiver;
57
-
58
-    /**
59
-     * Listener for receiving Bluetooth device change events.
60
-     */
61
-    private Listener listener;
62
-
63
-    public BluetoothHeadsetMonitor(Context context, Listener listener) {
64
-        this.context = context;
65
-        this.listener = listener;
66
-    }
67
-
68
-    private boolean getBluetoothHeadsetProfileProxy() {
69
-        adapter = BluetoothAdapter.getDefaultAdapter();
70
-
71
-        if (adapter == null) {
72
-            JitsiMeetLogger.w(TAG + " Device doesn't support Bluetooth");
73
-            return false;
74
-        }
75
-
76
-        // XXX: The profile listener listens for system services of the given
77
-        // type being available to the application. That is, if our Bluetooth
78
-        // adapter has the "headset" profile.
79
-        BluetoothProfile.ServiceListener listener
80
-            = new BluetoothProfile.ServiceListener() {
81
-                @Override
82
-                public void onServiceConnected(int profile, BluetoothProfile proxy) {
83
-                    if (profile == BluetoothProfile.HEADSET) {
84
-                        headset = (BluetoothHeadset) proxy;
85
-                        updateDevices();
86
-                    }
87
-                }
88
-
89
-                @Override
90
-                public void onServiceDisconnected(int profile) {
91
-                    // The logic is the same as the logic of onServiceConnected.
92
-                    onServiceConnected(profile, /* proxy */ null);
93
-                }
94
-            };
95
-
96
-        return adapter.getProfileProxy(context, listener, BluetoothProfile.HEADSET);
97
-    }
98
-
99
-    private void onBluetoothReceiverReceive(Context context, Intent intent) {
100
-        final String action = intent.getAction();
101
-
102
-        if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
103
-            // XXX: This action will be fired when a Bluetooth headset is
104
-            // connected or disconnected to the system. This is not related to
105
-            // audio routing.
106
-            int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
107
-
108
-            switch (state) {
109
-            case BluetoothHeadset.STATE_CONNECTED:
110
-            case BluetoothHeadset.STATE_DISCONNECTED:
111
-                JitsiMeetLogger.d(TAG + " BT headset connection state changed: " + state);
112
-                updateDevices();
113
-                break;
114
-            }
115
-        } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
116
-            // XXX: This action will be fired when the connection established
117
-            // with a Bluetooth headset (called a SCO connection) changes state.
118
-            // When the SCO connection is active we route audio to it.
119
-            int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
120
-
121
-            switch (state) {
122
-            case AudioManager.SCO_AUDIO_STATE_CONNECTED:
123
-            case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
124
-                JitsiMeetLogger.d(TAG + " BT SCO connection state changed: " + state);
125
-                updateDevices();
126
-                break;
127
-            }
128
-        }
129
-    }
130
-
131
-    private void registerBluetoothReceiver() {
132
-        receiver = new BroadcastReceiver() {
133
-            @Override
134
-            public void onReceive(Context context, Intent intent) {
135
-                onBluetoothReceiverReceive(context, intent);
136
-            }
137
-        };
138
-
139
-        IntentFilter filter = new IntentFilter();
140
-        filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
141
-        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
142
-
143
-        context.registerReceiver(receiver, filter);
144
-    }
145
-
146
-    /**
147
-     * Detects if there are new devices connected / disconnected and fires the
148
-     * {@link Listener} registered event.
149
-     */
150
-    private void updateDevices() {
151
-        boolean headsetAvailable = (headset != null) && !headset.getConnectedDevices().isEmpty();
152
-        listener.onBluetoothDeviceChange(headsetAvailable);
153
-    }
154
-
155
-    public void start() {
156
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
157
-
158
-        if (!audioManager.isBluetoothScoAvailableOffCall()) {
159
-            JitsiMeetLogger.w(TAG + " Bluetooth SCO is not available");
160
-            return;
161
-        }
162
-
163
-        if (!getBluetoothHeadsetProfileProxy()) {
164
-            JitsiMeetLogger.w(TAG + " Couldn't get BT profile proxy");
165
-            return;
166
-        }
167
-
168
-        registerBluetoothReceiver();
169
-
170
-        // Initial detection.
171
-        updateDevices();
172
-    }
173
-
174
-    public void stop() {
175
-        if (receiver != null) {
176
-            context.unregisterReceiver(receiver);
177
-        }
178
-
179
-        if (adapter != null && headset != null) {
180
-            adapter.closeProfileProxy(BluetoothProfile.HEADSET, headset);
181
-        }
182
-
183
-        receiver = null;
184
-        headset = null;
185
-        adapter = null;
186
-    }
187
-
188
-    interface Listener {
189
-        void onBluetoothDeviceChange(boolean deviceAvailable);
190
-    }
191
-}

+ 1
- 5
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetActivityDelegate.java Zobrazit soubor

@@ -1,6 +1,5 @@
1 1
 /*
2
- * Copyright @ 2019-present 8x8, Inc.
3
- * Copyright @ 2018 Atlassian Pty Ltd
2
+ * Copyright @ 2018-present 8x8, Inc.
4 3
  *
5 4
  * Licensed under the Apache License, Version 2.0 (the "License");
6 5
  * you may not use this file except in compliance with the License.
@@ -17,10 +16,8 @@
17 16
 
18 17
 package org.jitsi.meet.sdk;
19 18
 
20
-import android.annotation.TargetApi;
21 19
 import android.app.Activity;
22 20
 import android.content.Intent;
23
-import android.os.Build;
24 21
 
25 22
 import com.facebook.react.ReactInstanceManager;
26 23
 import com.facebook.react.bridge.Callback;
@@ -178,7 +175,6 @@ public class JitsiMeetActivityDelegate {
178 175
         };
179 176
     }
180 177
 
181
-    @TargetApi(Build.VERSION_CODES.M)
182 178
     public static void requestPermissions(Activity activity, String[] permissions, int requestCode, PermissionListener listener) {
183 179
         permissionListener = listener;
184 180
         activity.requestPermissions(permissions, requestCode);

+ 3
- 14
android/sdk/src/main/java/org/jitsi/meet/sdk/ProximityModule.java Zobrazit soubor

@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright @ 2017-present Atlassian Pty Ltd
2
+ * Copyright @ 2017-present 8x8, Inc.
3 3
  *
4 4
  * Licensed under the Apache License, Version 2.0 (the "License");
5 5
  * you may not use this file except in compliance with the License.
@@ -33,21 +33,10 @@ import com.facebook.react.module.annotations.ReactModule;
33 33
  * is used with the conference audio-only mode.
34 34
  */
35 35
 @ReactModule(name = ProximityModule.NAME)
36
-class ProximityModule
37
-    extends ReactContextBaseJavaModule {
36
+class ProximityModule extends ReactContextBaseJavaModule {
38 37
 
39 38
     public static final String NAME = "Proximity";
40 39
 
41
-    /**
42
-     * This type of wake lock (the one activated by the proximity sensor) has
43
-     * been available for a while, but the constant was only exported in API
44
-     * level 21 (Android Marshmallow) so make no assumptions and use its value
45
-     * directly.
46
-     *
47
-     * TODO: Remove when we bump the API level to 21.
48
-     */
49
-    private static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
50
-
51 40
     /**
52 41
      * {@link WakeLock} instance.
53 42
      */
@@ -71,7 +60,7 @@ class ProximityModule
71 60
         try {
72 61
             wakeLock
73 62
                 = powerManager.newWakeLock(
74
-                        PROXIMITY_SCREEN_OFF_WAKE_LOCK,
63
+                        PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
75 64
                         "jitsi:"+NAME);
76 65
         } catch (Throwable ignored) {
77 66
             wakeLock = null;

Načítá se…
Zrušit
Uložit