;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Felipe Zmoginski

Além do Android e iOS: guerra comercial dá origem a 3º sistema operacional

Harmony OS é apresentado ao público: sistema operacional deve ser usado por 500 milhões de smartphones a cada ano - Divulgação/Huawei
Harmony OS é apresentado ao público: sistema operacional deve ser usado por 500 milhões de smartphones a cada ano Imagem: Divulgação/Huawei

30/09/2020 04h00

Receba os novos posts desta coluna no seu e-mail

Email inválido

Usuários mais jovens talvez não se lembrem, mas a enfadonha discussão entre fanboys do iOS e do Android já contou com (muitos) mais atores à mesa. Há pouco mais de uma década, Nokia, HP, Microsoft e a "inovadora" BlackBerry brigavam por nacos de market share do mercado de serviços móveis. Uma disputa que terminou em duopólio, para alegria dos desenvolvedores, que não precisam mais criar versões de seus apps para múltiplos sistemas.

Vencer esta briga foi uma batalha fundamental na história recente de Apple e Google. A cada transação in-app, venda de conteúdo ou comércio de aplicativo pago, os donos da plataforma mordem, em média, 30% do que ganham os desenvolvedores ou criadores de conteúdo. Segundo um relatório, publicado pelo serviço AppAnie, 10,5% da bilionária receita do Google, em 2019, veio dos serviços mobile, como o Google Play. No caso da Apple, este percentual sobe para 17,8%.

A disputa pelo terreno mobile parecia pacificada até o governo americano iniciar, há dois anos, uma agressiva campanha contra a Huawei, a quem acusa de espionagem. As restrições impostas à fabricante de produtos telecom chinesa incluem até a proibição de embarcar Android, um sistema desenvolvido por uma empresa americana, em seus dispositivos.

A saída óbvia da Huawei foi criar seu próprio sistema, o Harmony OS, que deve equipar seus telefones já a partir de janeiro de 2021. O Harmony existe há três anos e, originalmente, era usado apenas nas smarTVs e smartwatches da marca. Agora, porém, vão para os celulares.

Esta seria uma decisão sem nenhuma relevância, não fosse a Huawei a maior fabricante mundial de smartphones, com 19,7% de participação neste mercado, no mundo. Para efeito de comparação, a Samsung, número 2 no ranking, tem 19,6%. Isso segundo um ranking publicado em julho pela consultoria Counterpoint.

Para nós, brasileiros, a disputa pode parecer distante, já que a Huawei não é uma marca popular no país, ao menos no segmento de celulares para o consumidor final. Mas, no mundo, ela vende 500 milhões de unidades todos os anos e é muito popular na Ásia, África e mesmo nos vizinhos na América do Sul.

O surgimento de um novo sistema operacional, fomentado pela maior fabricante de dispositivos do tipo no mundo, além de ser uma dor de cabeça adicional para criadores de apps e conteúdos, é um problema, sobretudo, para o Google, já que uma fatia enorme de consumidores que se encaminharia naturalmente para o Android, não mais deve fazê-lo.

O dilema da guerra comercial em um mundo globalizado é justamente este: ao tentar prejudicar os interesses de uma companhia chinesa, a medida americana, em última análise, afeta negativamente os interesses de uma de suas mais brilhantes empresas de tecnologia, o Google.